Nginx配置referer校验,实现简单的防盗链

1.0 背景

对增删修改类请求接口的referer做白名单校验或 在参数中增加随机,预防跨站请求伪造漏洞


2.1 Nginx Referer模块

ngx_http_referer_module模块用于阻止"Refer"头字段中具有无效值的来源非法的域名请求。使用适当的"Referer"字段值创建请求非常容易,这些伪造的"Referer"字段可能会包括一些不合法的字段。本模块的目的不是彻底阻止此类请求,而是阻止常规浏览器发送的大量非允许"Refer"请求。还需应考虑到,即使对于有效的请求,常规浏览器也不应发送"Referer"字段。


2.2 valid_referers

| Syntax:  | valid_referers none | blocked | server_names | string ...; |
| -------- | ---------------------------------------------------------- |
| Default: | —                                                          |
| Context: | server, location                                           |
none:请求头缺少Referer字段,即空Referer

blocked:请求头Referer字段不为空(即存在Referer),但是值被代理或者防火墙删除了,这些值不以“http://”或“https://”开头,通俗点说就是允许“http://”或"https//"以外的请求。

server_names:Referer请求头白名单。

arbitrary string:任意字符串,定义服务器名称或可选的URI前缀,主机名可以使用*号开头或结尾,Referer字段中的服务器端口将被忽略掉。

regular expression:正则表达式,以“~”开头,在“http://”或"https://"之后的文本匹配。

指定合法的来源'referer', 决定了内置变量$invalid_referer的值,如果referer头部包含在这个合法值里面,这个变量被设置为0,否则设置为1. 需要注意的是:这里并不区分大小写的.


2.2.1 Example Configuration

server {
	listen 80;
	server_name app123456.eapps.dingtalkcloud.com;

	client_max_body_size 100m;
	proxy_buffering off;
	proxy_read_timeout  3600;

	access_log /var/log/nginx/app123456.eapps.dingtalkcloud.com-access.log main;
	error_log /var/log/nginx/app123456.eapps.dingtalkcloud.com.com-error.log;

        if ($host != 'app123456.eapps.dingtalkcloud.com') { 
              return 403 ; 
          } 

        valid_referers server_names none *.test.com *.dingtalkcloud.com;
        if ($invalid_referer) {
            return 403;
        }

        add_header 'X-Permitted-Cross-Domain-Policies' 'master-only';
        add_header 'X-Content-Type-Options' 'nosniff';
        add_header 'X-XSS-Protection' '1; mode=block';
        add_header 'X-Frame-Options' 'SAMEORIGIN';
        add_header 'X-Download-Options' 'noopen';

	location / {
            proxy_pass https://123456-dingtalk-h5-dev.test.com;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

        location /cb/ {
            proxy_pass https://cb.test.com/;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

}

上面配置合法的Referer为*.test.com *.dingtalkcloud.com 和 无Referer(none)(浏览器直接访问,就没有Referer) ; 其他非法Referer请求过来时, $invalid_referer 值为1 , 就return 403


2.2.1 验证效果

[root@10-80-15-202 ~]# curl  -sI --referer "https://appxxx.eapps.dingtalkcloud.com" http://app123456.eapps.dingtalkcloud.com/self-serve
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 08 Mar 2023 07:12:49 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 9316
Connection: keep-alive
Vary: Accept-Encoding
Vary: Accept-Encoding
Access-Control-Allow-Headers: accept,os,accesstoken,content-Type,X-Requested-With,Authorization,apptype,appkey,devid,token,uid,versioncode,versionname,mfg,x-request-id,x-request-uid
Access-Control-Max-Age: 2592000
Access-Control-Allow-Methods: GET, PUT, OPTIONS, POST, DELETE
Access-Control-Allow-Credentials: true
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Permitted-Cross-Domain-Policies: master-only
X-Frame-Options: SAMEORIGIN
X-Download-Options: noopen

[root@10-80-15-202 ~]# curl  -sI  http://app123456.eapps.dingtalkcloud.com/self-serve
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 08 Mar 2023 07:12:49 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 9316
Connection: keep-alive
Vary: Accept-Encoding
Vary: Accept-Encoding
Access-Control-Allow-Headers: accept,os,accesstoken,content-Type,X-Requested-With,Authorization,apptype,appkey,devid,token,uid,versioncode,versionname,mfg,x-request-id,x-request-uid
Access-Control-Max-Age: 2592000
Access-Control-Allow-Methods: GET, PUT, OPTIONS, POST, DELETE
Access-Control-Allow-Credentials: true
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Permitted-Cross-Domain-Policies: master-only
X-Frame-Options: SAMEORIGIN
X-Download-Options: noopen

[root@10-80-15-202 ~]# curl  -sI --referer "https://baidu.com" http://app123456.eapps.dingtalkcloud.com/self-serve
HTTP/1.1 403 Forbidden
Server: nginx
Date: Wed, 08 Mar 2023 07:10:41 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 146
Connection: keep-alive
Vary: Accept-Encoding
posted @ 2023-03-07 17:53  爱折腾的大臭臭  阅读(2620)  评论(0编辑  收藏  举报