You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django是否自动清理URL以防范目录遍历攻击?

问题

我在Django Web应用中编写了如下视图函数:

def download_func(request, url):
    file_url = '/home/mylaptop/myproject/' + url
    file = open(file_url, "rb").read()
    response = HttpResponse(file, content_type="application/octect-stream")
    response['Content-Disposition'] = 'attachment; filename = %s' %url
    return response

同时配置了如下URL规则:

urlpatterns = [
    ...
    url(r'^media/videos/(?P<url>[-._\w]+)/$', views.download_func),
    ...
]

此前上传的视频下载功能运行完全正常,现咨询Django是否会自动清理URL以防范目录遍历攻击?

回答

直接说结论:Django本身不会自动清理URL参数来防范目录遍历攻击——你当前的功能能正常运行且没出安全问题,主要是你的URL正则表达式帮你挡住了大部分风险,而非Django的自动处理。

具体拆解下:

  • 你的URL规则里用了[-._\w]+这个正则,它只允许匹配字母、数字、下划线、连字符和点号,这意味着用户根本无法传入包含../的路径片段(因为/不在允许的字符列表里)。这类典型的目录遍历请求(比如../secret_config.txt)会直接不匹配你的URL规则,返回404,所以暂时不会有问题。
  • 但要警惕:如果未来你修改URL正则,允许了/或者其他特殊字符,直接把url参数拼接到文件路径里就会立刻暴露给目录遍历攻击——攻击者可以构造包含../的参数,跳出你指定的项目目录,访问服务器上的其他敏感文件。

给你几个优化建议,让下载功能更健壮安全:

  1. 强制验证文件路径范围:用os.path模块的工具来确保最终文件路径始终在你预期的目录内,即使URL参数被篡改也不会越界。示例代码如下:
import os
from django.http import HttpResponseForbidden, HttpResponseNotFound

def download_func(request, url):
    base_dir = '/home/mylaptop/myproject/'
    # 用os.path.join拼接路径,避免手动拼接的潜在问题
    file_path = os.path.join(base_dir, url)
    # 规范化路径,消除所有相对路径符号
    file_path = os.path.abspath(file_path)
    
    # 检查最终路径是否在base_dir的范围内
    if not os.path.commonprefix([file_path, base_dir]) == base_dir:
        return HttpResponseForbidden("无权访问该文件")
    
    # 额外检查文件是否存在,避免报错
    if not os.path.isfile(file_path):
        return HttpResponseNotFound("文件不存在")
    
    # 用with语句打开文件,确保资源正确释放
    with open(file_path, "rb") as f:
        file_content = f.read()
    
    # 注意:你之前的content_type拼写错误,应该是octet而非octect
    response = HttpResponse(file_content, content_type="application/octet-stream")
    # 用文件名的basename来设置下载文件名,更安全
    response['Content-Disposition'] = f'attachment; filename="{os.path.basename(url)}"'
    return response
  1. 修正content_type拼写错误:你代码里写的application/octect-stream是拼写错误,正确的是application/octet-stream,这个小问题可能导致部分浏览器无法正确识别下载文件类型。
  2. 使用with语句管理文件:相比直接open()后读取,with语句会自动关闭文件句柄,避免服务器资源泄漏。

总结一下:你当前的实现因为URL正则的限制暂时安全,但安全完全依赖你自己的代码逻辑,Django没有自动处理这类风险的机制。添加路径验证步骤后,即使未来URL规则调整,也能有效防范目录遍历攻击。

内容的提问来源于stack exchange,提问作者Amirhossein Saemi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:24:12