3👍
r
prefixes to strings are not retained in the string value. 'a\\b'
and r'a\b'
are exactly the same string, which has a single backslash. u
prefixes determine whether the string holds bytes or Unicode characters. In general strings in Django apps should be Unicode strings, but Python will automatically convert bytes to characters where necessary (this can blow up if you use non-ASCII characters).
None of this determines whether a string is ‘safe’.
Using the cleaned_data
store on a Form means that the data has been validated for the particular type of field it is associated with. If you have an e-mail field, then the cleaned_data
value is sure to look like a valid e-mail address. If you have a plain text field then cleaned_data
can be any string. Neither of those provide you any guarantee that a string is ‘safe’; input validation is a good thing to do in general and a useful defense-in-depth but it does not make an application secure against injection.
Since these values are not escaped as far as I can see is it possible that they are not safe?
Input values should never be escaped and are never ‘safe’. It is not the job of the input handling phase to do escaping; it is when you drop the value into a string with a different context that you have to worry about escaping.
So, when you create an HTML response with a string in, you HTML-escape that string. (But better: use a templating language that automatically escapes for you, like Django’s autoescape
.)
When you create an SQL query with a string in, you SQL-escape that string. (But better: use parameterised queries or an ORM so that you never have to create a query with string variables.)
When you create a JavaScript variable assignment with a string in, you JS-escape that string. (But better: pass the data in a DOM data-
attribute and read it from JS instead of using inline code.)
And so on. There are many different forms of escaping and there is no global escaping scheme which can protect you against the range of possible injection attacks. So leave the input as it is, and escape at the output phase, or better use existing framework tools to avoid having to explicitly escape at all.