Express Prototype Pollution Gadgets

Support HackTricks

Serve XSS responses

Для отримання додаткової інформації перегляньте оригінальне дослідження

Change JSON content-type to HTML

В додатку Express, що використовує JSON content type response і відображає JSON:

app.use(bodyParser.json({type: 'application/json'}));
app.post('/', function(req, res){
_.merge({}, req.body);
res.send(req.body);
});

У цих випадках XSS зазвичай не можливий з типом вмісту JSON. Однак, з забрудненням прототипу ми можемо заплутати Express, щоб він повертав HTML-відповідь. Ця вразливість залежить від використання додатком res.send(obj) та використання парсера тіла з типом вмісту application/json.

{"__proto__":{"_body":true,"body":"<script>evil()"}}

Шляхом забруднення body та _body властивостей, можливо змусити Express віддавати HTML тип контенту та відображати властивість _body, що призводить до збереженого XSS.

Відображення UTF7

Можливо змусити express відображати UTF-7 контент з:

{"__proto__":{"content-type": "application/json; charset=utf-7"}}

Безпечні техніки сканування

JSON пробіли

Наступний PP додасть атрибутам всередині JSON додатковий пробіл, що не зламає функціональність:

{"__proto__":{"json spaces": " "}}

Тоді відображений JSON виглядатиме так:

{"foo":  "bar"} -- Note the extra space

Exposed Headers

Наступний PP гаджет змусить сервер надіслати HTTP заголовок: Access-Control-Expose_headers: foo

{"__proto__":{"exposedHeaders":["foo"]}}

Це вимагає, щоб модуль CORS був встановлений

Метод OPTIONS

З наступним payload можливо сховати метод з відповіді OPTIONS:

// Original reponse: POST,GET,HEAD

// Payload:
{"__proto__":{"head":true}}

//New response: POST;GET

Статус

Можливо змінити код статусу, що повертається, використовуючи наступний PP payload:

{"__proto__":{"status":510}}

Помилка

Коли ви призначаєте прототипу примітив, наприклад, рядок, це призводить до операції без дії, оскільки прототип має бути об'єктом. Якщо ви намагаєтеся призначити об'єкт прототипу самому Object.prototype, це викине виключення. Ми можемо використовувати ці дві поведінки, щоб виявити, чи була успішною забрудненість прототипу:

({}).__proto__.__proto__={}//throws type exception
({}).__proto__.__proto__="x"//no-op does not throw exception

Відображене значення

Коли додаток включає об'єкт у свою відповідь, створення атрибута з незвичайною назвою поряд з __proto__ може бути корисним. Зокрема, якщо лише незвичайний атрибут повертається у відповіді, це може вказувати на вразливість додатку:

{"unusualName":"value","__proto__":"test"}

Крім того, у сценаріях, де використовується бібліотека, така як Lodash, встановлення властивості як через забруднення прототипу (PP), так і безпосередньо в об'єкті пропонує ще один діагностичний підхід. Якщо така властивість відсутня у відповіді, це свідчить про те, що Lodash перевіряє наявність властивості в цільовому об'єкті перед злиттям:

{"__proto__":{"a":"value1"},"a":"value2","b":"value3"}
// If 'b' is the only property reflected, this indicates prototype pollution in Lodash

Misc

Дозволити крапки

Є опція в Express, яка дозволяє вам створювати об'єкти з параметрів рядка запиту. Ви безумовно можете використовувати це в ланцюжку помилок для експлуатації вразливості забруднення прототипу.

{"__proto__":{"allowDots":true}}

?foo.bar=baz створює об'єкт у Node.

Посилання

Підтримайте HackTricks

Last updated