web安全是一个很大的话题,XSS、CSRF大家都有所耳闻,这里简单记录下最近碰到的几种,别的慢慢补充吧。
X-Frame-Options MDN
看这个源自于一天要测一下某手机上iframe内嵌网页的某些兼容问题,想随便找网页塞进去试试,代码都是下面这个模子的,最最最最简单的模板。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Web</title>
</head>
<body>
<iframe src="https://www.zhihu.com" frameborder="0"></iframe>
</body>
</html>
知乎
百度
新浪
发现情况不太一样,知乎的不展示,手浪的有额外报错,稍微看了下。
知乎的设置了X-Frame-Options
,只允许同域SAMEORIGIN
。
同时可见,知乎也启用了 CSP(下面介绍),和HTTP2。
知乎此外根据Log,注意新浪的做了一些骚操作😂
(index):1 Uncaught DOMException: Failed to set the 'href' property on 'Location':
The current window does not have permission to
navigate the target frame to 'https://sina.cn/'.
这里是chrome上默认阻止了,要是手机上,页面会直接重定向到手浪。想要防止这个也很简单,iframe上添加sandbox="allow-forms allow-scripts allow-same-origin"
。这个又属于iframe的安全问题了,此处先不扩展了。
Content Security Policy(CSP) MDN
Content Security Policy(CSP)定义了内容安全策略,它是一种缓解web应用受到内容注入攻击(如跨站脚本攻击XSS)的机制。它是一种由作者或服务器管理员声明的策略,用于描述web应用的客户端可以加载哪些源的资源。
简单来说
CSP 通过告诉浏览器一系列规则,严格规定页面中哪些资源允许有哪些来源, 不在指定范围内的统统拒绝。相比同源策略,CSP 可以说是很严格了。
知乎,Twitter,Github等都启用了CSP。
CSP可以严格到哪个地步呢?严格到内联脚本和样式都可以不让你执行。
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Security-Policy" content="default-src 'self';" />
<title>CSP Test</title>
<style>
body {
color: red;
}
</style>
</head>
<body>
<script>
window.addEventListener('load', () => {
alert('what?!')
});
</script>
</body>
</html>
上面的这个页面输出:
想要如此严格的同时,还想运行内联脚本,也是可以的。
<!DOCTYPE html>
<html lang="en">
<head>
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'sha256-qznLcsROx4GACP2dm0UCKCzCG-HiZ1guq6ZZDob_Tng=' 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'"
/>
<title>CSP Test</title>
</head>
<body>
<!-- <script src="./test.js"></script> -->
<!-- <script>alert('Hello, world.');</script> -->
<script nonce="EDNnf03nceIOfn39fn3e9h3sdfa">
window.onload = function() {
alert('What?!');
};
</script>
</body>
</html>
可以给脚本加上nonce="EDNnf03nceIOfn39fn3e9h3sdfa"
nonce后面是随机数,可以让后端自动生成,每次都不一样,这样来防止被注入。
当然这个也可以支持hash。下面script中的脚本,改一个字符都不可以。
<!DOCTYPE html>
<html lang="en">
<head>
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'sha256-qznLcsROx4GACP2dm0UCKCzCG-HiZ1guq6ZZDob_Tng='"
/>
<title>CSP Test</title>
</head>
<body>
<script>alert('Hello, world.');</script>
</body>
</html>
连hash,随机数都可以支持,那么url匹配来允许指定域下的资源当然也都是可以的了。
例如 *://*.example.com:*
会匹配所有 example.com
的子域名,但不包括 example.com
。
同时,资源限制可以精细到img、font、style、frame等粒度,可以说是相当的牛逼了。
在此推荐一篇个人认为讲解的非常好的文章。
Content Security Policy (CSP) 介绍
Subresource Integrity MDN
面对国内的形式,各种灰产,比如你的脚本被注入,导致打开网页就弹支付宝花呗红包之类的....
子资源完整性 Subresource Integrity 简称 SRI 是一种安全机制,它用于让浏览器检查所下载的来自第三方的资源(例如 CDN)未被恶意篡改。它使用哈希值检查确保第三方资源的完整性。只要开发者提供了被需下载资源的哈希值,浏览器就可以检查实际下载的文件是否与预期的哈希值匹配。
依靠浏览器的检测,我们可以保证内容的安全性,如果内容被篡改,会触发error事件,我们可以再这里进行一些日志收集以备分析。
收集error事件需要注意一点,需要指定script的crossorigin
字段,且服务器要开启CORS允许当前域名可以获取错误信息。
可参考爝神在知乎的回答 应对流量劫持,前端能做哪些工作?
HSTS
HSTS 主要是通过服务器发送响应头的方式来控制浏览器操作:
- 首先在服务器响应头中添加 HSTS 响应头:
Strict-Transport-Security: max-age=expireTime [; includeSubDomains] [; preload]
此响应头只有在 https 访问返回时才生效,其中[ ]中的参数表示可选;
- 设置 max-age 参数,时间设置不宜过长,建议设置时间为 6 个月;
- 当用户下次使用 HTTP 访问,客户端就会进行内部跳转,并且能够看到 307 Redirect Internel 的响应码;
- 网站服务器变成了 HTTPS 访问源服务器。
开启 HSTS 后网站可以有效防范中间人的攻击,同时也会省去网站 301/302 跳转花费的时间,大大提升安全系数和用户体验。
可参考:
Web 应用安全性: 使用这些 HTTP 头保护 Web 应用
SSRF(Server-Side Request Forgery:服务器端请求伪造)
简单来说,允许用户输入URL,服务器去发起请求。这个可能会暴露内网资源。
RCE(remote command/code execute: 远程命令/代码执行漏洞)
eval(xxxx)
可以通过AST Node类型识别,干掉不安全的代码执行。
任意文件读取/下载
前端输入路径,后端用 path拼接
可能会拼出 ../../../../
的路径
End
先记这么多 Web安全是一个很大的话题,以后有空了可以来补充。
网友评论