Широко распространено мнение, что нет необходимости использовать токены XSRF для защиты сервисов, которые предоставляют доступ только к данным через GET и которые авторизуют пользователя с помощью файлов cookie.
Это не было правдой. Раньше они имели специфичную для AJAX уязвимость XSSI, когда на выходе был массив JSON.
Рассмотрим службу /getfriends
, которая возвращает данные типа [ { "name": "Alice" }, { "name": "Bob" } ]
.
Атакующая страница может сделать
<script>
var stolenData;
var RealArray = Array;
Array = function () {
return stolenData = new RealArray();
};
</script>
<script src="https://naivedomain.com/getfriends" type="text/javascript"></script>
и второй тег <script>
загружают JSON через домен с файлами cookie пользователя
и из-за причуд в EcmaScript 3 (исправлено в EcmaScript 5.0 и современных интерпретаторах ES 3) страница могла читать украденные данные, потому что синтаксический анализатор JavaScript вызывал переопределенный конструктор Array
при синтаксическом анализе [...]
в ответе JSON.
Защита этих служб с помощью токенов XSRF в дополнение к обычным подходам на основе файлов cookie позволила решить эту проблему, также как и запрет GET, авторизация через пользовательские заголовки и включение средства анализа. Анализаторы работают, делая ответ недействительным JSON, например, возвращает throw 0; [{ "name": "Alice" }, { "name": "Bob" }]
, чтобы клиент XHR мог удалить префикс throw 0;
, но загрузка клиента через <script>
не может.
Наконец, поскольку синтаксический анализатор JavaScript анализирует загруженный скрипт как программу, это затрагивает только службы, которые возвращают массивы JSON. Служба /getfriend
, которая вернула { "names": ["Alice", "Bob"] }
, не будет уязвимой, поскольку этот контент не является допустимой программой - он анализируется как блок с недопустимой меткой. Но недопустимый JSON, такой как { names: [ "Alice", "Bob" ] }
, уязвим, поскольку это допустимая программа.