xss
xss(cross-site scripting)经常发生在通过用户输入html标签后直接生成的DOM元素。
例如网站使用document.innerHTML直接将用户输入内容修改网站HTML的情况,而恶意攻击在输入中加入script标签,使得页面运行javascript脚本并发送用户保密信息到攻击者的服务器。
解决方案:
对输入HTML的文本进行安全性处理。
可以使用dompurify
库,删除脚本标签。返回一个可新的HTML文本。
通过下面的代码对文本进行处理也可以简单的防范攻击。(Chrome 83以上 )
if (window.trustedTypes && trustedTypes.createPolicy) { // Feature testing
const escapeHTMLPolicy = trustedTypes.createPolicy('myEscapePolicy', {
createHTML: string => string.replace(/\</g, '<')
});
}
在web服务器上添加响应头,可以限制可信类型策略的创建(trustedTypes.createPolicy)
Content-Security-Policy: trusted-types;
使用CSP增加script标签校验
- nonse
在web服务的每次页面请求生成一个随机值NONCE。
给script标签加上nonce="${NONCE}", 在响应头加上对应参数,浏览器会检验两个NONCE值是否相同,不同则不会生效。
Content-Security-Policy:
script-src 'nonce-{NONCE}' 'strict-dynamic';
object-src 'none';
base-uri 'none';
- hash
所有的外部的脚本都需要使用内联的script标签js加载,然后计算内联脚本的hash并填入响应头。
Content-Security-Policy:
script-src 'sha256-{HASHED_INLINE_SCRIPT}' 'strict-dynamic';
object-src 'none';
base-uri 'none';
ClickJacking
ClickJacking意为点击劫持,主要表现形式是一个黑客网站加入了目标网站的iframe,并将其隐藏,用按钮等形式引导用户点击,达到黑客的目的。
解决方案:
设置响应头X-Frame-Options
或者Content-Security-Policy: frame-ancestors
。
具体参数查看MDN文档X-Frame-Options frame-ancestors
CSRF
CSRF(Cross-site request forgery)表示跨站请求伪造,攻击者伪造用户请求,如更改密码或转移资金。
如果是攻击post请求,攻击者通常需要创建一个新网站,在里面发送一个post请求至目标服务器。
而get请求,攻击者只需要植入一个链接,如img标签,但地址为攻击的get请求。
解决方案:
使用post请求会加大攻击者的难度,但依然无法防御CSRF攻击。最有效的防御方案为CSRF令牌,再结合上Cookie的SameSite设置,才能有效的防范攻击。
首先服务器在用户登录的时候生成一个随机字符串CSRF令牌并传递给客户端。
通常CSRF令牌是在使用 POST 方法提交的 HTML 表单中,加入一个隐藏字段内将令牌传输到服务器。或者在自定义请求标头中传输 CSRF 令牌。但不应在Get请求的查询字符串中传输令牌。
在一种CSRF防范方案中,使用了双重提交的方式,即Cookie与body都带上了相同的CSRF令牌,这样服务器可以不维护CSRF令牌的对应表,但攻击者只要知道这样的防范方式,他们就可以使用一个随机字符串代替CSRF令牌。
还有一种方案是检测请求的Referer值是否正确。但这种方式更容易受到攻击。
https://portswigger.net/web-security/csrf
https://web.dev/secure/