为什么Apache无法阻止此SQL注入漏洞

时间:2018-08-02 16:25:51

标签: django apache mod-wsgi

我有一个Django / Apache / mod_wsgi堆栈,并且我试图隔离并消除自动扫描引发的潜在SQL注入漏洞。扫描确定了一个潜在的易受攻击的URL:

http://example.com/admin/

如果请求参数包含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看到两者之间的差异

  

http://example.com/admin/?something=pg_sleep()

和(例如)

  

http://example.com/admin/?something=sleep()

即使django应用程序中存在SQL漏洞,请求也不应走得那么远。为什么apache让它通过,为什么它默默地这样做呢?

完整的Apache虚拟主机供参考:

{{1}}

0 个答案:

没有答案