排查xss攻击应从请求中识别“写入意图”和“反射痕迹”,需在nginx日志中显式记录$request、$http_referer、$http_user_agent、$http_x_forwarded_for四个字段,并用awk命令结合状态码、referer、ua、ip、路径和时间规律综合研判,避免误报。

排查跨站攻击(XSS)流量,关键不是等页面被篡改才翻日志,而是从请求本身抓“写入意图”和“反射痕迹”。Nginx 访问日志本身不执行检测,但只要格式配置得当、分析有重点,就能快速定位真实攻击源 IP、来源路径和工具特征。
日志格式必须包含的 4 个核心字段
默认 combined 格式不足以识别 XSS 流量。需在 log_format 中显式加入:
-
$request:完整请求行,用于匹配
<script></script>、javascript:、onerror=、eval(等 XSS 载荷关键字 - $http_referer:判断是否来自钓鱼页或黑帽 SEO 页面;若为空或指向非本站域名,风险升高
-
$http_user_agent:扫描器常使用固定 UA,如
sqlmap/1.7、python-requests/2.*、curl/7.*,人工访问极少出现 -
$http_x_forwarded_for:CDN 或反向代理后,$remote_addr 是内网地址(如 10.0.0.1),真实攻击源藏在该字段中,必须启用
set_real_ip_from并配合使用
用命令快速筛出高置信 XSS 请求
以下命令可直接在终端运行,无需额外工具:
- 查含典型 XSS 关键字且返回 200/404 的请求:
awk '$9 ~ /^(200|404)$/ && $0 ~ /<script>|javascript:|onload=|eval\(|alert\(/ {print $1, $4, $7, $9, $12}' /var/log/nginx/access.log</script> - 聚焦 Referer 异常 + 高危 UA 组合:
awk -F'"' '$4 !~ /^https?:\/\/(yourdomain\.com|www\.yourdomain\.com)/ && $6 ~ /sqlmap|python-requests|curl\/[78]/ {print $1, $4, $6}' /var/log/nginx/access.log | sort | uniq -c | sort -nr - 按真实客户端 IP(取 $http_x_forwarded_for,空则 fallback 到 $remote_addr)统计可疑请求频次:
awk '{ip = $NF=="" ? $1 : $NF; if ($0 ~ /<script>|javascript:/) print ip}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -20</script>
结合上下文确认是否为真实攻击而非误报
单条含 <script></script> 的请求不等于 XSS 攻击——可能是前端调试、富文本编辑器内容、甚至合法 API 参数。需交叉验证:
- 看状态码:若大量
200响应中返回了含<script></script>的 HTML 页面,说明服务端未过滤,风险极高;若全是404或400,多为探测行为 - 看请求方法:GET 请求中 URI 含 XSS payload 是典型反射型 XSS 特征;POST 中 body 含载荷,需检查是否绕过前端校验
- 看时间规律:人工测试通常间隔数秒以上,扫描器则高频均匀(如每秒 1–3 次),可用
awk '{print substr($4,2,15)}'提取分钟级时间戳聚合分析 - 看目标路径:集中在搜索页(
/search?q=)、用户资料页(/profile?id=)、评论提交(/comment)等动态渲染入口,比访问静态资源更可疑
后续动作建议
一旦确认攻击源,不要只封 IP:
- 把对应 IP 加入 Fail2Ban 规则,自动封禁 24 小时
- 检查该 IP 是否还尝试过 SQL 注入、目录遍历(查
union select、../etc/passwd等),判断是否为综合扫描器 - 回溯其首次请求时间,查看是否已有成功注入痕迹(例如某次响应体中实际返回了
<script>alert(1)</script>) - 若发现 Referer 来自第三方黑帽站点,考虑向其托管服务商提交 abuse 投诉











