如果不使用TLS / SSL,如何在Django中删除HttpRequest连接?

时间:2012-01-22 18:57:23

标签: django ssl

我正在编写一个需要使用TLS / SSL的Django 1.3视图方法。如果在不使用TLS / SSL的情况下收到HttpRequest并且不返回任何类型的响应,我想完全删除连接。这是出于安全原因。

目前我正在回复这样的回复:

def some_view(request):
    if not request.is_secure():
        return HttpResponse(status=426)
    ...

然而,返回426 - Upgrade Required会带来一些问题:

  1. 它是2000年5月提出的标准的一部分(RFC 2817),并不是官方的HTTP标准。
  2. HttpResponse对中间人(MITM)攻击持开放态度。作为mentioned in the comments here,如果服务器在没有首先建立TLS / SSL连接的情况下向客户端返回任何类型的响应,则MITM可能会劫持响应,将其更改为在其他地方重新定向,并提供恶意重定向回应客户。
  3. 让服务器从HTTP URI重定向到HTTPS URI会对上面提到的MITM攻击开放。

    那么,如何在不返回任何类型的HttpResponse的情况下完全删除Django 1.3视图方法中的连接?

2 个答案:

答案 0 :(得分:4)

正如我在this answer中所说的那样,由于您提到的原因,我通常反对使用从http://https://的自动重定向。我肯定不会建议仅使用批量mod_rewrite - 样式重定向来保护网站。

但是,在您的情况下,当请求到达服务器时,为时已晚。如果有MITM,他会在你收到请求之前完成他的攻击(或部分攻击)。

到那时你能做的最好的事情是回复没有任何有用的内容。在这种情况下,重定向(使用301或302和Location标头)可能是合适的。但是,如果用户(甚至您作为开发人员)忽略警告(在这种情况下,浏览器将遵循重定向并几乎透明地重试请求),它可能会隐藏问题。

因此,我只建议返回404状态:

  • http://yoursite/https://yoursite/实际上是两个不同的网站。没有理由期望URI空间中的所有资源从一个到另一个的1:1映射(只是与ftp://yoursite/的完全不同的层次结构相同)。
  • 更重要的是,这是一个应该在上游处理的问题:使用http://将用户引导到此资源的链接应视为已损坏。不要让它自动工作。对于不应该存在的资源具有404状态是好的。此外,在出现错误时返回错误消息是好的:它会强迫您(或至少提醒您)作为开发人员,您需要修复导致此问题的页面/表单/链接。

如果您可以使用此框架执行此操作,则删除连接只是一个额外的好处:如果服务器可以异步发送(在客户端完成发送请求之前),如果浏览器可以,它将非常有用异步读取(在这种情况下,它应该在发生错误时立即停止发送)并且如果MITM攻击者是被动的(活动的MITM可以阻止响应通过客户端返回并确保客户端通过消费发送所有请求它有自己的“代理”,无论服务器是否已断开连接)。这些情况可能会发生,但无论如何,在源头修复问题仍然会更好。

答案 1 :(得分:2)

如果您使用Nginx作为前端代理,那么您可以使用另一个非标准HTTP状态代码444来关闭连接而不发送任何标头。 http://wiki.nginx.org/HttpRewriteModule#return这需要Nginx足够了解在HTTP上拒绝哪些网址。