前端安全(XSS、CSRF)

前端安全

一、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 攻击:

<!-- 页面中的某个输入框 -->
<input type="text" id="txt">

<!-- 攻击者构造的 URL 参数 -->
http://example.com/search?q=<script>document.getElementById("txt").value="XSS"</script>

当用户在输入框中输入任意文本后,点击链接并访问到带有恶意脚本的页面时,页面中的输入框就会自动填入字符串 “XSS”。

如何防止 XSS 攻击:

1、对用户输入的内容进行过滤和转义,例如将 HTML 标签进行转义。
(1). 过滤敏感字符

可以使用正则表达式或专门的库函数过滤掉一些特殊字符,比如 <> 符号、单引号和双引号等等。过滤掉这些字符之后,即可有效避免通过输入恶意代码的方式攻击。

举例来说,可以通过以下方式过滤 HTML 标签:

function filterHtmlTag(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); // 输出:&lt;script&gt;alert(&#x27;XSS&#x27;);&lt;/script&gt;

// 对编码的字符串进行解码
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-srcstyle-srcimg-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');

function safeEval(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) {
    
    
        return true;
      }
    }
    return false;
  });
  if (hasNewFunction) {
    
    
    throw new Error("new Function() expressions are not allowed.");
  }
  return eval(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 的过期时间、作用域等等。

猜你喜欢

转载自blog.csdn.net/m0_46412825/article/details/130931706