Is Django's built-in security enough? ( django的安全措施是全面的么?)

偶然看到这么一篇文章,觉得不管是什么安全措施,都要在正确的场景下正确的使用,人的意识才是最大的问题~~

注意里面关于xss的那部分

I have learned that Django provides built-in protection against the three main types of web app attacks (SQL injection, XSS and CSRF), which is really awesome.

Yet I have spoken to a few Django developers and they have essentially told me not to rely on these too heavily, if at all.

They told me to treat all data as "unsafe" and handle it appropriately.

I have two questions to ask everyone about this:

  1. Can Django's built-in security features be relied upon?
  2. What do my friends mean by "handle it (unsafe data) appropriately"? I know its about escaping and/or removing unsafe phrases and/or characters, but my biggest fear is that if I try to do that myself I will end up producing a "filter" that is worse off than Django's built in stuff. Does anyone have any guides for building on top of Django and not overriding it, in this regard?

    SQL injection. If you use Django's object-relational mapper (ORM) layer, you are basically protected from SQL injection.

    The only caveat is that you need to avoid manually forming SQL queries using string concatenation. For instance, do not use raw SQL queries (e.g., raw()). Similarly, do not use the extra() method/modifier to inject raw SQL. Do not execute custom SQL directly; if you bypass Django's ORM layer, you bypass its protections against SQL injection.

    CSRF. Django's built-in CSRF protection is good. Make sure you enable it and use it everywhere. Django provides ways to disable it locally or globally; obviously, don't do that.

    It is important that you make sure that GET requests do not have any side effects. For requests which can have a side-effect, make sure you use a POST request (and do not accept a GET request for those). This is standard web design, but some developers screw it up; Django's built-in CSRF prevention assumes you get this right.

    There are some caveats if you have subdomains (e.g., your web app is hosted on www.example.comand there is a subdomain alice.example.com that hosts user-controlled content); the built-in CSRF protection might not be sufficient in that case. That's a tricky case for a number of reasons. Most web applications won't have to worry about these caveats.

    XSS. If you use Django's template system and make sure that auto-escaping is enabled, you're 95% of the way there. Django provides an auto-escaping mechanism for stopping XSS: it'll automatically escape data that's dynamically inserted into the template, if it hasn't already been escaping (see e.g., mark_safesafe, etc.). This mechanism is good stuff, but it is not quite enough on its own. It takes you much of the way to stopping XSS, but you still have to be aware of some issues.

    In particular, Django's auto-escaping will escape data sufficiently for most HTML contexts, but in some special cases you must manually do additional escaping:

    • Make sure you quote all attributes where dynamic data is inserted. Good: <img alt="{{foo}}" ...>. Bad: <img alt={{foo}} ...>. Django's auto-escaping isn't sufficient for unquoted attribute values.

    • For data inserted into CSS (style tags and attributes) or Javascript (script blocks, event handlers, and onclick/etc. attributes), you must manually escape the data using escaping rules that are appropriate for CSS or Javascript.

    • For data inserted into an attribute where a URL is expected (e.g., a hrefimg src), you must manually validate the URL to make sure it is safe. You need to check the protocol against a whitelist of allowed protocols (e.g., http:https:mailto:ftp:, etc. -- but definitely not javascript:).

    • For data inserted inside a comment, you have to do something extra to escape -s. Actually, better yet, just don't insert dynamic data inside a HTML comment; that's an obscure corner of HTML that's just asking for subtle problems. (Similarly, don't insert dynamic data into attributes where it is crazy for user input to appear (e.g., foo class=...).)

    • You still must avoid client-side XSS (also known as DOM-based XSS) separately; Django doesn't help you with this. YOu could read Adam Barth's advice on avoiding XSS for some guidelines that will help you avoid client-side XSS.

    • If you use mark_safe to manually tell that Django that some data has already been escaped and is safe, you'd better know what you're doing, and it really better be safe. It's easy to make mistakes here if you don't know what you are doing. For example, if you generate HTML programmatically, store it into the database, and later send it back to the client (unescaped, obviously), it's very easy to make mistakes; you're on your own, and the auto-escaping won't help you.

    The reason why you have to do something extra for these cases is that Django's auto-escaping functionality uses an escaping function that is supposed to be one-size-fits-all, but in practice, one size doesn't always fit in every case; in some cases, you need to do something extra on your own.

    For more information about what escaping rules to use in these special contexts, see the OWASP XSS cheatsheet.

    Other stuff. There are some other things you didn't mention:

    For more information. See Django's documentation on security, including the chapter on security in the Django book.

 

http://security.stackexchange.com/questions/27805/is-djangos-built-in-security-enough

posted @ 2014-02-25 10:50  virusdefender  阅读(479)  评论(0编辑  收藏  举报