likes
comments
collection
share

不可不知的前端工程化——安全漏洞防护&数据加密

作者站长头像
站长
· 阅读数 38

写在前面

对前端而言,由于直接与用户进行交互,涉及到用户数据的展示,并承载着用户输入的一些敏感信息,那如何对用户隐私的保护,防止重要数据泄露,以及防止跨站脚本攻击(XSS)等安全问题的重视与防护就显得尤为重要。现如今,通过安全漏洞扫描,在上线前对项目进行漏洞修复,必要时对敏感数据进行加密处理,已然成为项目能否顺利发布必不可少的环节。

前端常见的安全问题及解决方案

HTTPS

在前端应用中,使用 HTTPS 来进行数据传输加密。HTTPS 需要在服务器端配置 SSL/TLS 证书,而前端代码无需做特殊处理,HTTPS 会自动对数据进行加密传输。

使用方法

  • 在服务器上配置 SSL/TLS 证书。
  • 将网站的链接协议改为 HTTPS。
  • 示例代码:
<!-- 使用 HTTPS 加载外部资源 -->
<script src="https://example.com/script.js"></script>
<img src="https://example.com/image.png" alt="Image">

<!-- 将当前页面重定向到 HTTPS -->
<script>
  if (location.protocol !== 'https:') {
        location.href = 'https://' + location.host + location.pathname + location.search;
  }
</script>


跨站脚本攻击 (XSS)

XSS攻击如何操作?

  1. 攻击者找到一个存在XSS漏洞的前端应用程序,通常是通过输入框、表单提交等用户输入的地方。
  2. 攻击者在输入框或其他可注入代码的地方注入恶意脚本代码,如 <script>alert('XSS Attack!');</script>
  3. 当用户浏览该页面时,恶意脚本会在用户的浏览器中执行,导致攻击者能够执行任意操作,如窃取用户的登录凭据、篡改页面内容等。

如何进行XSS防护?

  1. 输入验证和过滤:对用户输入的数据进行严格验证和过滤,过滤掉或转义特殊字符,确保只接受预期的输入。例如,使用 HTML 编码或 DOM 转义函数来转义用户输入中的特殊字符。
function escapeHTML(input) {
  return input.replace(/</g, '&lt;').replace(/>/g, '&gt;');
}

  1. 输出转义:在将用户输入数据插入到 HTML 页面中时,使用合适的转义函数进行输出转义,确保用户输入不会被当做代码执行。例如,使用 innerTexttextContent 属性来设置元素的文本内容,而不是使用 innerHTML
var userInput = '<script>alert("XSS Attack!");</script>';
element.innerText = userInput; // 转义用户输入,避免代码执行

  1. HTTP 头设置:在响应中设置合适的 Content-Security-Policy (CSP) 头,限制页面中可执行的脚本来源和其他资源加载来源,防止恶意脚本的注入。例如,设置 Content-Security-Policy: script-src 'self',只允许从同一域名加载脚本。
<!-- 在响应头中设置 Content Security Policy -->
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'

<!-- 或者使用 meta 标签设置 Content Security Policy -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'">


  1. 定期更新依赖库和框架:保持前端应用程序的依赖库和框架更新到最新版本,以获得最新的安全补丁和漏洞修复。

跨站请求伪造 (CSRF)

跨站请求伪造(CSRF)是一种攻击方法,攻击者通过伪造合法用户的请求,使用户在不知情的情况下执行非授权的操作。

CSRF攻击如何操作?

  1. 攻击者创建一个恶意网站,并在其中包含一个针对目标网站的请求。
  2. 诱使用户访问恶意网站,浏览器加载了恶意网站的内容。
  3. 恶意网站中的请求会利用用户在目标网站的登录状态,向目标网站发送一个伪造的请求。
  4. 目标网站认为该请求是合法的,执行了攻击者预期的操作,如修改用户信息、执行付款等。

如何进行CSRF防护?

  1. 验证来源请求:在目标网站的后端,对每个请求进行验证,确保请求来自合法的源。常见的方法是在请求中添加一个CSRF令牌(也称为防跨站请求伪造令牌)并验证该令牌的有效性。示例代码如下:
// 后端随机生成并发送给前端一个CSRF令牌
const csrfToken = generateCSRFToken();
res.cookie('csrfToken', csrfToken);

// 前端发送请求时,将令牌添加到请求头或请求参数中
const headers = { 'X-CSRF-Token': csrfToken };
axios.post('/api/endpoint', data, { headers });

// 后端在处理请求时,验证请求头或请求参数中的CSRF令牌的有效性。

  1. 使用SameSite属性:设置Cookie的SameSite属性为Strict或Lax,限制Cookie只能在同一站点下发送,防止被恶意网站伪造请求。示例代码如下:
   res.cookie('sessionId', sessionId, { sameSite: 'strict' });

敏感数据处理

在前端使用加密算法对用户敏感数据进行加密,确保数据在传输和存储过程中的安全性。常见的前端加密方法包括对称加密和非对称加密。

对称加密(Symmetric Encryption使用同一个密钥(称为对称密钥)进行加密和解密数据。在加密过程中,原始数据使用对称密钥进行加密,生成密文。在解密过程中,使用相同的对称密钥对密文进行解密,恢复出原始数据。常见的对称加密算法包括DES、AES和RC4等。

非对称加密(Asymmetric Encryption使用一对密钥(称为公钥和私钥)进行加密和解密数据。在加密过程中,原始数据使用公钥进行加密,生成密文。在解密过程中,使用私钥对密文进行解密,恢复出原始数据。常见的非对称加密算法包括RSA和ECC(椭圆曲线加密)等。

加密解密示例

jsencrypt 是一个用于在前端浏览器中进行非对称加密和解密的 JavaScript 框架。它基于RSA算法,可以使用encrypt公钥加密数据,在后端使用decryp私钥进行解密。以下是使用 jsencrypt 进行数据加密和解密的示例代码:

import JSEncrypt from 'jsencrypt'
// RSA加密
// 创建 JSEncrypt 实例 
const encrypt = new JSEncrypt(); 
// 设置公钥 
encrypt.setPublicKey(publicKey); 
// 待加密的数据 
let  data = 'sensitive data'; 
// 加密数据 
let encryptedData = encrypt.encrypt(data); 
console.log('加密后的数据:', encryptedData);


// RSA解密

const decrypt = new JSEncrypt()

decrypt.setPrivateKey(

`-----BEGIN RSA PRIVATE KEY-----${privateKey}-----END RSA PRIVATE KEY-----`

)

let data = decrypt.decrypt(JSON.stringify(data))


使用 CryptoJS 进行 AES 加密和解密

<script src="crypto-js.min.js"></script>
<script>
  // 加密密钥,需要妥善保管
  const encryptionKey = '加密密钥';

  // 敏感数据
  const sensitiveData = '敏感数据';

  // 加密
  const encryptedData = CryptoJS.AES.encrypt(sensitiveData, encryptionKey).toString();

  // 存储加密后的数据
  localStorage.setItem('encryptedData', encryptedData);

  // 解密
  const decryptedData = CryptoJS.AES.decrypt(encryptedData, encryptionKey).toString(CryptoJS.enc.Utf8);
</script>

防止敏感信息泄露

在代码中避免将敏感信息(如 API 密钥、密码等)直接硬编码,而是使用环境变量或配置文件来存储这些敏感信息,并在部署时进行配置。

// 使用环境变量存储敏感信息
const apiKey = process.env.API_KEY;
const apiSecret = process.env.API_SECRET;

结尾

以上,是本人目前在项目中遇到过的常见安全问题且常用的解决方案,如还有遗漏的且需要注意的点,欢迎小伙伴们在评论区留言讨论哦,感谢感谢😄

转载自:https://juejin.cn/post/7251786209340244028
评论
请登录