CSP 内容安全策略, 介绍, 配置CSP策略, CSP实战绕过

CSP 内容安全策略

一, CSP (内容安全策略)介绍

CSP(内容安全策略)是一种额外的安全层,可以帮助检测和减轻某些类型的攻击,如跨站脚本攻击(XSS)和数据注入攻击。
CSP允许网站管理员定义哪些动态资源允许执行和加载,有助于防止恶意脚本执行以及非授权内容的加载。

通过使用Content-Security-Policy HTTP头部,网站可以控制用户代理如何执行页面的特定部分,这可以显著减少XSS攻击的风险。CSP的一些常见指令包括:

default-src:设置默认加载资源的策略(例如,自身的源、任何地方的源、或者不加载任何外部资源)。
script-src:定义哪些脚本可以执行, 例如script标签, a标签的JavaScript:location.href="".
style-src:定义哪些样式表可以加载。
img-src:定义哪些图片资源可以加载。
connect-src:限制可以通过脚本接口进行连接的URL(例如,AJAX 请求、WebSocket)。
font-src:定义哪些字体资源可以加载。
object-src:限制可以加载哪些插件。
media-src:定义哪些媒体资源(音频和视频)可以加载。
frame-src:定义哪些iframe可以加载。

二, 配置 CSP 策略

1. 方式一: 设置响应头

// 只允许加载来自同源的所有资源
header("Content-Security-Policy: script-src 'self'"); 
// 允许执行来自同源以及http://192.168.112.183的脚本。
header("Content-Security-Policy: script-src 'self' http://192.168.112.183"); 
// 允许执行来自同源以及http://http://192.168.112.183的行内脚本
// 比如 
header("Content-Security-Policy: script-src 'self' http://192.168.112.183 'unsafe-inline'");
2. 方式二: 设置meta标签

虽然通过服务器发送HTTP响应头是最常见的实现方式,但你也可以直接在HTML文件中的标签中指定CSP。这种方法通常用于单个HTML页面的情况,或者在无法控制服务器响应头的环境中(例如某些静态站点托管服务)。

DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' https://apis.example.com; img-src 'self' https://images.example.com; style-src 'self' 'unsafe-inline';">
    <title>My Secure Pagetitle>
head>
<body>
    
body>
html>

在上面的例子中,标签使用了http-equiv属性来模拟一个HTTP响应头。
content属性中定义了CSP规则,与通过HTTP头发送的规则相同。

然而,需要注意的是,使用标签设置CSP的方法存在一些限制:

1. 无法使用某些指令,如frame-ancestors和report-uri。
2. 对于由多个页面组成的网站,每个页面都需要包含一个<meta>标签,这可能会导致维护上的困难。
3. 与通过HTTP头设置相比,这种方法可能会更容易遭受某些攻击方式,
   因为恶意用户可能会尝试注入标签来覆盖你的CSP规则。

总的来说,虽然在HTML中设置CSP是可能的,但出于维护和安全性的考虑,通常建议通过HTTP头来设置CSP。

3. 方式三: 全局配置CSP, 修改服务器配置文件

除了在PHP脚本或HTML中直接设置CSP之外,还可以在Web服务器的全局配置中设置内容安全策略(CSP)。
这样做的好处是,你可以为所有服务的页面统一定义安全策略,而不必为每个单独的页面或脚本设置。

以下是在几种常用Web服务器中设置CSP的方法:

Apache

在Apache中,你可以在 .htaccess 文件、虚拟主机配置文件,或者直接在全局配置文件 httpd.conf 中使用 Header 指令来设置CSP。例如:

<IfModule mod_headers.c>
    Header set Content-Security-Policy "default-src 'self';"
</IfModule>

Nginx

在Nginx中,你可以在服务器配置块中添加 add_header 指令来设置CSP,如下所示:

server {
    add_header Content-Security-Policy "default-src 'self';";
    ...
}
Microsoft IIS

在Microsoft IIS中,你可以通过Web.config文件来设置HTTP响应头,类似于这样:

<configuration>
    <system.webServer>
        <httpProtocol>
            <customHeaders>
                <add name="Content-Security-Policy" value="default-src 'self';" />
            </customHeaders>
        </httpProtocol>
    </system.webServer>
</configuration>

如果你使用的是CDN(内容分发网络)或者代理服务(如Cloudflare),这些服务通常提供了方便的界面来设置响应头,包括CSP。
这样你可以在不直接操作服务器配置的情况下,全局地管理这些策略。

在所有情况下,更改全局配置文件时都应该非常谨慎,因为错误的配置可能导致服务中断。
更改后,务必重启服务并测试确保配置正确生效。

此外,全局设置CSP可能会影响网站的所有部分,所以在启用前,需要确保所有部分都符合CSP的规定,以免意外破坏网站的功能。

三, 配置 CSP 安全报告

1. 拦截并报告CSP违规.

添加 report-uri 指令:


header("Content-Security-Policy: default-src 'self'; report-uri /csp-violation-report-endpoint.php");
?>

在这个例子中,当CSP违规发生时,浏览器会向 csp-violation-report-endpoint.php 发送json格式的报告。
你需要确保你的服务器端准备好接收和处理这些报告,通常是通过一个PHP脚本来记录这些违规。


if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // 这里发送过来的json没有key, 不能用$_POST[key]取值, 用伪协议获取内容
    $data = file_get_contents('php://input');
    // 这里可以将$data写入数据库,或者记录到日志文件等。
    file_put_contents('csp-violations.log', $data, FILE_APPEND);
    // 显示报告保存成功的消息
    header("Content-Type: application/json");
    echo json_encode(['success' => true]);
} else {
    header("HTTP/1.1 405 Method Not Allowed");
    echo "You must use POST request to send CSP reports.";
}
?>

在实际部署CSP策略之前,在开发和测试环境中充分测试这些策略是非常重要的。
这样可以确保CSP设置不会意外破坏网站的正常功能。
同时,对于复杂的网站,逐步实施CSP可能是更安全的做法,可以首先在报告模式下启动,然后再逐步转换到强制模式。

2. 仅报告而不拦截的CSP.

可以使用 Content-Security-Policy-Report-Only 头部,而不是 Content-Security-Policy
这个头部的格式与常规的CSP相同,但只用于报告目的。

header("Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self'; report-uri /csp-violation-report-endpoint.php");

在这种模式下,如果有脚本尝试从其他源加载,这个行为不会被浏览器阻止,但会向指定的URI发送报告。

四, CSP实战绕过

注入代码:
<script>alert(111)script>
1. 低级防御
(1). 控制台警告:
GET 
http://192.168.112.200/DVWA-master/vulnerabilities/csp/<script>alert(1)<script>
[HTTP/1.1 404 Not Found 6ms]
指向“http://192.168.112.200/DVWA-master/vulnerabilities/csp/%3Cscript%3Ealert(1)%3Cscript%3E”
的 <script> 加载失败。 csp:62:40

这里发现script标签没作用.

再看一下前端的代码:

<script src="">script>

这里看到注入的代码被写到了src的位置, 那么就知道了这里实际需要注入的是一个js脚本的地址.

(2). 查看响应头:
HTTP/1.1 200 OK
Date: Mon, 06 Nov 2023 09:30:30 GMT
Server: Apache/2.4.48 (Unix) OpenSSL/1.1.1k PHP/7.3.29 mod_perl/2.0.11 Perl/v5.32.1
X-Powered-By: PHP/7.3.29
Expires: Tue, 23 Jun 2009 12:00:00 GMT
Cache-Control: no-cache, must-revalidate
Pragma: no-cache
Content-Security-Policy: script-src 'self' https://pastebin.com hastebin.com example.com code.jquery.com https://ssl.google-analytics.com ;
Content-Length: 4144
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html;charset=utf-8
(3). 分析响应头

这里可以看到后端设置了CSP策略:

Content-Security-Policy: script-src 'self' 
https://pastebin.com hastebin.com example.com code.jquery.com 
https://ssl.google-analytics.com ;

'self':
表示允许加载执行与加载文档处于同一源的脚本(例如,与你的网页相同的域名)。

https://pastebin.com:
允许加载执行来自 https://pastebin.com 的脚本。

hastebin.com:
由于没有指定协议(如 http:// 或 https://),这将默认允许使用与包含文档相同的协议的 hastebin.com 域下的脚本。如果你的网页是通过 HTTPS 服务的,那么它将会是 https://hastebin.com。

example.com:
同样,这没有指定协议,因此它也会默认允许与你的网页相同协议的 example.com 下的脚本。

code.jquery.com:
这会允许加载执行来自 code.jquery.com 的脚本,同样适用于与包含文档相同的协议。

https://ssl.google-analytics.com:
这允许从 https://ssl.google-analytics.com 加载执行脚本,通常用于包含 Google Analytics 的跟踪代码。

(4). 绕过防御:

为了符合策略, 我们需要输入被允许域名下的js脚本.
打开 https://pastebin.com 网站, 输入一段需要执行的js代码(不需要

你可能感兴趣的:(渗透测试,csrf,渗透测试,安全)