我有一个Django / Apache / mod_wsgi堆栈,并且我试图隔离并消除自动扫描引发的潜在SQL注入漏洞。扫描确定了一个潜在的易受攻击的URL:
如果请求参数包含SQL注入模式,则返回意外的空响应,例如:
curl -I "http://example.com/admin/?username=';SELECT%20pg_sleep(3);--"
curl: (52) Empty reply from server
实际上,通过测试,我发现问题似乎是由于postgres函数调用pg_sleep()
的存在而引起的,即,您可以通过以下任一方法得到相同的空响应:
curl -I "http://example.com/admin/?something=pg_sleep(3)"
curl -I "http://example.com/admin/?something=pg_sleep()"
但不包含(例如):
curl -I "http://example.com/admin/?something=sleep()"
curl -I "http://example.com/admin/?something=pg_sleep"
curl -I "http://example.com/admin/?something=now()"
为了缓解这种情况,我通过将以下内容添加到apache VirtualHost中,阻止了通过IP地址对/admin
部分的外部访问:
<Location /admin>
Require ip ***.***.***.***
</Location>
这对于所有“正常”网址都可以正常工作,例如:
curl -I "http://example.com/admin/"
HTTP/1.1 403 Forbidden
但是对于麻烦的网址,它仍然返回空响应:
curl -I "http://example.com/admin/?username=pg_sleep()"
curl: (52) Empty reply from server
我猜想似乎是字符串pg_sleep()
的存在所特有的事实表明,这确实以某种方式绕过了<Location>
块,甚至没有到达pg_sleep()
块,并且实际上是在尝试在某个地方执行pg_sleep(10)
。尽管我应该补充一点,但没有延迟:RewriteCond %{QUERY_STRING} (.*)\((.*)\)(.*)
RewriteRule (.*) /$1? [R,NE,L]
不会暂停响应。它总是即时的。
我还尝试通过以下方式清除括号的URL:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
RewriteCond %{QUERY_STRING} (.*)\((.*)\)(.*)
RewriteRule (.*) /$1? [R,NE,L]
Alias /static /srv/example/htdocs/static
<Directory /srv/example/htdocs/static>
Require all granted
</Directory>
Alias /media /srv/example/htdocs/media
<Directory /srv/example/htdocs/media>
Require all granted
</Directory>
<Location "/admin">
Require ip ***.***.***.***
</Location>
<Directory /srv/example/app>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIDaemonProcess example user=www-data group=www-data processes=1 threads=15 maximum-requests=10000 python-path=/srv/example/lib/python2.7/site-packages
WSGIProcessGroup example
WSGIScriptAlias / /srv/example/app/wsgi.py
ErrorLog "/srv/example/log/error.log"
CustomLog ${APACHE_LOG_DIR}/example_access.log combined
LogLevel warn
</VirtualHost>
没有明显的效果。
返回空响应时,任何地方都没有记录。
我完全迷住了。
为什么Apache看到两者之间的差异
和(例如)
即使django应用程序中存在SQL漏洞,请求也不应走得那么远。为什么apache让它通过,为什么它默默地这样做呢?
完整的Apache虚拟主机供参考:
{{1}}