0%

前端安全5-CSP(笔记)

前言

因为绕过的方式太多,有时候一不小心就会写出一个含有xss漏洞的代码,这时候要怎么去防御。那么就是依靠CSP进行防御了

先看个简单的案例

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="script-src 'none'">
</head>
<body>
<script>alert(1)</script>
CSP test
</body>
</html>

上面的html并不会有弹窗,因为被csp策略阻止了

script-src 'none'的意思就是禁止任何脚本执行,包括

CSP规则

在上面的例子就用了script-src 'none'导致了任何的脚本都不会被执行,包括onerror那些
default-src就是预设的指示,如果某个指示,例如script-src没有设置任何规则,那么就会使用default-src的规则。
但是有几个是不会使用default-src的内容的,如下

  • base-uri
  • form-action
  • frame-ancestors
  • report-uri
  • sandbox

详细内容请看
https://content-security-policy.com/default-src/

还有其他的指示,我这里直接使用huli佬的

下面两个链接是官方文档

当然,每个指示都会有相应的规则,那么一般使用哪些规则呢,我这里也偷懒直接用huli佬的截图

例如script-src *就相当于允许除了data:,blob:,还有file:,demo如下

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="script-src *">
</head>
<body>
<script src=test.js></script>
CSP test
</body>
</html>

但是直接运行的话,就像下面的代码
1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="script-src *">
</head>
<body>
<script>alert(1)</script>
CSP test
</body>
</html>

这种直接运行的还是不行。只能用加载js的方式<script src=xxx>
想直接运行代码,还是得用unsafe-inline

script-src 规则

unsafe-inline

允许执行inline js

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="script-src 'unsafe-inline'">
</head>
<body>
<script>alert(1)</script>
CSP test
</body>
</html>

unsafe-eval

前一个策略允许执行js代码,但是不会运行动态执行js代码,也就是说

1
2
3
eval('alert(1)')
setTimeout('alert(1)')
Function('')()

类似这些
1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="script-src 'unsafe-inline' 'unsafe-eval'"><!-- 仍然需要unsafe-inline,不然不能执行 -->
</head>
<body>
<script>eval('alert(1)')</script>
CSP test
</body>
</html>

nonce-xxx

允许

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="script-src 'nonce-123'">
</head>
<body>
<script nonce=123>alert(1)</script>
CSP test
</body>
</html>

不允许执行不一样的与csp中的nonce不一样的

sha256-xxxx

我这里用一段python代码完成这个,也方便以后的操作

1
2
3
4
5
6
7
import hashlib
import base64

message = "alert(1)"
hash_object = hashlib.sha256(message.encode())
hash_base64 = base64.b64encode(hash_object.digest())
print(hash_base64.decode())

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="script-src 'sha256-bhHHL3z2vDgxUt0W3dWQOrprscmda2Y5pLsLg4GF+pI='">
</head>
<body>
<script>alert(1)</script>
CSP test
</body>
</html>

运行执行sha256一样的

strict-dynamic

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="script-src 'nonce-rjg103rj1298e' 'strict-dynamic'">
</head>
<body>
<script nonce=rjg103rj1298e>
const element = document.createElement('script')
element.src = 'test.js'
document.body.appendChild(element)
</script>
</body>
</html>

nonce=rjg103rj1298e这段生成的js代码也可以运行,因为strict-dynamic

CSP的配置

https://csp-evaluator.withgoogle.com
可以用这个网站查看csp策略是否有问题