[Flask] Generic way of input filtering and output encoding to prevent XSS
Scott Werner
scott.werner.vt at gmail.com
Tue Oct 3 17:50:32 EDT 2017
Why is description being converted from "foobar<script>alert(1)</script>"
to ”}foobar{“"? Are you using flask jsonify when creating your API
response?
>>> import json
>>> form_data =
json.loads('{"description":"foobar<script>alert(1)</script>"}')
{'description': 'foobar<script>alert(1)</script>'}
>>> json.dumps(form_data)
'{"description": "foobar<script>alert(1)</script>"}'
- You should serialize (dumping) and de-serialize (loading) using a
library like https://marshmallow.readthedocs.io/en/latest/.
- If the user can input html, like a rich editor, and you display it in
Angular (not escaped), then you should sanitize it with a library like
https://github.com/mozilla/bleach.
- A quick search shows that you can also sanitize on the client side
using angular:
https://docs.angularjs.org/api/ngSanitize/service/$sanitize.
In summary, never trust the user and always validate on the server.
On Tue, Oct 3, 2017 at 2:57 PM, Ritesh Nadhani <riteshn at gmail.com> wrote:
> Hello
>
> I inherited a Flask + Angular app where all the APIs are basically API
> calls. As is usual, through some forms allow users to provide names
> for object and we save it to our DB which can be retreived back. This
> happens with multiple apis.
>
> E.g.
>
> HTTP POST:
> POST /api/v2/flags HTTP/1.1
> ....
> Content-Type: application/json;charset=utf-8
> Content-Length: 109
> ...
>
> {
> "description":"foobar<script>alert(1)</script>",
> "name":"test99",
> "permission":"NO_ACCESS",
> "type":"watchlist"
> }
>
> HTTP RESPONSE:
> HTTP/1.1 200 OK Server: nginx/1.6.2 ..
> Content-Type: application/json
> Content-Length: 1195
>
> {
> "flags":[
> {
> "description":"”}foobar{“",
> "end_time":9999999999000,
> "entities":0,
> "id":4,
> "name":"test99",
> "permission":"NO_ACCESS",
> "start_time":0,
> "type":"watchlist",
> "user_id":3
> }
> ],
> "limit":100,
> "offset":0,
> "status":"Ok",
> "total":4
> }
>
> ...
>
> we recently had a security inspection and this was deemed to be not
> properly encoding of output and vulnerable to XSS attack.
>
> >>>
>
> What is the canonical way to handle this? Since the name is used as
> reference and other place, ideally I would not like to keep encoded
> version into the DB. Is there a generic library that can encode the
> output before sending it back to the client? I suspect in that case UI
> will have to decode the data in every case to show the correct string
> to user?
>
> I tested against some website e.g. digitalocean and I noticed that if
> you enter such string in the form, its blocked by cloudflare itself.
> Since we dont use cloudflare, what is our other options?
>
>
> --
> Ritesh
> _______________________________________________
> Flask mailing list
> Flask at python.org
> https://mail.python.org/mailman/listinfo/flask
>
--
Scott Werner
scott.werner.vt at gmail.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/flask/attachments/20171003/5ce3f20f/attachment.html>
More information about the Flask
mailing list