来源:[同程安全应急响应中心](https://mp.weixin.qq.com/s?__biz=MzI4MzI4MDg1NA==&mid=2247483817&idx=1&sn=5a1fd58b65edf4b88d2f455a486b97bd)
作者:**Nearg1e@YSRC**
来自 @Phithon 的一个漏洞。
问题出现在:`django.views.static.serve()`函数上。该函数可以用来指定web站点的静态文件目录。如:
```python
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^staticp/(?P<path>.*)$', serve, {'document_root': os.path.join(settings.BASE_DIR, 'staticpath')})
]
```
这样django项目根目录下staticpath中的所有文件,就可以在staticp/目录中访问。e.g. `http://127.0.0.1:8000/staticp/test.css`
这种方法是不被django官方推荐在生成环境使用的,对安全性和性能都有一定影响。
问题代码如下 (django/views/static.py):
```python
path = posixpath.normpath(unquote(path))
path = path.lstrip('/')
newpath = ''
for part in path.split('/'):
if not part:
### Strip empty path components.
continue
drive, part = os.path.splitdrive(part)
head, part = os.path.split(part)
if part in (os.curdir, os.pardir):
### Strip '.' and '..' in path.
continue
newpath = os.path.join(newpath, part).replace('\\', '/')
if newpath and path != newpath:
return HttpResponseRedirect(newpath)
```
path既我们传入的路径,如果传入的路径为 `staticp/path.css` ,则`path=path.css` 。跟踪代码可知,path经过了unquote进行url解码,后来又 `replace('\\', '/')`,进入HttpResponseRedirect,很诡异的逻辑看起来很有问题。一般遇到这类型的函数我们会先试着找看看,任意文件读漏洞,但是这个对’.’和’..’进行了过滤,所以这边这个HttpResponseRedirect函数就成了帅的人的目标。
我们的最终目的是 `HttpResponseRedirect('//evil.neargle.com')`
或者 `HttpResponseRedirect('http://evil.neargle.com')`,那么就要使 `path != newpath`,那么path里面就必须带有’\‘,好的现在的我们传入 `’/staticp/%5C%5Cblog.neargle.com’` ,则`path=’\\blog.neargle.com’,newpath=’//blog.neargle.com’,HttpResponseRedirect` 就会跳转到 ’blog.neargle.com’ 造成跳转漏洞。
#### 修复
![](https://images.seebug.org/content/images/2017/04/014D1D4F-5DEE-42A9-8D22-3F9C31CC354D.png)
嗯,官方表示自己也不知道为什么要写这串代码,删了这一串代码然后用safe_url函数代替。
暂无评论