С 2009 года, когда задавался этот вопрос, JavaScript значительно изменился. Все остальные ответы теперь устарели или слишком сложны. Вот текущая лучшая практика:
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function demo() {
console.log('Taking a break...');
await sleep(2000);
console.log('Two second later');
}
demo();
await sleep()
. Вы можете попробовать этот код live в Runkit . Обратите внимание, что
await
может выполняться только в функциях с префиксом ключевого слова async
. Runkit завершает ваш код в асинхронной функции перед его исполнением. await
останавливает только текущую функцию async
. Две новые функции JavaScript помогли написать этот фактический " сон ":
async/await
позволяет использовать код явно async
/ await
, приземлился в V8 и был включен по умолчанию, поскольку Chrome 55 он приземлился в Узел 7 в октябре 2016 года также приземлился в Firefox Nightly в ноябре 2016 года Если по какой-то причине вы используете Node старше 7 или ориентированы на старые браузеры, async
/ await
все еще можно использовать через Babel (инструмент, который будет транслировать JavaScript + новые функции в простой старый JavaScript), с transform-async-to-generator
плагин . Запустите
npm install babel-cli --save
Создайте .babelrc
с помощью:
{
"plugins": [
"transform-async-to-generator",
]
}
Затем запустите свой код с помощью
node_modules/babel-cli/bin/babel-node.js sleep.js
Но вам опять не нужно это, если вы используете Node 7 или более позднюю версию, или если вы ориентируетесь на современные браузеры.
Использование хэш-функции для встроенных скриптов разрешено в Уровне политики безопасности контента 2. Из примера в спецификации:
Content-Security-Policy: script-src 'sha512-YWIzOWNiNzJjNDRlYzc4MTgwMDhmZDlkOWI0NTAyMjgyY2MyMWJlMWUyNjc1ODJlYWJhNjU5MGU4NmZmNGU3OAo ='
blockquote>Альтернативой является nonce , снова из примеров:
Content-Security-Policy : script-src 'self' 'nonce- $ RANDOM';
blockquote>, затем
<script nonce="$RANDOM">...</script> <script nonce="$RANDOM" src='save-because-nonce'></script>
Они отображаются в Chrome 40+, но я не уверен, какая удача на данный момент у него будут другие браузеры.
Для последних версий Chrome (46+) текущий ответ больше не верен. unsafe-inline
все еще не имеет эффекта (в тегах заголовка манифеста и в meta
), но в документации вы можете использовать описанную здесь здесь , чтобы расслабить ограничение .
Использование хэшей для
<script>
элементовДиректива
script-src
позволяет разработчикам присваивать белый список конкретному встроенному скрипту, указывая его хэш как разрешенный источник сценария.Использование прост. Сервер вычисляет хеш содержимого конкретного блока сценария и включает в себя кодировку base64 этого значения в заголовке
Content-Security-Policy
:blockquote>Content-Security-Policy: default-src 'self'; script-src 'self' https://example.com 'sha256-base64 encoded hash'
Пример
Рассмотрим следующее:
manifest.json:
{ "manifest_version": 2, "name": "csp test", "version": "1.0.0", "minimum_chrome_version": "46", "content_security_policy": "script-src 'self' 'sha256-WOdSzz11/3cpqOdrm89LBL2UPwEU9EhbDtMy2OciEhs='", "background": { "page": "background.html" } }
background.html:
<!DOCTYPE html> <html> <head></head> <body> <script>alert('foo');</script> </body> </html>
Дальнейшие исследования
Я также опробовал установку применимой директивы в теге
meta
вместо манифеста. Хотя CSP, указанный в сообщении консоли, включал содержимое тега, он не выполнил встроенный скрипт (в Chrome 53).new background.html:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'sha256-WOdSzz11/3cpqOdrm89LBL2UPwEU9EhbDtMy2OciEhs='"> </head> <body> <script>alert('foo');</script> </body> </html>
Приложение: Генерация хэшей
Вот два метода генерации хэшей:
- Python ( передайте JS на stdin, проведите его где-то еще):
import hashlib import base64 import sys def hash(s): hash = hashlib.sha256(s.encode()).digest() encoded = base64.b64encode(hash) return encoded contents = sys.stdin.read() print(hash(contents))
- В JS, используя Стэнфордскую библиотеку криптоваторов в Javascript :
var sjcl = require('sjcl'); // Generate base64-encoded SHA256 for given string. function hash(s) { var hashed = sjcl.hash.sha256.hash(s); return sjcl.codec.base64.fromBits(hashed); }
Убедитесь, что при хэшировании встроенных скриптов включено все содержимое тега скрипта (включая все ведущие / завершающие пробелы). Если вы хотите включить это в свои сборки, вы можете использовать что-то вроде cheerio , чтобы получить соответствующие разделы. В общем случае для любого
html
вы можете:var $ = cheerio.load(html); var csp_hashes = $('script') .map((i, el) => hash($(el).text()) .toArray() .map(h => `'sha256-${h}'`) .join(' '); var content_security_policy = `script-src 'self' 'unsafe-eval' ${csp_hashes}; object-src 'self'`;
Это метод, используемый в hash-csp , плагин gulp для генерации хэшей.
Следующий ответ верен для более старых версий Chrome (& lt; 46). Для более поздних, пожалуйста, проверьте @ Chris-Hunt answer https://stackoverflow.com/a/38554505/422670
Я только что опубликовал очень похожий ответ на вопрос https://stackoverflow.com/a/11670319/422670
Как уже было сказано, невозможно отключить встроенную политику безопасности в расширениях v2 . unsafe-inline
просто не работает намеренно.
На самом деле нет другого способа, чем перемещать все ваши javascript в js-файлы и указывать на них с помощью <script src>
.
Там, хотя, возможность делать Eval и новую функцию внутри изолированного iframe, например, со следующими строками в манифесте:
"sandbox": {
"pages": [
"page1.html",
"directory/page2.html"
]
},
Песочница не будет иметь доступа к API расширения или приложения или прямой доступ к незанятым страницам (он может связываться с ними через postMessage ()). Вы также можете ограничить права на песочницу конкретным CSP
. Теперь есть полный пример из команды Google Chrome на g3b galub eval в iframe о том, как обойти проблему, обмениваясь с изолированный iframe, а также краткое руководство по аналитике
. Благодаря Google в линейке много переписывания расширений: (
EDIT
g15]Можно устранить политику безопасности для REMOTE-скриптов, но не для строк.
Политика против
eval()
и ее родственников, таких какsetTimeout(String)
,setInterval(String)
иnew Function(String)
можно смягчить, добавив'unsafe-eval'
к вашей политике:"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"
Однако мы настоятельно рекомендуем против этого. Эти функции являются известными векторами атаки XSS.
blockquote>это появилось в документации trunk и обсуждается в потоке «eval re-allowed»
inline scripts
не вернется, хотя :Нет механизма для ослабления ограничения против execu встроенный JavaScript. В частности, установка политики скрипта, которая включает
blockquote>'unsafe-inline'
, не будет иметь никакого эффекта.
Afaik, это ошибка.
"default-src 'self' https://ssl.google-analytics.com"
работает, а "default-src 'self' http://ssl.google-analytics.com"
не работает. Это настоящая технология кровотечения, проверьте подробности http://code.google.com/p/chromium/issues/detail?id=105796 . Обновление: http://code.google.com/p/chromium/issues/detail?id=107538 ссылается на эту проблему.