
XSS漏洞智能检测听起来像是把 LLM 大模型、AI智能体、机器学习几个热门词堆在一起凑概念但真正把这条链路跑通之后你会发现它解决的并不是“能不能识别 XSS”的问题而是“在大量 Web 输入里怎么更快、更稳、更可解释地判断风险”的问题。如果你正打算做安全方向的毕业设计或者想入门 AI 安全实战这套系统的核心思路非常值得拆开来看。它最值得关注的地方不是单点模型多强而是把规则检测、机器学习分类、LLM 语义验证和智能体调度组合成一条完整判断链路。下面我按实际落地顺序拆一遍也会把环境、参数、验证方式和常见坑一起写清楚。需要先说明一点XSS 检测只应该用于授权环境、自建靶场、教学实验和合规的安全评估。不要把检测能力用在未授权系统上这不只是技术问题也是边界问题。1. 先搞清楚它检测的是哪一类问题以及为什么需要三层结构1.1 XSS 检测的难点在哪里XSS 全称是跨站脚本攻击本质是 Web 应用把用户输入当成代码执行。攻击者往页面里插入一段可被浏览器解析的内容让页面在用户浏览器里执行脚本从而窃取信息、篡改页面或发起其他恶意行为。这类漏洞的检测难点主要有四个。第一输入形式太多。同样的风险可以藏在 URL 参数、表单字段、JSON 请求体、Cookie、请求头里检测系统如果只认一种格式漏报会很大。第二上下文太复杂。同样是script字样在 JavaScript 字符串、HTML 属性、注释节点里危害程度完全不同。只做字符串匹配很容易误报。第三绕过手段多。大小写混写、HTML 实体编码、Unicode 编码、事件属性替换等都会让规则失效。如果只靠人工维护特征库永远跟不上变化。第四样本量不均衡。真实业务请求中绝大多数是正常输入恶意样本占比很低。模型很容易偏向预测为“正常”看起来准确率很高但实际漏报严重。所以这套系统不能只靠一个模型也不能只靠规则。它需要一个分层结构让每一层处理自己最擅长的问题。1.2 三个技术词分别解决什么问题LLM 大模型、AI 智能体、机器学习在这套系统里的分工不一样。机器学习负责“找可疑”。把文本特征转换成向量训练一个分类器快速判断输入是否具有 XSS 的常见特征。它速度快适合处理大批量请求但解释性一般。LLM 大模型负责“下结论”。把候选样本的特征、上下文、触发位置组织成文本交给大模型判断。它能理解语义能结合上下文推理能生成一段可读的判断理由比黑盒分类器更容易解释。AI 智能体负责“串流程”。它不直接检测而是协调多个模块先调用规则层再调用机器学习层拿不准的样本再交给 LLM最后汇总结果、生成报告、触发告警。你可以把智能体理解成“项目经理”机器学习是“初筛员”LLM 是“专家复核员”。整套系统要解决的核心问题不是单点能力而是协作效率。1.3 这套系统的技术定位毕业设计如果做成“调一个接口判断是否为 XSS”技术含量很有限。但这套系统把检测流程拆成了数据预处理、特征提取、规则过滤、机器学习分类、LLM 验证、告警输出几个环节每个环节都可以单独开题也可以做成模块化系统。从评审角度看这种设计比较好讲清楚“为什么要这个模块”“模块之间怎么协作”“结果怎么验证”。从学习角度看它覆盖了 Web 安全、机器学习、Prompt 工程、Agent 编排、后端 API 多个方向适合作为综合项目。2. 整体架构怎么搭从样本输入到告警输出的一条数据流2.1 模块划分和职责我建议把系统分成六个模块不要一开始就把逻辑写在一个文件里。模块主要职责输入输出数据采集模块接收待检测的 Web 输入HTTP 请求、文件上传、数据库样本规范化后的文本记录数据预处理模块清洗、解码、切分原始输入结构化字段特征提取模块提取文本特征和上下文信息结构化字段特征向量和特征说明检测引擎模块规则匹配、机器学习分类、LLM 验证特征、文本上下文风险等级、置信度智能体调度模块编排检测流程、处理重试和降级检测任务检测结果、日志报告输出模块生成结果、报警、展示检测结果JSON、表格、报告模块之间通过统一的中间格式传递数据。比如一条待检测记录包含请求 ID、来源 URL、参数名、参数值、上下文 HTML、触发点类型。这样到了检测引擎每一层都能从同一条记录里拿到足够信息。2.2 数据流转过程实际跑起来以后数据流大概是这样的收到一条请求或一个样本。先做归一化去掉无意义的空白统一 URL 编码识别 HTML 实体编码。进入规则层做快筛。明显正常的请求直接放行明显高风险的样本直接标记。规则层拿不准的样本进入机器学习分类器。机器学习输出“风险概率”如果概率低于阈值直接通过如果高于阈值进入 LLM 验证。智能体把样本上下文、特征、ML 结果拼成提示词请求 LLM。LLM 返回风险判断和理由。智能体汇总规则层、ML 层、LLM 的结果输出最终风险等级。这个流程的好处是大多数明显正常或明显恶意的样本不会走到 LLM节省资源。只有“拿不准”的样本才需要大模型复核这也是为什么整套系统能在普通配置下运行的原因。2.3 技术栈选择建议技术栈没有标准答案但有一个比较稳的组合思路。后端和调度Python生态最全。机器学习scikit-learn 或 LightGBM适合表格特征。LLM 推理通过 Transformers 加载本地模型或调用兼容 OpenAI 格式的 API。Agent 编排可以用 LangChain、LangGraph或者自己写一个 Pipeline 类。毕设阶段自己写简单的调度器反而更容易讲清楚。API 服务FastAPI轻量适合演示。数据存储SQLite 够用数据量大再换 PostgreSQL。不要一开始就把 Agent 框定在复杂框架里。先写一个线性流程跑通之后再加条件分支和重试。3. 核心实现思路机器学习负责“找可疑”LLM 负责“下结论”3.1 输入预处理和特征工程预处理是整个系统的地基。如果输入没有清洗干净后面的特征提取和 LLM 判断都会受影响。我会按四个步骤做预处理解码做 URL 解码和 HTML 实体解码但要控制解码次数避免无限递归。切分把输入按参数名、参数值、上下文节点切分。标记记录输入在页面中的位置比如出现在 HTML 标签内、属性内、JavaScript 代码块内还是注释里。过滤去掉对判断没有帮助的日志号、时间戳、随机字符串。特征提取可以从三个维度做长度特征、字符组成特征、敏感关键字特征。下面是一个简化示例不是完整方案。def extract_basic_features(snippet: str) - dict: features {} text snippet.lower() features[length] len(snippet) features[has_angle_bracket] 1 if in snippet and in snippet else 0 features[has_script] 1 if script in text else 0 features[has_event_handler] 1 if any( key in text for key in [onclick, onload, onerror] ) else 0 features[has_js_protocol] 1 if javascript: in text else 0 features[special_char_ratio] ( sum(not c.isalnum() for c in snippet) / max(len(snippet), 1) ) return features这种特征比较基础但对入门项目足够。真正要提升效果还需要加入上下文特征比如“是否在属性值内”“是否在 script 标签内”“是否在事件属性内”。3.2 规则层和机器学习分类器怎么配合规则层适合处理“高置信度”样本。比如输入里直接出现了完整的script标签并且位于 HTML 文本节点这基本就是高风险。规则命中后可以直接给出结论不需要模型继续判断。但规则层的问题在于覆盖不全。攻击者换一种编码规则可能就失效了。所以规则层只处理两类情况明显正常普通文本、数字、日期、邮箱直接放行。明显风险特征非常明确的脚本标签或事件属性直接阻断。剩下的灰色地带交给机器学习分类器。机器学习分类器的输入是特征向量输出是风险概率。我会把训练数据分成三类正常样本、恶意样本、可疑样本。训练时不要只用漏洞库里的样本还要加入真实请求日志里的正常数据否则模型会严重偏向“全部判正常”。训练完成之后先在小样本上验证概率分布。如果正常请求的风险概率普遍低于 0.2说明特征区分度不错如果两类样本的概率分布重叠严重就要回过去看特征有没有提取对。3.3 LLM 语义判断的提示词设计与 token 控制LLM 不是用来识别字符串特征的而是用来理解上下文。下面这段提示词的结构可以复用。你是一个 Web 安全检测助手。请判断下面这段 Web 输入是否具有 XSS 风险。 输入内容 {input} 上下文位置{context} 输入类型{input_type} 初步风险概率{ml_probability} 请只输出 JSON { risk: high | medium | low, reason: 简短判断理由, suggestion: 建议处理方式 }提示词里带上“上下文位置”“输入类型”“初步风险概率”是为了让 LLM 知道它不是在看一串孤立的字符串而是在判断一个具体场景下的输入。token 控制要注意两点。第一输入长度不能无限大。我会把待检测样本截断到 1500 到 3000 字以内超出部分只保留上下文片段。这不是因为 LLM 不能读长文本而是为了控制推理时间和成本。第二输出格式要固定。要求 LLM 只输出 JSON方便程序解析。如果还带大段解释后续处理会变得麻烦。需要理解“智能体、模型、AI、token 的关系”智能体是一次任务流程的调度者模型是每一步里真正做计算的组件token 是模型处理文本的最小单元。输入多长、输出多长、上下文窗口多大都由 token 决定。所以在设计提示词时要想着“这个任务到底需要多少 token 才能完成”而不是盲目把整段页面 HTML 都塞进去。3.4 智能体工作流编排多个模型如何协作智能体部分不需要做成很复杂的多轮对话。毕业设计阶段我更建议做一个带分支和重试的 Pipeline。def detect(sample): result {} # 第一步规则快筛 rule_result rule_filter(sample) if rule_result in (allow, block): return finalize(rule_result, rule) # 第二步机器学习分类 ml_result ml_classifier.predict(sample.features) result[ml_probability] ml_result.probability # 第三步概率低直接通过概率高交给 LLM 复核 if ml_result.probability config.ml_threshold: return finalize(allow, ml) # 第四步LLM 复核 llm_result llm_verify(sample, ml_result.probability) return finalize(llm_result.risk, llm)智能体真正要处理的不只是“调几个模型”而是“模型失败怎么办”。比如 LLM 接口超时要不要降级到 ML 结果ML 服务内存占用过高要不要限制并发输出 JSON 解析失败要不要重试一次这些逻辑看起来不起眼但会让系统在演示时更稳。我一般会加两个策略超时降级如果 LLM 调用超过设定时间就直接使用 ML 概率和规则层结果不阻塞主流程。重试一次对 JSON 解析失败、网络瞬时错误做一次重试避免偶发问题影响整个任务。4. 环境准备和最小运行流程建议按三步走4.1 硬件和依赖条件这套系统不是非要高配 GPU 才能跑。如果使用中小规模模型CPU 也能做推理只是速度慢一些。如果你是用本地大模型做 LLM 验证建议看一下显存和内存。下面是一个通用的参考区间配置项最低要求推荐配置CPU4 核8 核以上内存8 GB16 GB 以上GPU不需要6 GB 以上显存磁盘10 GB 可用空间30 GB 以上系统Windows / Linux / macOSLinux 优先Python3.83.10如果完全没有 GPU建议把 LLM 换成参数更小的模型并把批量检测的并发数调低。如果是纯展示也可以使用 API 接口本地不加载模型。依赖安装可以用通用命令具体版本以你选择的模型和框架为准。pip install scikit-learn transformers torch accelerate fastapi uvicorn安装之后先不要急着加载模型。先跑一个空流程确认所有模块能正常导入。4.2 第一次运行先跑通单条样本第一次测试不建议直接丢一大堆样本进去。先构造一条最小测试样本正常样本“hello”风险样本包含script和事件属性的字符串边界样本只有半个标签比如scr然后分别执行一次检测观察输出。正常情况下你应该看到类似下面这样的结果{ sample_id: test_001, risk: high, source: llm, ml_probability: 0.91, reason: 输入中同时出现了脚本标签和可执行上下文风险较高。 }单条样本跑通说明输入处理、特征提取、规则层、ML 层、LLM 层、输出层都通了。这个阶段不要管速度多快先确认结果合理。4.3 批量检测和接口化单条样本正常之后再处理批量文件。我会准备一个 CSV 文件每行包含request_id、url、parameter_name、parameter_value、context_html几列。批量任务需要一个固定输出目录每条检测结果对应一个 JSON 文件避免并发写入同一个文件。接口化推荐用 FastAPI下面是一个最小表达。from fastapi import FastAPI from pydantic import BaseModel app FastAPI() class DetectRequest(BaseModel): request_id: str input_text: str context: str app.post(/detect) def detect_endpoint(req: DetectRequest): sample normalize(req.input_text, req.context) result detect(sample) return result接口化之后前端的 Web 管理后台、后端的自动化扫描器都可以通过 HTTP 调用检测能力而不需要直接操作 Python 类。这也是毕业设计演示时比较出效果的部分。4.4 推理精度选型FP16、BF16还是FP32LLM 推理精度不是越高越好也不是越低越省。它需要根据模型和硬件来选择。FP32 是单精度占用内存最大兼容性最好。如果显存充足模型参数不大可以优先使用 FP32。这样出问题最少。FP16 是半精度显存占用比 FP32 少一半推理速度通常更快。但某些模型在 FP16 下可能出现数值溢出特别是梯度更新或部分中间层对精度敏感时。推理场景一般比训练场景好一些但也要看实际表现。BF16 是另一种半精度格式保留的指数范围比 FP16 大更适合大模型推理。很多新硬件对 BF16 支持得比较好。如果你的运行环境支持 BF16我会优先试 BF16再对比输出质量。我给一个比较通用的判断流程先用默认精度加载模型跑一条样本记录输出内容和显存占用。如果显存不够切换到 BF16 或 FP16。切换后重新跑同一条样本对比风险等级和判断理由是否变化。如果输出明显变差就换回 FP32。如果只是输出理由稍微变化但风险等级稳定就可以继续使用低精度。这部分在论文里可以单独写一小节标题可以叫“LLM 推理精度对检测效果的影响”因为这是一个非常实际的工程问题。5. 效果怎么验证准确率只是起点还要看稳定性、成本和误报5.1 核心参数怎么调系统里最需要关注的参数有六个。参数作用调节建议ML 阈值决定哪些样本进入 LLM 复核默认 0.5先看概率分布再调输入截断长度控制 LLM 上下文长度1500 到 3000 之间LLM 超时时间避免等待太长10 到 30 秒批量并发数控制同时检测的样本数小模型 2 到 4大模型 1规则命中等级决定哪些样本直接阻断只对高置信度规则生效输出格式保证下游可解析固定 JSON不要一上来就把 ML 阈值调到 0.9这样很多风险样本不会进入 LLM漏报会变高。也不要调到 0.1这样所有样本都要过 LLM资源占用会很高。我的做法是先跑 200 条样本统计 ML 输出的概率分布。如果正常样本集中在 0.1 以下恶意样本集中在 0.7 以上可以把阈值放在 0.4 到 0.5 之间。5.2 评价指标不能只看正确率很多毕设里只写“准确率 99%”但 XSS 检测场景里准确率可能很“骗人”。假设 100 条样本里只有 5 条风险样本系统把 95 条正常样本全判对5 条风险样本全判错过准确率有 95%但实际上漏报全部风险样本系统没有意义。所以至少要看这些指标真正例 TP风险样本被正确识别为风险。假正例 FP正常样本被误报为风险。真负例 TN正常样本被正确识别为正常。假负例 FN风险样本被漏报。精确率识别为风险的结果里有多少是真的风险。召回率所有风险样本里系统找回了多少。F1 分数精确率和召回率的调和平均。在安全过滤场景我更看重召回率。漏掉一个风险样本比误报一个正常请求更严重。但召回率太高又会增加人工审核成本所以要在精确率和召回率之间找平衡。5.3 我自己会盯的 5 个判断点第一连续跑 100 条样本进程不退出日志不报错输出格式一致。这是稳定性。第二同样的输入跑两次风险等级尽量一致。这是可重复性。第三故意把风险样本做一下编码变形看系统还能不能识别。比如把javascript写成java%73cript如果规则层识别不出来ML 层或 LLM 层能不能识别。第四单条检测时间是否可接受。如果批量检测时平均一条要 20 秒那就要考虑并发、降级和队列。第五误报的样本能不能通过日志回溯原因。系统要回答“为什么这条正常请求被判成风险”是规则命中还是 ML还是 LLM。否则上线后没人敢用。6. 常见问题和排错顺序以及毕设展示建议6.1 报错排查顺序很多报错不是模型问题而是环境和输入问题。我的排查顺序是看现象是启动报错、运行卡住还是输出为空。看输入格式CSV 字段有没有缺失JSON 字段名对不对文本编码是不是 UTF-8。看依赖版本transformers、torch、scikit-learn 之间版本是否兼容。看资源配置内存是否被占满显存是否不够磁盘是不是写满了。看模型路径本地模型目录是否完整有没有缺少 config.json 或 tokenizer 文件。如果 LLM 输出一直解析失败先不要怀疑模型“笨”。先打印原始返回结果看是不是输出里混了 Markdown 代码块、额外解释文字或者 JSON 格式不合法。如果是要调整提示词让它严格只输出 JSON。如果批量任务跑到一半卡住先看是不是并发太高把内存打满了。把并发数降到 1加上日志输出重跑一次看卡在哪一条样本上。6.2 低配置环境的降载方案如果机器配置不够不要硬扛直接降载。LLM 使用更小的模型或者改用云 API。不使用 GPU使用 CPU 推理但要调低批大小。只对 ML 概率大于阈值的样本做 LLM 复核。批量检测时每次只处理 50 条分批写入结果不要一次性全放内存。低配置能跑通不代表适合大批量跑。所以在论文里可以把“不同配置下的吞吐量”作为一个实验小节这会比单纯说“支持大数据量”更有说服力。6.3 合规边界很重要写 XSS 检测项目时千万不要把系统描述成“自动化攻击工具”。在文档和 PPT 里要明确写清楚使用范围仅用于自建靶场、安全教育、授权渗透测试。不收集用户真实数据。检测结果只做评估和告警不执行任何利用行为。检测系统里不需要包含“攻击载荷库”这种敏感命名。叫“风险样本库”或“测试样本集”更合适也更符合安全开发习惯。6.4 可以继续扩展的方向如果做完基础版本时间还够可以从四个方向扩展。一是增加告警通知。检测到高风险后通过 Webhook 发送消息演示效果更直观。二是增加仪表盘。用表格展示检测总数、风险分布、误报率、每条样本的检测链路方便评审老师看。三是做样本去重和聚类。很多风险样本是同一模式聚成一类后更容易总结特征。四是做规则自学习。把历史误报和漏报样本入训练集定期重新训练 ML 模型。真正把这个项目落地之后你会发现难点不是某个模型调得多好而是把输入格式、日志、异常处理、参数降级、输出一致性这些事情理顺。智能检测系统的价值恰恰来自这些容易被忽略的工程细节。如果只是跑通一个 Demo那它只能算课程作业如果能把这套链路讲清楚、测明白它才是一个完整可用的毕业设计作品。