Django 1.6 最佳实践: 服务器和代码安全 (2)

在我们的博客中, 记录了我们在开发过程中所使用的技术和遇到的问题, 希望作为其他开发和设计者的一个学习交流平台.

Django 1.6 最佳实践: 服务器和代码安全 (2)


10. 使用django form验证

django form是一个绝佳的验证python dict数据的框架. 大多数时间我们都用它来验证包含POST数据的HTTP request. 但我们也可以更广泛的使用它. 例如我们可以使用它来验证用户上传的csv文件中的数据, 这样就避免了直接将用户输入的数据保存到数据库的危险:

    import csv
    import StringIO

    from django import forms

    from .model import Purchase, Seller


    class PurchaseForm(forms.ModelForm):

        class Meta:
            model = Purchase

        def clean_seller(self):
            seller = self.cleaned_data['seller']
            try:
                Seller.objects.get(name=seller)
            except Seller.DoesNotExist:
                msg = "{0} does not exist in purchase #{1}".format(seller, self.cleaned_data[purchase_number])
                raise forms.ValidationError(msd)
        return seller

    def add_csv_purchases(rows):

        rows = StringIO.StringIO(rows)

        records_added = 0
        errors = []

        for row in csv.DictReader(rows, delimiter=','):
            form = PurchaseForm(row)
            if form.is_valid():
                form.save()
                records_added += 1
            else:
                errors.append(form.errors)
        return records_added, errors

11. 关闭支付信息的Autocomplete

在用户填写支付信息的HTML input项中应当关闭Autocomplete. 这样在兼容该功能的浏览器中, 便不会提示保存这些敏感信息的提示了:

    from django import forms

    class SpecialForm(forms.Form):
        my_secret = forms.CharField(widget=forms.TextInput(attrs={'autocomplete': 'off'}))

12. 谨慎对待用户上传的文件

唯一能保证用户上传的文件被安全的呈现的方式是通过不同的域名呈现这些文件. 这也是为什么安全专家们推荐使用CDN的原因之一, CDN为我们提供了一个储存含有潜在危险的文件的地方.

当我们无法使用CDN时, 我们就需要确保文件保存的目录无法运行该文件.使用django的FileField和ImageField时, 虽然有默认的验证, 但我们最好还是再确认一下用户上传的文件类型与内容是否一致, 我们可以使用python-magic, pillow等来实现这一功能.

13. 不使用ModelForms.Meta.exclude

使用ModelForms时, 使用Meta.fields代替Meta.exclude. 因为这一设置会导致除了我们明确指明的field外, 其他field都能被修改, 为我们留下了安全隐患, 特别是当model中的field有所增加时.

14. 不使用ModelForms.Meta.fields='__all__'

使用ModelForms.Meta.fields='__all__'产生的安全隐患与使用Meta.exclude十分类似.

15. 小心SQL注入

django ORM对SQL有所屏蔽, 但在使用raw SQL时, 则需要我们格外小心.

16. 不要储存信用卡信息

除非你对PCI-DSS安全标准非常了解, 并且有足够的钱, 时间和精力来测试PCI兼容性, 否则不要保存信用卡信息. 我们还推荐使用第三方服务比如支付宝, paypal等方式处理支付功能.

17. 加固django admin

  • 改变默认的django admin地址
  • 使用djangi-admin-honeypot, 自动在/admin/显示一个假的admin登录页面, 并保存登录者的信息.
  • 尽量使用HTTPS
  • 可根据IP地址限制用户访问django admin
  • 小心使用 allow_tag, 当allow_tag=True时, admin中允许显示HTMLtag, 所以要小心

18. 保护好admin docs

如果你开启了admin docs, 最好能像django admin那样保护他们.

19. 检测dajngo站点

定期检查web server的logs和errors, 注意黑客攻击.

20. 定期升级依赖模块

应当定期将依赖模块升级到最新稳定版, 特别是Django自身.

21. 防止clickjacking

clickjacking是指黑客制作的网站, 引导用户去点击某一元素, 但用户点击的其实是隐藏在frame或iframe中的其他内容. 比如将购买按钮影藏在"赞"之后, 当用户点击时, 其实是为黑客埋单了.

22. 使用defusedcml

黑客攻击XML库并不是什么新鲜事了, 但不幸的的是Python没有预料到这一点, 并且其他第三方库例如lxml非常容易受到攻击. 幸好, 我们还有defusedxml, 一个专门用于代替python自带的xml库的第三方库.

23. 安全检查列表

可以使用Pony Checkup, 它会自动检查Django站点的安全性.

24. 提供反馈页

允许用户反馈错误也是一个不错的主意, GitHub就有这样一个页面: https://bounty.github.com/submit-a-vulnerability.html

25. 预备措施

你需要准备好一套对策来应对可能出现的问题, 基本的计划如下:

  • 关闭所有东西, 或置于只读模式
  • 发布静态页面告知用户
  • 备份所有东西
  • 发email给security@djangoproject.com, 即使是你的错误导致的
  • 开始解决问题

26. 跟进其他安全最佳实践

安全策略总是在进化的, 因此我们也必须紧跟这些最佳实践. 你可以订阅django发布页和其他安全相关的博客.


原文链接: http://www.weiguda.com/blog/36/