Некоторые из наших клиентов высказали мнение о предполагаемой уязвимости XSS во всех наших конечных точках JSONP, но я не согласен с тем, является ли она на самом деле уязвимостью. Хотелось узнать мнение сообщества, чтобы убедиться, что я что-то не пропустил.
Итак, как и в любой системе jsonp, у нас есть конечная точка, например:
http://foo.com/jsonp?cb=callback123
где значение параметра cb воспроизводится обратно в ответе:
callback123({"foo":"bar"});
Клиенты жаловались на то, что мы не отфильтровываем HTML в параметре CB, поэтому они придумают такой пример:
http://foo.com/jsonp?cb=<body onload="alert('h4x0rd');"/><!--
Очевидно, что для URL, который возвращает тип содержимого text/html
, это создает проблему, при которой браузер отображает этот HTML, а затем выполняет потенциально вредоносный JavaScript в обработчике загрузки. Может использоваться для кражи файлов cookie и отправки их на сайт злоумышленника или даже для создания поддельного экрана входа в систему для фишинга. Пользователь проверяет домен и видит, что он доверяет ему, поэтому он отправляется в агаду и входит в систему.
Но в нашем случае мы устанавливаем заголовок типа контента равным application/javascript
, что вызывает различные варианты поведения в разных браузерах. т.е. Firefox просто отображает необработанный текст, тогда как IE открывает диалог «сохранить как ...». Я не считаю ни один из них особенно пригодным для использования. Пользователь Firefox не собирается читать вредоносный текст, говорящий ему прыгать с моста и много думать о нем. А пользователь IE, вероятно, будет сбит с толку диалоговым окном «Сохранить как» и нажмет «Отмена».
Полагаю, я мог видеть случай, когда пользователь IE обманут в сохранении и открытии файла .js, который затем проходит через механизм JScript от Microsoft и получает все виды доступа к компьютеру пользователя; но это кажется маловероятным. Это самая большая угроза здесь или есть какая-то другая уязвимость, которую я пропустил?
(Очевидно, я собираюсь «исправить», включив фильтрацию, чтобы принимать только действительный идентификатор javascript, с некоторым ограничением длины на всякий случай; но я просто хотел диалог о том, какие другие угрозы я мог пропустить. )