1、CRLF
需要注意的地方:
a)rewrite, return, add_header, proxy_set_header or proxy_pass中
b)使用了$uri和$document_uri,因为这两个参数会进行URL解码,正确配置应该是$request_uri。

c)变量,例如(?P<myvar>[^.]+).

这里先测试一下$uri
添加一条配置

location /sectest {
  return 302 https://$host$uri;
}

结果如下:

 

修改配置为

location /sectest {
  return 302 https://$host$request_uri;
}

结果如下:

测试一下匹配变量导致的CRLF
添加

    location ~ /v1/((?<action>[^.]*)\.json)?$ {
        add_header X-Action $action;
        return 200 "OK";
    }

结果如下:

应该修改正则为

    location ~ /v1/((?<action>[^.\s]*)\.json)?$ {
        add_header X-Action $action;
        return 200 "OK";
    }

2、HTTP头覆盖
如果location有add_header,那么以location为准。如果location没有add_header,则继承Http和server块的add_header内容。
官方配置例子如下:

server {
  listen 80;
  add_header X-Frame-Options "DENY" always;
  location / {
      return 200 "index";
  }

  location /new-headers {
    # Add special cache control
    add_header Cache-Control "no-cache, no-store, max-age=0, must-revalidate" always;
    add_header Pragma "no-cache" always;

    return 200 "new-headers";
  }
}

如果访问/,响应头中有X-Frame-Options

GET / HTTP/1.0

HTTP/1.1 200 OK
Server: nginx/1.10.2
Date: Mon, 09 Jan 2017 19:28:33 GMT
Content-Type: application/octet-stream
Content-Length: 5
Connection: close
X-Frame-Options: DENY

index

如果访问/new-headers,响应头中没有X-Frame-Options

GET /new-headers HTTP/1.0


HTTP/1.1 200 OK
Server: nginx/1.10.2
Date: Mon, 09 Jan 2017 19:29:46 GMT
Content-Type: application/octet-stream
Content-Length: 11
Connection: close
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache

new-headers

 

3、alias导致的任意文件读取
错误配置示例如下:

location /files {
  alias /home/;
}

这里如果访问http://example.com/files/readme.txt,就可以获取/home/readme.txt文件。
如果访问http://example.com/files../etc/passwd就可以读取/etc/passwd

需要注意,这里只能添加一个../,也就是跳到上层的目录,这里我修改nginx的配置如下:

        location /files {
                alias /home/elk/;
        }

修复建议:
location和alias的最后必须都带/或者都不带/

Gixy介绍
开源程序https://github.com/yandex/gixy用来检测Nginx配置中存在的问题
安装使用:

pip install gixy
gixy /etc/nginx/nginx.conf

检查项如下:

[ssrf] Server Side Request Forgery
[http_splitting] HTTP Splitting
[origins] Problems with referrer/origin validation
[add_header_redefinition] Redefining of response headers by "add_header" directive
[host_spoofing] Request's Host header forgery
[valid_referers] none in valid_referers
[add_header_multiline] Multiline response headers

参考文章:
https://www.leavesongs.com/PENETRATION/nginx-insecure-configuration.html
https://mp.weixin.qq.com/s?__biz=MzIzOTQ5NjUzOQ==&mid=2247483699&idx=1&sn=6f0394df7be9aafd65c12002c2bb4f10&chksm=e9287d07de5ff41165757618d932021e1b8e036fd0c1b8305e38ad693097cf05e37b76928eb5&mpshare=1&scene=23&srcid=0714xbWwfcwuCe7XA9oIQryo#rd