如何编写安全的JavaScript代码以防止常见的XSS攻击?

来源:站长站作者:USDT程序员头衔:程序员
导读:本期聚焦于小伙伴创作的《如何编写安全的JavaScript代码以防止常见的XSS攻击?》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何编写安全的JavaScript代码以防止常见的XSS攻击?》有用,将其分享出去将是对创作者最好的鼓励。

XSS攻击全称为跨站脚本攻击,是Web应用中最常见的安全漏洞之一,攻击者通过在页面中注入恶意JavaScript脚本,当用户访问页面时脚本会自动执行,进而窃取用户Cookie、会话令牌等敏感信息,或者篡改页面内容、跳转恶意链接。要编写安全的JavaScript代码,首先需要了解XSS攻击的三种主要类型,再针对性地采取防护措施。

如何编写安全的JavaScript代码以防止常见的XSS攻击?

XSS攻击的常见类型

存储型XSS

存储型XSS的恶意脚本会被永久存储在服务器端,比如论坛的评论区、用户资料页等位置。当其他用户访问包含恶意脚本的页面时,脚本会从服务器加载并执行,影响范围通常比较广。

反射型XSS

反射型XSS的恶意脚本不会存储在服务器,而是通过URL参数等方式传递,服务器接收到参数后直接返回到页面中。攻击者通常会构造包含恶意脚本的钓鱼链接,诱导用户点击触发攻击。

DOM型XSS

DOM型XSS的攻击过程不涉及服务器端,完全是前端JavaScript操作DOM时未做安全处理导致的。恶意脚本通过修改页面的DOM结构执行,比如使用innerHTML直接插入未过滤的用户输入内容。

编写安全JavaScript代码的核心防护措施

1. 严格的输入验证与过滤

对所有用户输入的内容进行验证,只允许符合预期格式的内容通过,同时过滤掉可能的恶意脚本标签和属性。比如用户名只允许字母、数字和下划线,评论内容过滤掉scriptiframe等危险标签。

以下是一个简单的输入过滤函数示例,用于过滤常见的危险标签:

/**
 * 过滤用户输入中的危险HTML标签
 * @param {string} input - 用户输入的原始内容
 * @returns {string} 过滤后的安全内容
 */
function filterDangerousTags(input) {
    if (typeof input !== 'string') {
        return '';
    }
    // 替换script标签,包括大小写变体
    let filtered = input.replace(/<script[sS]*?>[sS]*?</script>/gi, '');
    // 过滤iframe、object、embed等危险标签
    filtered = filtered.replace(/<(iframe|object|embed|svg)[sS]*?>[sS]*?</1>/gi, '');
    // 过滤on开头的事件属性,比如onclick、onload
    filtered = filtered.replace(/s+onw+s*=s*["'][^"']*["']/gi, '');
    return filtered;
}

// 使用示例
const userInput = '<script>alert("xss")</script><p>正常内容</p>';
const safeInput = filterDangerousTags(userInput);
console.log(safeInput); // 输出 <p>正常内容</p>

2. 输出时正确编码

当需要将用户输入的内容输出到页面时,要根据输出的上下文进行对应的编码,避免浏览器将内容解析为可执行的脚本。常见的输出场景和对应的编码方式如下:

输出场景编码方式说明
HTML正文HTML实体编码将<、>、&、"等字符转义为对应的实体,比如<转义为&lt;
HTML属性属性值编码除了HTML实体编码外,还要确保属性值用引号包裹,避免属性值被截断注入
JavaScript上下文JS编码将用户输入的内容转义为合法的JS字符串,避免闭合引号注入脚本
URL上下文URL编码使用encodeURIComponent对参数进行编码,避免注入恶意协议或路径

以下是一个HTML实体编码的实现示例:

/**
 * HTML实体编码,防止内容被解析为HTML标签
 * @param {string} str - 需要编码的字符串
 * @returns {string} 编码后的字符串
 */
function encodeHTML(str) {
    if (typeof str !== 'string') {
        return '';
    }
    return str
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#39;');
}

// 使用示例
const unsafeContent = '<img src="x" onerror="alert(1)">';
const encodedContent = encodeHTML(unsafeContent);
// 输出到页面时,encodedContent会被显示为普通文本,不会执行脚本
document.getElementById('content').textContent = encodedContent;

3. 避免不安全的DOM操作

前端操作DOM时,尽量避免使用innerHTMLouterHTML等会解析HTML字符串的属性,优先使用textContentinnerText来插入文本内容,这两个属性只会将内容作为纯文本处理,不会执行其中的脚本。

如果必须使用innerHTML,一定要先对插入的内容进行编码处理,示例:

// 不安全的写法,直接插入用户输入
const userComment = '<script>stealCookie()</script>';
document.getElementById('comment').innerHTML = userComment; // 会执行恶意脚本

// 安全的写法,先编码再插入
const safeComment = encodeHTML(userComment);
document.getElementById('comment').innerHTML = safeComment; // 只会显示文本,不会执行脚本

4. 使用内容安全策略(CSP)

内容安全策略是服务器端通过响应头设置的一种安全机制,可以限制页面可以加载的资源来源,禁止执行内联脚本和不安全的脚本源,从根源上降低XSS攻击的影响。常见的CSP配置如下:

// 服务器端设置响应头示例(Node.js Express框架)
const express = require('express');
const app = express();

app.use((req, res, next) => {
    // 只允许从同源加载脚本,禁止内联脚本,禁止eval执行
    res.setHeader('Content-Security-Policy', "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:");
    next();
});

CSP的常用指令说明:

  • default-src:设置所有资源的默认加载源
  • script-src:设置脚本的加载源,设置为'self'表示只允许同源脚本,'unsafe-inline'允许内联脚本(不建议开启)
  • style-src:设置样式表的加载源
  • img-src:设置图片的加载源

5. 其他辅助防护措施

  • 设置Cookie的HttpOnly属性,让JavaScript无法读取Cookie,即使发生XSS攻击,攻击者也无法窃取Cookie内容
  • 尽量使用前端框架(如React、Vue)开发,这些框架内置了XSS防护机制,默认会对插入的内容进行编码处理
  • 避免使用eval()new Function()等可以执行字符串脚本的方法,防止恶意字符串被执行
  • 对用户输入的URL进行校验,只允许http、https协议的链接,禁止javascript:伪协议

总结

防止XSS攻击需要从输入、输出、DOM操作、服务器配置等多个层面共同入手,没有单一的防护方法可以完全杜绝XSS风险。开发者在编写JavaScript代码时,要始终保持安全意识,对所有用户输入的内容持不信任态度,结合输入过滤、输出编码、CSP策略等多种手段,才能有效降低XSS攻击的发生概率,保障应用和用户数据的安全。

XSS攻击JavaScript安全输入过滤输出编码CSP策略修改时间:2026-06-10 13:12:28

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。