C, PHP, VB, .NET

Дневникът на Филип Петров


* Clickjacking

Публикувано на 03 юни 2017 в раздел ОСУП.

Clickjacking е техника, с която ви карат да извършите собственоръчно действие, което не сте желали. Визуално на екрана виждате един обект, но с натискане на левия бутон на мишката върху него вие извършвате съвсем различно действие, а не това, което очаквате. Например отивате на някой уебсайт и виждате видеоклип. Искате да натиснете бутона Play и го правите. Но вместо да сте натиснали Play и клипчето да тръгне, се оказва че сте натиснали върху рекламен банер, който въобще не виждате, натиснали сте Like на някоя статия във Фейсбук, която въобще не сте виждали и т.н.

Вниманието на уеб програмистите следва да се насочи към това да не позволяват ресурс, който се хоства на техен сайт, да бъде вграждан в чужд и върху него да се извърши подобна атака. Името на атаката произлиза от "hijacking" - отвличане. В случая става въпрос за "отвличане на кликове" - clickjacking. Нека дадем един много елементарен базов пример. На съвсем добронамерен сайт mysite.dom вие имате страница good.html със следния код:

<html><head></head><body>
<a href="http://www.google.com" target="_blank">Go to Google</a>
</body></html>

Както виждате това е най-обикновена хипервръзка - в случая тя се явява обекта, върху който хакера желае да накара посетителя на неговия сайт да кликне! При някой по-практичен пример това извършва неприятна за потребителя операция в акаунта. В лошия сайт evilsite.dom хакерът слага файл bad.html със следния код:

<html><head></head><body>
<div style="position: absolute; left: 20px; top: 20px;">
   <a href="http://www.yahoo.com">Go to Yahoo!</a>
</div>
<iframe style="opacity:0;" width="110" height="30" scrolling="no" src="http://mysite.dom/good.html"></iframe>
</body></html>

С абсолютна позиция на екрана се изобразява хиперлинк с текст "Go to Yahoo!" - това е нещото, което човекът, който посети сайта, вижда. Буквално върху него се зарежда good.html от mysite.dom в iframe, но забележете със стил с "opacity: 0", т.е. този iframe e невидим! Ако направите този пример, ще видите че на екрана ще виждате "Go to Yahoo!", но ако цъкнете на линка всъщност ще отидете на google.com.

Този пример разбира се е безобидно елементарен. Сериозна цел на хакера би била да вгради реален сайт в iframe, в който поради same origin policy и XSRF token няма възможност да накара човека да извърши дадено действие автоматично, но с хитро позициониране на бутон или връзка под скрития обект, всъщност кара човека да извърши това действие. Един от най-популярните примери за clickjacking атака е тази срещу страницата с настройки на Adobe Flash - чрез зареждане на тази страница в iframe, хакери са можели да накарат потребителя да кликне така, че да разреши на флаш анимациите да имат достъп до микрофона и камерата на компютъра. Популярен пример е как хакери са накарали огромно количество хора да направят "retweet" на тяхна публикация.  Друг пример е да ви накарат да натиснете бутонче "like" за страница във Фейсбук. Естествено има и редица други.

За да защитим нашия сайт от clickjacking атака, бихме искали да не позволяваме страници, на които може да бъде изпълнено опасно действие и не са предвидени да бъдат вграждани в iframe, да могат да бъдат вграждани в iframe. Един стар и ненадежден подход е използването на JavaScript, в който да проверим къде се намираме и да извършим пренасочване (или блокиране) - т.нар. framebursting. Например променяйки кода на good.html по следния начин:

<html><head>
<script>
if (top != window) {
 window.stop();
 document.execCommand('Stop'); // за IE
}
</script>
</head><body>
<a href="http://www.google.com" target="_blank">Go to Google</a>
</body></html>

Ще видите, че това ще направи така, че страницата ще се зарежда нормално ако се отвори в "top level" (посещавайки mysite.dom), но няма да се зареди въобще ако е вградена във фрейм. Друг, още по-популярен (и още по-ненадежден!) начин за защита е да се използва пренасочване:

<html><head>
<script>
if (top != window) {
 top.location = window.location
}
</script>
</head><body>
<a href="http://www.google.com" target="_blank">Go to Google</a>
</body></html>

Ако заредите страницата в iframe, ще видите, че браузъра автоматично ще се пренасочи към вашия сайт.

Тази техника обаче е заобиколима и както подчертахме, ненадеждна! Хакерът може да "победи" тази защита по множество начини. Най-популярният е хакера да вгради вашия сайт със "sandbox", например:

...
<iframe sandbox="allow-scripts allow-forms" style="opacity:0;" height="30" width="110" scrolling="no" src="good.html"></iframe>
...

Това би позволило javascript и форми, но, понеже е пропуснато allow-navigation, ще забрани нашата команда top.location = window.location. Първата предложена защита обаче ще продължава да работи (тя не извършва пренасочване). За нея може да се направи deny-scripts, от което нито един javascript в good.html няма да се изпълни, т.е. защитата ни ще бъде спряна напълно. Цялостното спиране на JavaScript обаче не винаги е желано - понякога хакера ще желае той да се изпълни, защото в противен случай важна функционалност на атакувания сайт няма да работи. В такъв случай продължава да има работещи, но по-сложни техники за заобикаляне на защитата - няма да ги разглеждаме, а само ще споменем най-популярния - изобразяване на div контейнер на целия екран на вашия сайт (в началото при зареждане на сайта), който покрива всичко останало и прихваща кликовете на мишката и непосредствено след това този div се променя така, че вече да не ги прихваща, но чрез javascript и само и единствено ако сайта е зареден в top. Подобни "трикове" в днешно време са напълно заменени от Content Security Policy хедъра.

Content Security Policy Frame Ancestors и X-Frame-Options - работещото решение за проблема

X-Frame-Options е (вече остарял, но все още масово използван и работещ) HTTP Хедър, който има три възможни опции:

  • DENY - забранява се вграждането на страницаjd в iframe;
  • SAMEORIGIN - позволява вграждането на страницата в iframe, но само в рамките на текущия (нейния си) домейн;
  • ALLOW FROM http://... - позволява вграждането на страницата в iframe, но само от посочените в списъка адреси на уебсайтове.

Ако например сложите следния код в .htaccess файл при сървър Apache:

Header always set X-FRAME-OPTIONS "DENY"

Вие ще гарантирате, че нито една страница от вашия сайт няма (или поддиректорията му, в която сте сложил този .htaccess) няма да може да бъде вграждан в iframe, с което гарантирате, че няма да има clickjacking атаки. Направете тест и ще видите, че в конзолата на бразуъра ще видите съобщение подобно на следното (от Chrome): "Refused to display '...' in a frame because it set 'X-Frame-Options' to 'deny'".

Въпреки, че X-Frame-Options все още работи, той се счита за "deprecated" и тенденцията в бъдеще ще е да се премине към Frame Ancestors директивата на Content Security Policy (за повече информация относно CSP, вижте статията за XSS атаки). Ето един примерен хедър за .htaccess файл:

Header set Content-Security-Policy "default-src 'self';frame-ancestors 'none';

Това би имало същия ефект като гореописания. За съжаление CSP е сравнително нов стандарт и трябва да мине известно време докато по-старите браузъри, които не го поддържат, изчезнат и спрат да бъдат използвани. Става въпрос за Crome по-стари от версия 40, Firefox по-стари от версия 33 и т.н. Докато хора, използващи такива стари браузъри, не станат пренебрежимо количество, е препоръчително вашия сайт да изпраща и двата хедъра - X-Frame-Options и CSP Frame Ancestors. Имайте предвид, че X-Frame-Options има приоритет на CSP Frame Ancestors (не, че е препоръчително да правите правилата така, че да си противоречат).

 



Добави коментар

Адресът на електронната поща няма да се публикува


*