跳转到帖子

咖啡馆实战:网站反向代理、CDN 与源站之间的权限边界排查

精选回复

发布于

背景网站接入 CDN、WAF 或 Nginx 反向代理后,公网入口看起来只剩一个域名,但真实攻击面通常还包括源站 IP、备用域名、健康检查端口和运维入口。授权渗透中常见的问题不是代理本身失效,而是源站仍允许任意公网地址直连,或后端无条件信任客户端可控的 X-Forwarded-For,导致访问控制、限速和审计同时失真。本文以一套典型架构为例:CDN/WAF → 公网 Nginx → 应用服务。测试目标仅限已授权资产,重点验证源站绕过、真实客户端 IP 传递、管理路径访问边界及日志留痕。问题定位先建立资产和信任链,不要一上来扫描整个网段。需要向网站维护方确认域名、代理出口地址段、源站地址、应用监听端口、管理路径以及允许测试的时间窗口。随后分别从代理入口和源站入口请求同一资源,比较状态码、响应头、证书、页面摘要和日志记录。DOMAIN= 正常代理入口\ncurl -skD proxy.hdr -o proxy.body 在授权范围内,将域名直接解析到源站,保留正确的 TLS SNI 与 Host\ncurl -skD origin.hdr -o origin.body \\\n --resolve ${DOMAIN}:443:${ORIGIN} proxy.body origin.body\ndiff -u proxy.hdr origin.hdr | sed -n '1,120p'如果源站请求返回与代理入口相同的业务页面,而源站防火墙又没有限制 CDN/WAF 回源地址,基本可以确认存在入口边界缺口。若代理入口对管理路径返回 403,但直连源站返回 200,问题已经从“暴露源站”升级为“安全控制可绕过”。技术分析需要把三个边界分开判断:网络边界:源站 80/443 是否只允许可信代理地址段访问。应用边界:管理路径是否还具备独立认证,而不是只依赖 WAF 规则或来源 IP。身份边界:后端是否仅从可信代理接收真实客户端 IP,是否允许用户自行伪造转发头。一个常见误配置是直接使用 $http_x_forwarded_for 作为客户端地址。该变量保存原始请求头,公网用户可以自行构造。正确做法是先声明可信代理,再让 realip 模块从约定头中递归解析地址;同时,源站网络层仍应拒绝非代理流量。仅修 Nginx 日志格式并不能消除绕过。操作步骤第一步,低频确认源站是否响应目标虚拟主机。测试时使用 --resolve,避免修改系统 hosts,也避免因直接访问 IP 导致 SNI 不匹配。只请求根路径、健康检查路径和双方确认的管理路径,不做目录爆破。第二步,验证转发头信任关系。在代理入口发送一个文档地址作为 X-Forwarded-For 测试值,然后由维护方查看代理日志与应用日志。如果应用将该值直接记为客户端地址,说明后端信任范围过宽。# 仅用于自有或明确授权环境中的日志验证\ncurl -sk -H 'X-Forwarded-For: 198.51.100.77' \\\n 服务端同时观察代理与应用日志\nsudo tail -F /var/log/nginx/access.log \\\n /srv/app/log/access.log第三步,检查 Nginx 实际生效配置,而不是只看某个配置文件。nginx -T 能展开 include,适合发现遗留虚拟主机、重复监听和错误的 real_ip 配置。sudo nginx -T 2>&1 | grep -nE \\\n 'listen|server_name|set_real_ip_from|real_ip_header|real_ip_recursive|allow|deny|access_log'第四步,关联日志。建议临时记录连接源地址、解析后的客户端地址、原始转发头、请求 ID、上游地址和耗时。这样可以区分“用户直连源站”和“用户经可信代理访问”。log_format edge_audit '$time_iso8601 rid=$request_id '
'peer=$remote_addr realip_remote=$realip_remote_addr '
'xff=

网络流量与边界分析示意图
网络请求、日志与边界流量分析示意
服务器与云环境安全示意图
服务器、云资产与权限边界梳理示意

这类问题建议不要只看“域名是否走了 CDN”,而是把权限边界拆成三段验证:客户端到 CDN、CDN 到反代、反代到应用。最容易漏的是源站仍可被公网直连,攻击者只要从历史 DNS、证书透明日志或扫描结果拿到源 IP,就能绕过 CDN 上的 WAF、限速和鉴权。

先确认源站是否接受非 CDN 流量。不要只用 IP 直连测试,还要带上真实 Host,因为不少虚拟主机默认站点返回 404,但指定 Host 后仍能访问:

curl -vk --resolve example.com:443:ORIGIN_IP 
curl -vk  -H 'Host: example.com'

# 对比 CDN 与源站响应头、状态码和正文摘要
curl -skI 
curl -skI --resolve example.com:443:ORIGIN_IP 

源站入口应在安全组或防火墙层只允许 CDN 回源网段,而不是仅在 Nginx 里判断请求头。若 CDN 支持回源 mTLS,优先使用客户端证书;否则至少配置一个由 CDN 注入、外部无法覆盖的回源密钥,并确保 CDN 会先删除客户端同名头。

# Nginx:第二层校验,不能替代防火墙白名单
map $http_x_origin_token $origin_ok {
    default 0;
    "替换为高强度随机值" 1;
}

server {
    listen 443 ssl;
    server_name example.com;

    if ($origin_ok = 0) { return 444; }

    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass 
    }
}

另外重点检查真实客户端 IP 的信任链。只有 CDN 出口地址可以被设为 trusted proxy;如果无条件信任 X-Forwarded-For 或 CF-Connecting-IP 一类头,直连源站时就可能伪造 IP,绕过后台白名单或限流。

# 仅示意,网段要从 CDN 官方接口同步并定期更新
set_real_ip_from 203.0.113.0/24;
real_ip_header X-Forwarded-For;
real_ip_recursive on;

最后检查缓存权限边界:登录态页面、后台接口、带 Authorization 的请求不应进入公共缓存。可分别使用两个账号请求同一 URL,观察 Age、Cache-Status、Vary 和正文是否串号;同时测试查询参数、Cookie、大小写及路径规范化是否影响缓存键。敏感路径建议直接配置 bypass/no-store,而不是依赖应用临时返回头。

排查时最好保留 CDN 请求 ID、反代 access log 和应用 trace ID,按同一请求串起来。日志至少记录原始对端 IP、解析后的客户端 IP、Host、回源鉴权结果和缓存状态,这样能明确问题究竟出在 CDN 策略、源站暴露,还是应用错误信任代理头。

创建帐户或登录后发表意见

最近浏览 0

  • 没有会员查看此页面。