前端安全
一、xss攻击
什么是xss攻击:
XSS(跨站脚本攻击)是指攻击者通过注入恶意代码到 Web 页面中,从而达到攻击的目的。
XSS(跨站脚本攻击)是一种常见的 Web 攻击方式,攻击者通过在 Web 页面中注入恶意脚本,从而达到窃取用户信息、Cookie 和会话 ID、破坏网站基础设施等目的。
XSS 攻击一般分为以下三种类型:
1. 反射型 XSS
反射型 XSS 攻击是指攻击者将恶意代码注入到 URL 中,让用户点击该链接后触发攻击。服务器接收到 URL 参数后,直接将其返回到浏览器端,浏览器解析 URL 参数中的恶意脚本并执行,从而达到攻击的目的。
举例来说,攻击者可以通过以下方式构造一个恶意链接:
http://example.com/search?q=<script>alert('XSS')</script>
当用户点击该链接时,就会弹出一个对话框,显示 “XSS” 字符串。
2. 存储型 XSS
存储型 XSS 攻击是指攻击者将恶意代码提交到服务器端,随后其他用户访问网站时,服务器会将恶意代码从数据库中读取并返回给用户,从而触发攻击。
举例来说,攻击者可以通过提交一个评论或留言来实现存储型 XSS 攻击。攻击者在评论框中插入一段 JavaScript 代码,然后将评论提交到服务器。当其他用户访问该页面时,服务器从数据库中读取该条评论并将其发送给浏览器,浏览器解析评论中的 JavaScript 代码并执行,从而达到攻击的目的。
3. DOM 型 XSS
DOM 型 XSS 攻击是指攻击者通过修改网页中的 DOM(文档对象模型) 节点来篡改页面,从而实现攻击的目的。攻击者利用网站提供的接口或者漏洞,构造特定参数注入恶意代码,前端 JavaScript 代码在解析参数时,直接把参数作为 HTML 插入到页面中,导致页面结构和样式被攻击者篡改。
举例来说,攻击者可以通过以下方式来实现 DOM 型 XSS 攻击:
<!-- 页面中的某个输入框 --><inputtype="text"id="txt"><!-- 攻击者构造的 URL 参数 -->
http://example.com/search?q=<script>document.getElementById("txt").value="XSS"</script>
当用户在输入框中输入任意文本后,点击链接并访问到带有恶意脚本的页面时,页面中的输入框就会自动填入字符串 “XSS”。
如何防止 XSS 攻击:
1、对用户输入的内容进行过滤和转义,例如将 HTML 标签进行转义。
(1). 过滤敏感字符
可以使用正则表达式或专门的库函数过滤掉一些特殊字符,比如
<
和
>
符号、单引号和双引号等等。过滤掉这些字符之后,即可有效避免通过输入恶意代码的方式攻击。
举例来说,可以通过以下方式过滤 HTML 标签:
functionfilterHtmlTag(str){return str.replace(/<\/?[^>]*>/g,'');}
上述代码通过正则表达式过滤掉所有的 HTML 标签,保留文本内容。
(2). 转义特殊字符
可以使用专门的库函数进行 HTML 编码,将 HTML 特殊字符(如
<
,
>
,
'
,
"
,
&
等)转成实体字符。在返回给用户前端时再进行反解码,使其还原为原始字符。这样做可以有效防止恶意代码注入的攻击。
举例来说,可以使用
he
库进行 HTML 编码和解码处理:
const he =require('he');// 对字符串进行编码const html ="<script>alert('XSS');</script>";const encodedHtml = he.encode(html);// 输出编码后的字符串
console.log(encodedHtml);// 输出:<script>alert('XSS');</script>// 对编码的字符串进行解码const decodedHtml = he.decode(encodedHtml);// 输出解码后的字符串
console.log(decodedHtml);// 输出:"<script>alert('XSS');</script>"
上述代码使用
he
库对 HTML 特殊字符进行了编码和解码,并成功防止了 XSS 攻击。
综上所述,通过过滤敏感字符和转义特殊字符这两种方式,可以有效避免 XSS 攻击的发生。在实际开发中,建议使用专门的库函数来进行字符过滤和编码,以提高效率和减少出错率。
2、使用 CSP(内容安全策略)对网站进行安全配置,限制外部资源的加载和执行。
内容安全策略(Content Security Policy,CSP)是一种内置于浏览器中的安全保护机制,可帮助开发人员在 Web 应用程序中限制外部资源的加载和执行。下面是一些使用 CSP 的最佳实践:
(1). 开启 CSP
要想启用 CSP,需要在 HTTP 响应头中添加
Content-Security-Policy
字段并指定策略。例如,以下代码可以限制只允许加载同源的 JavaScript、CSS 以及图片:
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self';
在上述示例中,
default-src
为默认策略,将限制所有资源的加载,而
script-src
、
style-src
和
img-src
分别指定了加载 JavaScript、CSS 和图片的限制。
(2). 限制外部资源的加载
通过 CSP,可以限制 Web 应用程序从外部加载资源。通常的做法是将资源限制为同源,或者白名单机制,只允许加载特定站点的资源。这无疑可以有效降低恶意脚本注入的概率。
以下是限制资源加载的 CSP 配置示例:
Content-Security-Policy: default-src 'self'; script-src 'self' example.com; style-src 'self'; img-src 'self' *.cdn.example.com;
在上述示例中,
'self'
表示只允许从同源加载资源,
example.com
表示只允许从 example.com 加载 JavaScript,而
*.cdn.example.com
则表示只允许从 cdn.example.com 的任意二级域名加载图片。
(3). 防止对网站进行 XSS 攻击
CSP 还可以用于防止跨站脚本攻击(XSS),通常通过禁止内联脚本和未经授权的脚本执行来实现。可以使用以下代码来禁止内联脚本执行:
Content-Security-Policy: default-src 'self'; script-src 'self';
在上述示例中,通过去掉
unsafe-inline
,可以禁止所有内联脚本的执行,只允许从同源加载 JavaScript。
(4). 报告 CSP 违规情况
除了限制外部资源的加载和执行之外,CSP 还支持报告违规情况,以及记录相关信息。例如,可以使用以下配置将违规情况报告给特定 URL:
Content-Security-Policy: default-src 'self'; report-uri /csp-report
在服务器端,可以处理这些报告并分析 CSP 违规情况,以进一步提高 Web 应用程序的安全性。
综上所述,通过使用 CSP,可以限制 Web 应用程序的资源加载和执行,提高其安全性。如果想要更深入了解 CSP,请参考 CSP 官方文档。
3、禁止使用
eval()
和
new Function()
等动态执行代码的方法,使用更安全的解析方法,如 JSON.parse():因为它只能用于解析 JavaScript 对象表示法(JSON),无法解析任意 JavaScript 代码。因此,如果你确定要从外部动态获取一些数据并将其解析为 JavaScript 对象,建议使用 JSON.parse()。。
为了禁止使用
eval()
和
new Function()
等动态执行代码的方法,可以采用类似 CSP 的办法,使用严格的 Content-Security-Policy 来限制 JavaScript 代码的执行。具体实现过程如下:
(1). 禁止使用 eval() 方法
要禁止使用 eval() 方法,需要将 script-src CSP 限制为只允许非内联 Script 标签和外部引入的 JavaScript 文件。
例如:
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com/;
上述配置中,script-src CSP 限制为只允许从同源或者来自于 https://cdn.example.com/ 域名下的外部组件里加载 JavaScript。
(2). 禁止使用 new Function() 方法
禁止使用 new Function() 方法相对复杂一些,因为无法通过限制资源来实现,但可以使用代码静态分析库,例如 Esprima 或 Acorn,在运行时检查和拒绝解析可疑的字符串。
实现示例代码如下:
const esprima =require('esprima');functionsafeEval(code){const ast = esprima.parseScript(code,{tolerant:true});const hasNewFunction = ast.body.some(node=>{if(node.type ==='ExpressionStatement'&& node.expression.type ==='NewExpression'){const callee = node.expression.callee;if(callee.type ==='Identifier'&& callee.name ==='Function'&& node.expression.arguments.length >0){returntrue;}}returnfalse;});if(hasNewFunction){thrownewError("new Function() expressions are not allowed.");}returneval(code);}
在上述代码中,将要执行的代码先进行语法分析,如果发现有 new Function(),则会抛出异常,否则继续使用 eval() 方法执行代码。
通过上述方式,可以禁止使用 eval() 和 new Function() 等动态执行代码的方法,增强 JavaScript 代码的安全性。
二、 CSRF 攻击
什么是 CSRF 攻击:
CSRF(跨站请求伪造)是指攻击者利用受害者已经登录的状态,向服务器发起恶意请求,从而达到攻击的目的。
以下是一个 CSRF 攻击的示例:
假设你登陆了一个购物网站,并在该网站上具有提交订单的权限。攻击者知道你已登录该网站,并让你访问了一个恶意站点。这个恶意站点中嵌入了一个已经被构造好的图片标签,其中
src
属性设置为购物网站的订单提交接口 URL,并附带攻击者制造的恶意参数。你在浏览该页面的时候,你的浏览器会自动载入这个图片并向该接口发送请求,此时请求中的恶意参数就会被一并提交。由于你已经登录了购物网站,所以该请求中会包含你的登录凭证,服务器会认为该请求是你提交的,从而执行该订单。
如何防止 CSRF 攻击:
1、使用token或验证码等来验证请求的合法性,以及在请求中添加 Referer、Origin 或 X-Requested-With 等 HTTP Header 来限制请求来源。
2、对关键操作进行二次确认,例如弹窗提示用户是否确认执行该操作。
3、设置合适的 cookie 策略,例如限制 cookie 的过期时间、作用域等等。
版权归原作者 前端神棍 所有, 如有侵权,请联系我们删除。