nginx通过子域名隔离与csp等安全头实现xss防护:用server_name匹配租户子域,map校验合法性并return 400,独立限流、日志及proxy_set_header透传x-tenant-id;每server块强制配置content-security-policy default-src 'self'等头,禁用document.domain,cookie按子域隔离,阻断跨域脚本渗透路径。

Nginx 本身不执行 JavaScript、不渲染 HTML,所以它不能“阻止 XSS 脚本运行”,但可以通过子域隔离策略,从架构层面切断跨站脚本的渗透路径——核心是让恶意脚本无法读取、劫持或污染其他租户/应用的上下文。
用子域名做租户级逻辑隔离
每个业务或租户分配独立子域(如 admin.example.com、user.example.com、api.example.com),在 Nginx 中用 server_name 精确匹配并分块配置:
server {
listen 443 ssl;
server_name ~^(?<tenant>[a-z0-9\-]+)\.example\.com$;
# 合法性校验:只允许 2–16 位小写字母、数字、短横线
map $tenant $valid_tenant {
default 0;
"~^[a-z0-9\-]{2,16}$" 1;
}
if ($valid_tenant = 0) {
return 400;
}
# 每个子域独立日志,便于溯源
access_log /var/log/nginx/$tenant-access.log tenant_log;
# 独立限流,防一个租户拖垮全局
limit_req_zone $binary_remote_addr zone=$tenant:10m rate=50r/s;
limit_req zone=$tenant burst=20 nodelay;
# 关键:透传可信租户标识,禁用客户端伪造
proxy_set_header X-Tenant-ID $tenant;
proxy_set_header Host $tenant.example.com;
location / {
proxy_pass https://backend-$tenant;
proxy_hide_header Server;
proxy_hide_header X-Powered-By;
}
}</tenant>
配合强安全响应头阻断 XSS 利用链
子域隔离只是起点,还需每块 server 都启用现代防护头,确保即使某个子域被注入脚本,也无法突破边界:
-
Content-Security-Policy必须设为default-src 'self',禁止加载其他子域资源add_header Content-Security-Policy "default-src 'self'; script-src 'self'; connect-src 'self'; img-src 'self' data:; font-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none';" always;
-
Strict-Transport-Security强制 HTTPS,防降级劫持add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
-
X-Frame-Options: DENY或SAMEORIGIN,防点击劫持配合 XSS 扩大攻击面 -
Referrer-Policy: no-referrer-when-downgrade,避免敏感路径泄露
切断跨子域共享与通信通道
浏览器默认允许同主域下不同子域页面通过 document.domain = "example.com" 放宽同源限制——这是子域渗透的关键跳板。必须主动阻断:
- 在所有响应中添加
Origin-Agent-Cluster: ?1,启用进程级隔离(Chrome 96+) - 禁用
document.domain修改:在 HTML 中加入<meta http-equiv="origin-trial" content="...">不可行,需后端在返回 HTML 时注入 JS 报错拦截(Nginx 无法直接注入,但可配合sub_filter替换,慎用) - 更可靠的做法:不使用
document.domain,所有跨子域交互改用postMessage+ 严格origin校验,且只在明确需要互通的子域间白名单放行
防止 Cookie 跨子域窃取
若使用共享主域 Cookie(如 Domain=.example.com),攻击者一旦攻陷 blog.example.com,就可能窃取 admin.example.com 的会话。应改为:
- 每个子域使用独立 Cookie 域名:
Domain=admin.example.com - 设置
SameSite=Strict或Lax,并显式声明Secure和HttpOnly - Nginx 不生成 Cookie,但可通过
proxy_cookie_domain重写后端 Set-Cookie 头:proxy_cookie_domain ~^(.+)$ $tenant.example.com;
子域隔离不是万能盾牌,但它把原本“一损俱损”的单点风险,变成“一损仅损一域”的可控故障。配合 CSP、COOP/COEP、CORP 等现代策略,才能真正封死 XSS 向其他业务域横向渗透的通道。











