DVWA靶场之十三:CSP 绕过(Content Security Policy (CSP) Bypass)

DVWA靶场之十三:CSP 绕过(Content Security Policy (CSP) Bypass)


CSP(Content Security Policy,内容安全策略) 是浏览器的一种安全机制,用来防止网页加载或执行不安全的内容,特别是 防止 XSS(跨站脚本攻击)。

它让网站开发者告诉浏览器:

"我只信任从哪些地方加载资源(如脚本、样式、图片),其它地方的资源都不要执行。"

举个例子:

php 复制代码
Content-Security-Policy: script-src 'self'

这条规则的意思是:

"只允许执行来自本站(self)域名的 JavaScript,不允许执行来自其他域的脚本。"

如果攻击者往网页里注入了 <script src="http://evil.com/hack.js"></script>,浏览器就会拒绝加载这个脚本,因为 CSP 不允许从 evil.com 加载。

本练习/题目的目的是在存在 CSP 的页面上找到实现 JS 执行的方式(通常因为 CSP 配置不当或实现错误),从而演示该配置的弱点。


1. low

php 复制代码
<?php

$headerCSP = "Content-Security-Policy: script-src 'self' https://pastebin.com hastebin.com www.toptal.com example.com code.jquery.com https://ssl.google-analytics.com https://digi.ninja ;"; // allows js from self, pastebin.com, hastebin.com, jquery, digi.ninja, and google analytics.

header($headerCSP);

# These might work if you can't create your own for some reason
# https://pastebin.com/raw/R570EE00
# https://www.toptal.com/developers/hastebin/raw/cezaruzeka

?>
<?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>
<p>
    As Pastebin and Hastebin have stopped working, here are some scripts that may, or may not help.
</p>
<ul>
    <li>https://digi.ninja/dvwa/alert.js</li>
    <li>https://digi.ninja/dvwa/alert.txt</li>
    <li>https://digi.ninja/dvwa/cookie.js</li>
    <li>https://digi.ninja/dvwa/forced_download.js</li>
    <li>https://digi.ninja/dvwa/wrong_content_type.js</li>
</ul>
<p>
    Pretend these are on a server like Pastebin and try to work out why some work and some do not work. Check the help for an explanation if you get stuck.
</p>
';

只允许从下面这些来源加载或执行 JavaScript 脚本。

php 复制代码
$headerCSP = "Content-Security-Policy: script-src 'self' https://pastebin.com hastebin.com www.toptal.com example.com code.jquery.com https://ssl.google-analytics.com https://digi.ninja ;";

Content-Security-Policy: CSP 安全策略头的名称。告诉浏览器要启用 CSP 检查
script-src指定允许执行 JavaScript 的来源
'self' 允许来自当前网站自身域名的脚本(例如 https://yourdomain.com/js/app.js)
https://pastebin.com 允许从 pastebin.com 域名加载脚本。之后的类似

low难度练习就是把下面网址放进去测试
可以工作的脚本

  1. alert.js
    原因:正常的JavaScript文件
    服务器返回:正确的Content-Type: application/javascript头
    结果:浏览器会执行这个脚本
  2. cookie.js
    原因:正常的JavaScript文件,正确的内容类型
    功能:显示你的cookies
    结果:浏览器会执行并显示cookie信息

不能工作的脚本

  1. alert.txt
    原因:文件扩展名为.txt
    服务器返回:Content-Type: text/plain
    结果:浏览器不会把文本文件当作JS执行
  2. forced_download.js
    原因:服务器设置了Content-Disposition: attachment头
    效果:强制浏览器下载文件而不是执行它
    结果:脚本不会被执行
  3. wrong_content_type.js
    原因:服务器强制设置Content-Type: text/plain
    即使文件扩展名是.js,但内容类型是纯文本
    结果:浏览器拒绝执行

2. medium

php 复制代码
<?php

$headerCSP = "Content-Security-Policy: script-src 'self' 'unsafe-inline' 'nonce-TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=';";

header($headerCSP);

// Disable XSS protections so that inline alert boxes will work
header ("X-XSS-Protection: 0");

# <script nonce="TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=">alert(1)</script>

?>
<?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>
';

只允许从下面这些来源加载或执行 JavaScript 脚本。

php 复制代码
Content-Security-Policy: script-src 'self' 'unsafe-inline' 'nonce-TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA='

script-src:这是在说"下面这些来源允许加载/执行 JavaScript"。

'self':允许来自本站域名的脚本。

'unsafe-inline':允许所有内联脚本执行(例如直接写在 的代码,或 HTML 属性里的事件处理器 οnclick="...")。这是一个非常宽松、风险较高的设置。

'nonce-TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=':表示允许带有指定 nonce 值的内联 <script> 标签执行。TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA= 是 nonce 的 Base64 文本;解码后是 Never going to give you up。

实际上,要让某个内联脚本能执行,你在 HTML 中会写:<script nonce="TmV2ZXIgZ29pbmcgdG8gZ2l2ZSB5b3UgdXA=">/* script */</script>

浏览器会比对标签上的 nonce 与 CSP 中的 nonce-...,相同就允许该内联脚本执行。

比如


3. high

vulnerabilities/csp/source/high.php

php 复制代码
<?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>
';

vulnerabilities/csp/source/high.js

php 复制代码
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();
    });
}

严格的CSP策略

php 复制代码
$headerCSP = "Content-Security-Policy: script-src 'self';";
复制代码
只允许同源脚本 ('self')
禁止内联脚本 (没有unsafe-inline)
禁止外部域 (没有其他域名)

安全的代码结构

javascript 复制代码
// high.js - 使用JSONP方式安全加载数据
function clickButton() {
    var s = document.createElement("script");
    s.src = "source/jsonp.php?callback=solveSum";
    document.body.appendChild(s);
}

发现可以修改callback达到注入效果,这里使用burp

把solveSum改掉

可以得到


4. impossible

vulnerabilities/csp/source/impossible.php

php 复制代码
<?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>
';

vulnerabilities/csp/source/impossible.js

php 复制代码
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();
    });
}

这次没有callback函数了,完全消除了代码注入点

相关推荐
编程牛马姐1 天前
独立站SEO流量增长:提高Google排名的优化方法
前端·javascript·网络
2401_873479401 天前
如何从零搭建私有化IP查询平台?数据采集、清洗、建库到API发布全流程
服务器·网络·tcp/ip
FS_Marking1 天前
CWDM vs DWDM:区别是什么?
网络
Vis-Lin1 天前
BLE 协议栈:ATT 协议详解
网络·物联网·网络协议·iot·ble
lcxc1 天前
Mac M4超流畅运行Win版同花顺教程
网络
bluechips·zhao1 天前
帝国CMS 8.0 安全审计分析——代码审计
安全·网络安全·代码审计
whuhewei1 天前
为什么客户端不存在跨域问题
前端·安全
W.A委员会1 天前
常见网络攻击
网络·http·网络安全
zmj3203241 天前
CAN数据帧详解
网络·can·canfd·数据帧
Flittly1 天前
【SpringSecurity新手村系列】(4)验证码功能实现
java·spring boot·安全·spring