黑盒测试实战总结:从入门到精通的那些坑和技巧

司徒晓莉 安全 阅读 2,144
赞 48 收藏
二维码
手机扫码查看
反馈

又踩坑了,这次是跨站脚本攻击

最近在做一个用户评论系统,结果上线没几天就收到了一个报告,说有用户在评论里注入了恶意脚本。我赶紧查了一下,发现确实有这个问题。这下子有点慌了,因为之前一直以为这种安全问题只会在别人的故事里出现。

黑盒测试实战总结:从入门到精通的那些坑和技巧

排查过程:折腾了半天发现是个XSS漏洞

首先,我检查了一下数据库,发现那条评论里确实包含了一些奇怪的脚本代码。然后我开始回想这个评论系统的实现过程,主要是通过前端表单提交,后端接收到数据后存到数据库,然后再通过API返回给前端展示。看起来挺简单的,但没想到会有这么大的隐患。

为了验证是不是真的存在XSS漏洞,我试着在评论框里输入了一段简单的JavaScript代码:

<script>alert('XSS Test');</script>

提交后刷新页面,果然弹出了一个警告框。这下确定了,确实是XSS漏洞。接着我开始排查具体是哪个环节出了问题。

核心代码就这几行,这里我踩了个坑

先看前端的部分,主要就是一个表单提交的逻辑:

const form = document.querySelector('#comment-form');
form.addEventListener('submit', (e) => {
    e.preventDefault();
    const comment = document.querySelector('#comment').value;
    fetch('/api/comments', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({ comment })
    }).then(response => response.json())
      .then(data => {
          console.log('Success:', data);
          // 渲染新评论
          renderComment(data.comment);
      })
      .catch((error) => {
          console.error('Error:', error);
      });
});

再看看后端的处理逻辑(这里用了Node.js + Express):

const express = require('express');
const app = express();
app.use(express.json());

let comments = [];

app.post('/api/comments', (req, res) => {
    const { comment } = req.body;
    comments.push(comment);
    res.status(201).json({ comment });
});

app.get('/api/comments', (req, res) => {
    res.json(comments);
});

app.listen(3000, () => {
    console.log('Server is running on port 3000');
});

前端把评论内容传给后端,后端直接存到数组里,然后通过API返回给前端展示。问题就出在这里,前端没有对评论内容进行任何过滤或转义,直接渲染到了页面上。

最终的解决方案:用DOMPurify净化HTML

解决XSS攻击最直接的方法就是对用户输入的内容进行过滤和转义。我决定使用一个成熟的库来处理这个问题:DOMPurify。

首先在项目中安装DOMPurify:

npm install dompurify

然后在前端代码中引入并使用DOMPurify来净化用户输入的内容:

import DOMPurify from 'dompurify';

const form = document.querySelector('#comment-form');
form.addEventListener('submit', (e) => {
    e.preventDefault();
    let comment = document.querySelector('#comment').value;
    comment = DOMPurify.sanitize(comment); // 这里进行净化
    fetch('/api/comments', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({ comment })
    }).then(response => response.json())
      .then(data => {
          console.log('Success:', data);
          // 渲染新评论
          renderComment(data.comment);
      })
      .catch((error) => {
          console.error('Error:', error);
      });
});

function renderComment(comment) {
    const commentList = document.querySelector('#comment-list');
    const newComment = document.createElement('div');
    newComment.innerHTML = DOMPurify.sanitize(comment); // 这里也进行净化
    commentList.appendChild(newComment);
}

这样,无论是提交时还是渲染时,用户输入的内容都会经过DOMPurify的净化,确保不会执行恶意脚本。

技术细节:DOMPurify的工作原理

DOMPurify是一个纯JavaScript库,用于净化HTML内容,防止XSS攻击。它的工作原理是通过解析HTML内容,然后根据预定义的安全规则进行过滤和转义。DOMPurify支持多种配置选项,可以自定义哪些标签、属性和协议是允许的。

举个例子,如果你不想让用户提交的评论里包含任何外部链接,可以这样配置:

const clean = DOMPurify.sanitize(dirty, {
    ADD_TAGS: ['a'],
    ADD_ATTR: ['href'],
    FORBID_ATTR: ['target']
});

这样一来,用户提交的评论里的链接会被过滤掉,从而进一步提高安全性。

总结一下,希望对你有帮助

以上是我这次踩坑后的总结,希望能帮到你。如果你有更好的方案或者遇到类似的问题,欢迎在评论区交流。安全问题不容忽视,特别是涉及到用户输入的地方一定要格外小心。

本文章不代表JZTHEME立场,仅为作者个人观点 / 研究心得 / 经验分享,旨在交流探讨,供读者参考。
发表评论
令狐凌薇
读完这篇文章,我开始注重用户体验,不再只关注技术实现的难度。
点赞
2026-02-19 09:25