记录一次使用Nginx修复PDF文件上传导致的XSS漏洞
问题描述
由于项目中有上传pdf文件的需求,且前期实现时是使用东方通中间件直接对外提供静态文件下载的功能,导致不容易修改该问题。
根据报告方的修改建议:
1)pdf.js升级至 4.2.67+
2)禁用isEvalSupported功能
示例:
// PDF.js配置 pdfjsLib.GlobalWorkerOptions.workerSrc = "pdf.worker.js"; pdfjsLib.disableFontFace = true; pdfjsLib.disableIsEvalSupported = true; // 显式禁用
3)添加CSP规则
示例:
Content-Security-Policy: script-src 'self' 'unsafe-inline'; object-src 'none'
4)响应头改为下载
示例:
location ~ \.pdf$ { add_header Content-Disposition "attachment"; }
5)过滤上传文件内容
结合项目实际条件决定使用Nginx增加响应头的方式对达到禁止浏览器直接打开PDF文件的目的,从而修复该漏洞。
Nginx配置
修改mime.types文件中pdf的相关配置
application/octet-stream pdf;
修改nginx.conf文件
http { include mime.types; default_type application/octet-stream; server { listen 443 ssl; server_name localhost; ssl_certificate D:\\nginx-1.28.0\\conf\\cert\\nginx.crt; ssl_certificate_key D:\\nginx-1.28.0\\conf\\cert\\nginx.key; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256"; ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; keepalive_timeout 300; client_header_timeout 300; client_body_timeout 300; send_timeout 300; location ~* \.pdf$ { proxy_pass http://192.168.1.2$request_uri; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; add_header X-Content-Type-Options nosniff; add_header X-Download-Options noopen; add_header Content-Disposition "attachment" always; } location / { proxy_pass http://192.168.1.2$request_uri; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 200m; add_header X-Content-Type-Options nosniff; } } }