Question about CSP and XSS

I’m about to launch a public facing website for the first time and I want to make sure I don’t have any glaring security vulnerabilities.

To my understanding CSP (Content Security Policy) and, by extension Django-CSP), help prevent XSS attacks, i.e. injection of malicious code into the page to be loaded by other users. On the other hand, Django is supposed to prevent most XSS attacks by escaping some (but not all) potentially bad code.

I’ve implemented sanitization of all user input and at no point in my site is there any direct user input that is visible by others without first passing through the server. Am I correct in assuming that I’m pretty much covered and not widely open to XSS attacks? I’ve spent the last several hours researching and manually whitelisting every possible hash (which has been incredibly annoying and feels somewhat hacky, and prone to bugs since it’s all manual), and I’ve been wondering if I’d overdone it? Does my use case allow me to skip CSP if I’ve bleached all user input? Thanks

First, I’ll quote from the CSP spec itself at Content Security Policy Level 3.

CSP is not intended as a first line of defense against content injection vulnerabilities. Instead, CSP is best used as defense-in-depth. It reduces the harm that a malicious injection can cause, but it is not a replacement for careful input validation and output encoding.

So yes, you’re taking the right route by sanitizing user input. But don’t forget that you also want it filtered and sanitized on output as well.

Also, don’t forget that there are other security topics to account for as well, such as CSRF.

Finally, I’ll toss in my standard recommendations that you move the admin off of the admin/ url - make it something really non-obvious, and ensure you don’t use anything like admin or root as your superuser account. (Sometimes, “security-by-obscurity” does significantly reduce your vulnerability surface.)

Hi Ken,
first - thank you for taking the time to respond.

I’ve covered CSRF, the cases you mentioned, as well as OWASP Top 10 and read through the MDN topics on security.

Could you please give an example of a possible vulnerability by improper output? To my knowledge Django automatically escapes output in templates, so if I’m using the templates do generate some HTML, even if I use that HTML in a JavaScript’s .innerHTML, I should be fine. Or at least that’s what I’ve seen by doing some basic test. There is a strong possibility I’m very wrong.

Thanks again

You are correct.

However, Django also provides the facilities for not automatically escaping output. You have the autoescape off tag, the safe and safeseq filters, and the ability to identify strings as a SafeString - all of which can bypass the template’s normal escape processing.

Additionally, with the growth of JavaScript SPA frameworks, you can have JavaScript generating HTML for a page where the data being used for that HTML does not go through Django’s processing, because you’re not rendering the data as a template in Django.

So it’s not that you’re “wrong” here - you’re not. You just need to be aware that these facilities exist, and you can’t ignore the possibilities when you’re performing a security review of your project. (In other words, you can’t just say “Oh, I don’t have to worry about that because Django does it for me.” You need to approach it as "Do we have any code that bypasses this default processing.)

Thanks again, Ken!