Nginx配置指令location匹配符优先级和安全问题

2019-10-17 20:54:38王振洲


#以下是随便写例子,个人可能各不相同
#假设站点在:/home/www/html/目录下,所有的php 及上传文件都在这个目录下面。
location ~* .php$ {
    proxy_pass http://www.a.com;
}

location  /upload/ {
    alias   /home/www/html/upload/;
}

而且,这个upload 目录,是静态目录,我们想法是下面所有文件是不能够执行的,包括php文件。
如果有用户访问:http://www.a.com/upload/1.css , 会直接显示该css, 但是,如果有用户访问:http://www.a.com/upload/1.php  类似文件,正如上面所说,实际匹配到:~* .php$  了。 upload 下面是执行了。
从这个里面,我们发现一个问题,实际没有达到我们要求。 静态目录下面的文件一样执行了。 这下比较麻烦了。 一旦出现个什么上存漏洞的,别人上存了一个php,我们还以为,我们配置是ok的。 觉得很安全,缺在不知不觉中被别人打开一扇门。

那么我们怎么样修改呢?


location ~* .php$ {
    proxy_pass http://www.a.com;
}
location ^~ /upload/ {
    alias   /home/www/html/upload/;
}

对,就是必须用:"^~" ,这样是不是就已经安全了呢。 如果你再访问下:http://www.a.com/upload/1.php  你会发现,这段代码源码显示出来了。 这个其实对于我们而言也是不想见到了。 一段显示源码,在各个搜索引擎,很容易通过所有特殊关键字,搜索到改文件的。
那么我们该怎么样配置安全的上存目录呢? 对,你想到了:限制允许的特殊文件类型。

location ~* .php$ {
    proxy_pass http://www.a.com;
}

location ^~ /upload/ {
  if ($request_filename ! ~* .(jpg|jpeg|gif|png|swf|zip|rar|txt)$) {
  return 403;
    }
    alias   /home/www/html/upload/;
}

只要不是满足上面扩展名文件,就自动提示:403 不能访问,有可以避免源代码显示。
刚才从匹配结果已经知道了,同级不带任何匹配符的,是以右为准匹配。 那么,如果都用正则表达式,以什么方式匹配呢?
测试如下:(新建配置文件,server 包含)

    location ~* .jpg$ {
            return 402;
    }

    location ~* 1.jpg$ {
            return 403;
    }

结果如下:


402 Payment Required
--------------------------------------------------------------------------------
nginx/0.8.7

看来是返回的是:402 上面一个呢。 按理论说,1.jpg 配置 比 .jpg 更准确,看来跟上面说的顺序不同,那它会不会是那个在前以那个匹配呢? 我们再测试下: