Будет ли это хорошей идеей против XSS?

поскольку использование HTTP-заголовка Origin / X-Frame-Options не очень популярно, и я не думаю, что новый CSP в Firefox будет лучше (накладные расходы, усложнение и т. д.). Я хочу сделать предложение для нового JavaScript / Версия ECMA.

Но сначала я публикую идею, чтобы вы могли сказать, плоха ли она. Я называю это простым jsPolicy:

Каждый, кто использует JavaScript, поместил скрипты в свою html-голову. Так почему бы нам не использовать их, чтобы добавить туда наши политики для управления всеми последующими сценариями. пример:

<html>
<head>
<title>Example</title>
<script>
window.policy.inner = ["\nfunction foo(bar) {\n  return bar;\n}\n", "foo(this);"];
</script>
</head>
<body>
<script>
function foo(bar) {
  return bar;
}
</script>
<a href="#" onclick="foo(this);">Click Me</a>
<script>
alert('XSS');
</script>
</body>
</html>

Теперь браузер сравнивает ‹scripts>.innerHTML и onclick.value с теми, что указаны в политике, поэтому последний блок элемента скрипта не выполняется (игнорируется).

Конечно, дублировать весь встроенный код будет нецелесообразно, поэтому вместо этого мы используем контрольные суммы. пример:

crc32("\nfunction foo(bar) {\n  return bar;\n}\n");

результаты "1077388790"

А теперь полный пример:

if (typeof window.policy != 'undefined') {
  window.policy.inner = ["1077388790", "2501246156"];
  window.policy.url = ["http://code.jquery.com/jquery*.js","http://translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"];
  window.policy.relative = ["js/*.js"];
  window.policy.report = ["api/xssreport.php"];
}

Браузеру нужно только сравнить, установлена ​​ли контрольная сумма встроенного скрипта в policy.inner или если URL-адрес script.src соответствует policy.url.

Примечание. Идея policy.relative заключается в том, чтобы разрешать только локальные скрипты:

window.policy.url = false;
window.policy.relative = ["js/*.js"];

Примечание: policy.report должен быть почти таким же, как с CSP (отправляет заблокированные скрипты и URL-адреса в API):
https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-unofficial-draft-20110315.html#violation-report-syntax

Важный:

  • Политика не может быть установлена ​​дважды (иначе выдается предупреждение) = константа
  • Для размышления: политика может быть установлена ​​только в голове (иначе выдается предупреждение)
  • Политика используется только для проверки скриптов, которые являются частью исходного html-кода, а не тех, которые размещаются на лету. пример:
    document.write('‹script src="http://code.jquery.com/jquery-1.5.2.min.js">‹/scr' + 'ipt>');
    Вам не нужно определение policy.url для "http://code.jquery.com...", так как контрольная сумма policy.inner подтвердила полный исходный код скрипта. Это означает, что источник загружается, даже если для policy.url установлено значение false (да, это все еще безопасно!). Это гарантирует простоту использования политики.
  • если одна из политик отсутствует, ограничений нет. Это означает, что пустое значение policy.relative означает, что разрешены все локальные файлы. Это гарантирует обратную совместимость
  • если для одной из политик установлено значение «false», использование не разрешено (по умолчанию — true). пример:
    policy.inner = false;
    Это запрещает любой встроенный скрипт
  • Политика игнорирует только запрещенные сценарии и выдает предупреждение на консоль (ошибка остановит выполнение разрешенных сценариев, а это не требуется)

Я думаю, что это сделало бы XSS невозможным, и вместо CSP он также избежал бы постоянного XSS (пока никто не перезаписывает политику), и его было бы намного проще обновлять.

Что вы думаете?

EDIT:
Вот пример, сделанный в Javascript:
http://www.programmierer-forum.de/php/js-policy-against-xss.php

Конечно, мы не можем контролировать выполнение скрипта, но он показывает, как он мог бы работать, если бы браузер, совместимый с jsPolicy, работал.

EDIT2:
Не думайте, что я говорю о кодировании небольшой функции javascript для обнаружения xss!! Моя идея jsPolicy должна стать частью нового движка JavaScript. Вы можете сравнить это с php-настройкой, помещенной в файл .htaccess. Вы не можете изменить этот параметр во время выполнения. Те же требования применяются к jsPolicy. Вы можете назвать это global setting.

jsPolicy вкратце:
Парсер HTML -> отправить скрипты в JavaScript Engine -> сравнить с jsPolicy -> разрешено?
А) да, выполнение через JavaScript Engine
B) нет, проигнорировать и отправить отчет веб-мастеру

EDIT3:
Ссылка на комментарий Майка это тоже возможная настройка:

window.policy.eval = false;

person Community    schedule 28.04.2011    source источник
comment
Да, это. Если бы это было частью новой версии Javascript/ECMA, это решило бы все проблемы с XSS. Может я плохо объяснил. Какая часть вам не ясна?   -  person mgutt    schedule 30.04.2011
comment
Я обновил объяснение и добавил еще несколько примеров. Я надеюсь, что теперь это более ясно.   -  person mgutt    schedule 30.04.2011
comment
От MDC: Примечание. Из соображений безопасности вы не можете использовать элемент ‹meta› для настройки заголовка X-Content-Security-Policy. Неплохо подмечено. Вы не можете установить параметры безопасности на стороне клиента... Как это безопасно?   -  person Rudie    schedule 30.04.2011
comment
@Rudie По моему мнению, это так (если браузер соответствует требованиям политики), поскольку браузер контролирует выполнение всех скриптов в зависимости от политики. Вы знаете, почему мета CSP запрещена? Я думаю, это потому, что вы можете перезаписать мета с помощью JavaScript, и проще игнорировать мета, чем создавать правила безопасности для механизма javascript, которые запрещают доступ к мета. Но в моей идее нет сопоставимой слабости, поскольку политическая установка постоянна.   -  person mgutt    schedule 30.04.2011
comment
Но настройка политики в заголовках HTTP не менее безопасна, согласны? Я думаю надежнее. И это всего несколько байт. Вероятно, меньше, чем файл cookie (теперь они неэффективны). edit Это также меньше, чем JS, который вы предлагаете отправлять для каждого запроса. Все решения имеют «накладные расходы».   -  person Rudie    schedule 30.04.2011
comment
@Rudie У вас много недостатков, потому что вам нужно добавлять заголовки с помощью apache или на лету с помощью php. И последнее, но не менее важное: вы поднимаете накладные расходы. И нет, у jsPolicy нет накладных расходов, потому что настройка jsPolicy будет помещена - наверняка - в общий внешний файл js (мой первый пример со встроенной политикой только для того, чтобы быстро показать, как это будет работать), и это будет кэшировано.   -  person mgutt    schedule 30.04.2011
comment
Хороший вопрос =) Я думаю, у вас может быть что-то тогда. Только с помощью XSS все еще возможно обойти эти новые правила (и это именно то, чем является XSS). Так что я бы не назвал это XSS-решением, но определенно связано с безопасностью браузера =) Держите нас в курсе?   -  person Rudie    schedule 30.04.2011
comment
Если браузер придерживается jsPolicy, вы не можете обойти правила. Единственным вариантом было бы перезаписать внешний файл js, но для этого потребуется доступ по ftp, и я думаю, что тогда у вас гораздо большая проблема ^^   -  person mgutt    schedule 30.04.2011
comment
XSS также включает выполнение скриптов (на том же веб-сайте › домене), которые не должны были выполняться. Например, печать плохих комментариев HTML. Эти комментарии (с XSS) могут содержать javascript. Этот javascript не будет остановлен вашим решением (если только он не настолько сумасшедший, что вы не включили его в правила). Это XSS. Или я ошибаюсь? Я смог бы...   -  person Rudie    schedule 30.04.2011
comment
Да, вы. Пример: если вы добавите в базу данных форума постоянный xss для прорыва некоторых html-тегов с помощью --><script>alert('xss')</script><!-- или внутри входных данных с помощью " /><script>alert('xss')</script><input type="text" value=", результатом будет в любом случае абсолютно правильный внутренний скрипт. И это должно передать jsPolicy до того, как оно будет выполнено, поскольку jsPolicy является частью программного обеспечения браузера, где сценарий передается JSengine (это также покрывает ошибки парсера браузера html!). Коротко: парсер HTML -> обнаружен сценарий -> отправить в jsEngine -> jsPolicy -> выполнить, если он действителен   -  person mgutt    schedule 30.04.2011
comment
Да, я понимаю. Но скрипты, которые вы (разработчик) разрешаете, могут быть такими же, как скрипты, используемые в XSS... Встроенные скрипты не крутые, но все их используют (и они должны работать!!). Другим встроенным скриптом может быть XSS. Как вы фильтруете одно, а не другое? Насколько точно вы делаете policy.inner?   -  person Rudie    schedule 30.04.2011
comment
Они фильтруются по контрольным суммам, а точность определяется частотой столкновений алгоритма контрольной суммы/хеширования (crc32 colission @stackoverflow). Это означает, что контрольная сумма alert('xss') (CRC32=3414049779) полностью отличается от alert('XSS') (CRC32=2462090537). Если crc32 недостаточно безопасен, мы можем использовать md5.   -  person mgutt    schedule 30.04.2011


Ответы (4)


Межсайтовые сценарии выполняются на стороне клиента. Ваши политики определяются на стороне клиента. Видите проблему?

Мне нравится Content Security Policy, и я использую ее во всех своих проектах. На самом деле, я работаю над фреймворком JavaScript, одним из требований которого является «дружественность к CSP».

CSP > crossdomain.xml > ваша политика.

person Community    schedule 30.04.2011
comment
CSP также находится на стороне клиента. Подумай об этом. Вы определяете правила внутри заголовка, а клиентский браузер придерживается спецификации CSP и при необходимости останавливает выполнение. Если бы браузер придерживался jsPolicy, было бы то же самое. Надеюсь, вы не думаете, что я говорю о написании js-функции или чего-то подобного. На самом деле это должно быть обновление самого движка Javascript и добавление новых «глобальных констант». - person mgutt; 30.04.2011
comment
Вы можете сравнить jsPolicy с настройкой php, помещенной в файл .htaccess. Его нельзя изменить во время выполнения. - person mgutt; 30.04.2011
comment
CSP не на стороне клиента. Веб-сервер отправляет HTTP-заголовок, который браузер захватывает и обрабатывает. Весь документ с DOM и JavaScript на данный момент даже не существует. Эра клиентской части начинается после CSP. В противном случае CSP не будет работать. Есть причина, по которой они решили не разрешать настройку политик CSP через метатеги. - person Tower; 11.06.2011

Подавляющее большинство XSS-атак исходит из «надежных» источников, по крайней мере, в том, что касается браузера. Обычно они являются результатом эхо-ввода пользователя, например. в форуме, и не должным образом избежать ввода. Вы никогда не получите XSS от ссылки на jquery, и крайне вы получите его из любого другого связанного источника.

В случае, когда вы пытаетесь выполнить междоменный скриптинг, вы не можете получить контрольную сумму на удаленном скрипте.

Так что, хотя ваша идея кажется хорошей, я не вижу в ней смысла.

person Mark Kahn    schedule 30.04.2011
comment
Вы говорите о постоянном XSS, и это не распространяется на CSP, но это моя идея. XSS в сообщениях на форуме означает вывод ‹script›alert('xss')‹/script›. Но это было бы бесполезно, потому что контрольная сумма alert('xss') не установлена ​​в policy.inner. То же самое, если xss имеет вид ‹script src=hacker.domain/xss.js›‹/script›. URL-адрес не является частью policy.url и не может быть загружен. Теперь ты понял мою мысль? - person mgutt; 30.04.2011
comment
Ах, хорошо. Я до сих пор не вижу смысла во внешних ссылках, и я думаю, что вы просите много накладных расходов со стороны разработчика (ладно, не много, а больше, чем просто удаление ссылки в). Что касается родственника, foo.php?js/foo.js технически соответствует. В общем, я начинаю относиться к этой идее, но я думаю, что просить людей считать контрольные суммы не будет работать, особенно с новыми разработчиками, которые не знают, что такое контрольная сумма :) Люди также не любят перепечатывать URL-адреса. , особенно в системах, которые могут включать JS из более чем 20 частей или представлений. - person Mark Kahn; 30.04.2011
comment
Что касается предотвращения xss на форуме, моей лучшей идеей было создать тег <noScriptBelowThis>, но это, конечно, предотвращает оптимизацию скорости, которая размещает скрипты непосредственно перед </head>. - person Mark Kahn; 30.04.2011
comment
@noScriptBelowThis Такой тег будет аналогичен тегу {literal} в смарте. Очень короткий тег ‹l› подойдет для минимизации накладных расходов. Но это не поможет против xss внутри скриптов, таких как форма поиска с событием onsubmit. Но это очень легко понять, так что большой палец вверх и за это тоже ;) - person mgutt; 30.04.2011
comment
@high_demand_on_developers Взгляните на спецификацию CSP. Что было бы проще? контрольная сумма дело непростое, вы правы. Но было бы несложно автоматически установить эти контрольные суммы/URL-адреса с помощью PHP: 1. получить filemtime() файла шаблона, 2. если были изменены preg_match() скрипты, 3. получить URL-адрес или контрольную сумму crc32() и 4. перезаписать настройки политики в общем файле js. Но не думайте об этом. Подумайте о преимуществах запрета всех встроенных скриптов и разрешения только одной локальной папки с файлами js и большого количества внешних скриптов в качестве src. - person mgutt; 30.04.2011
comment
@noScriptBelowThis2 Я был слишком поспешным. Начальный и закрывающий теги не будут работать, потому что XSS может прорваться. Но я думаю, что вы имели в виду без закрывающего тега, поскольку написали «BelowThis». Это было бы возможно, но бесполезно, так как вы не можете размещать коды между сообщениями на форуме или скриптами в нижнем колонтитуле и т. д. А как насчет xss перед этим тегом? Я знал веб-сайт, на котором была дыра xss в теге <title> ^^ - person mgutt; 30.04.2011

Эта идея постоянно всплывает и вновь всплывает... и каждый раз эксперты по безопасности опровергают ее.
Не хочу показаться резким, но это не проблема разработки, это является проблемой безопасности. В частности, большинство разработчиков не осознают, сколько существует вариантов, векторов, эксплойтов и техник уклонения.

Как упоминалось в некоторых других ответах, проблема заключается в том, что ваше решение не решает проблему, доверять ли тому, что поступает в браузер, поскольку на стороне клиента у вас нет возможности узнать, что такое код, а что данные. Даже ваше решение не предотвращает этого.

См., например. этот вопрос на ITsec.SE для некоторых практических проблем с реализацией этого. (ваш вопрос более или менее дублирует этот вопрос...)

Кстати, о CSP — проверьте этот другой вопрос на ITsec.SE.

person Community    schedule 01.05.2011
comment
@whitelist_dom_idea приятно видеть, что у других были похожие идеи, но у него была главная проблема. это не было безопасно против вложенных xss, которые нарушают элементы белого списка. Но где дыра в jsPolicy? - person mgutt; 02.05.2011
comment
@code_or_data Почему ты этого не знаешь? Только если это код, он перенаправляется в движок javascript. Даже если в синтаксическом анализаторе HTML есть ошибка или надстройка для браузера, поэтому данные обрабатываются как код и пересылаются в движок, jsPolicy идет первым, поскольку он является частью движка, а не синтаксического анализатора. - person mgutt; 02.05.2011

Политика используется только для проверки скриптов, которые являются частью исходного html-кода, а не тех, которые размещаются на лету. пример: document.write(''); Вам не нужно определение policy.url для "http://code.jquery.com...", так как контрольная сумма policy.inner подтвердила полный исходный код скрипта. Это означает, что источник загружается, даже если для policy.url установлено значение false (да, это все еще безопасно!). Это гарантирует простоту использования политики.

Похоже, вы отдали всю игру здесь.

Если у меня есть код типа

// Pull parameters out of query string.
var match = location.search.match(/[&?]([^&=]+)=([^&]*)/);

window[decodeURIComponent(match[1])](decodeURIComponent(match[2]));

и кто-то обманом заставляет пользователя посетить мой сайт с помощью строки запроса ?eval=alert%28%22pwned%22%29, тогда они подверглись XSS-обработке, и ваша политика ничего не сделала, чтобы остановить это.

person Community    schedule 01.05.2011
comment
Хороший! Но разве это не так глупо, как include($_GET['page'] . '.php'); или использование 123456 в качестве пароля администратора? И не реализуете идею, хотя умеете решать 99% всех XSS?! Я действительно благодарю вас за этот пример, но если eval (по POST/GET/COOKIE) является единственной дырой в системе и только если код небезопасен, как насчет расширения политики на policy.eval = false? И против вашей атаки CSP тоже не поможет. - person mgutt; 02.05.2011
comment
Дыры в системе огромны. javascript: в URL-адресах от третьих лиц, XSS через HTML от третьих лиц. На самом деле, вероятно, проще перечислить векторы XSS, которые он останавливает, чем те, которые он не останавливает. - person Mike Samuel; 02.05.2011
comment
Пожалуйста, дайте примеры кода. Как вы хотите разместить код javascript внутри URL-адреса стороннего скрипта. Или вы имеете в виду, взломан ли сторонний сервер, такой как jquery? Никакая техника тут не поможет. Вот почему вам следует использовать локальные скрипты, только если вы не доверяете третьим сторонам. Но тогда это не дыра в Политике. Это дыра в третьей стороне. Или вы имеете в виду xss внутри URL-адреса script.src? Это не сработает, так как javascript:alert('xss') означает добавление встроенного скрипта, который не разрешен политикой. а что значит хтмл от третьих лиц? если его встроенный код тоже не разрешен. - person mgutt; 03.05.2011
comment
@mgutt, myLink.href = linkFromThirdParty не подпадает под действие вашей политики. CSS не похож ни на p { color: expression(alert(1337)) }, ни на myDiv.innerHTML = textFromThirdParty. Проверяя только скрипты, вы пропускаете большинство векторов XSS. - person Mike Samuel; 03.05.2011
comment
css рассматривается как встроенный код. Я не знаю, как заполняется myLink.href. Вы имеете в виду, если кто-то взломает сервер jquery и поместит плохой код в jquery-1.5.2.min.js? тогда xss - это только результат (сначала идет атака на сервер). И если вы не доверяете jquery, вам нужно скопировать файл на локальный хост. - person mgutt; 03.05.2011
comment
Третья сторона должна быть покрыта. Пока varFromThirdParty определен внутри встроенного скрипта, он покрывается policy.inner и пока он определен во внешнем файле policy.url покрывает его. Если он определяется через местоположение браузера, это небезопасный код javascript. Если вы установите policy.url = ["http://example.org/tool.js"];, вы доверяете example.org безопасности. И никакой защиты от результатов серверных атак (за исключением того, что вы изобретаете что-то вроде script-url-md5-hash-database.com, где браузеру нужно сравнивать хэши файлов: возможно, но медленно). - person mgutt; 03.05.2011
comment
@mgutt, определение varFromThirdParty не является источником опасного контента. Строка, на которую ссылается этот var, является источником опасного содержимого. - person Mike Samuel; 03.05.2011
comment
А откуда струна? Для этого вам нужен встроенный или внешний скрипт (покрывается jsPolicy). Или, как вы сказали, совпадение местоположения браузера (что является небезопасным кодированием). - person mgutt; 04.05.2011