python.flask.security.insecure-deserialization.insecure-deserialization
Verifed by r2c
Community Favorite

Author
99,209
Download Count*
License
Detected the use of an insecure deserialization library in a Flask route. These libraries are prone to code execution vulnerabilities. Ensure user data does not enter this function. To fix this, try to avoid serializing whole objects. Consider instead using a serializer such as JSON.
Run Locally
Run in CI
Defintion
rules:
- id: insecure-deserialization
metadata:
owasp:
- A08:2017 - Insecure Deserialization
- A08:2021 - Software and Data Integrity Failures
cwe:
- "CWE-502: Deserialization of Untrusted Data"
references:
- https://docs.python.org/3/library/pickle.html
category: security
technology:
- flask
cwe2022-top25: true
cwe2021-top25: true
subcategory:
- audit
likelihood: LOW
impact: MEDIUM
confidence: LOW
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
message: Detected the use of an insecure deserialization library in a Flask
route. These libraries are prone to code execution vulnerabilities. Ensure
user data does not enter this function. To fix this, try to avoid
serializing whole objects. Consider instead using a serializer such as
JSON.
languages:
- python
severity: ERROR
patterns:
- pattern-inside: |
@app.route(...)
def $X(...):
...
- pattern-not: $MODULE.$FUNC("...")
- pattern-not: $MODULE.$FUNC(open("...", ...))
- pattern-either:
- pattern: pickle.$FUNC(...)
- pattern: _pickle.$FUNC(...)
- pattern: cPickle.$FUNC(...)
- pattern: dill.$FUNC(...)
- pattern: shelve.$FUNC(...)
- pattern: yaml.load(...)
Examples
insecure-deserialization.py
# example from https://medium.com/gdg-vit/deserialization-attacks-d312fbe58e7d
# flask_app.py
import os
import pickle
from uuid import uuid1
from flask import Flask, make_response, request
from base64 import b64encode, b64decode
# The User Class which assigns a random ID to each connection
class UserID:
def __init__(self, uuid=None):
self.uuid = str(uuid1())
def __str__(self):
return self.uuid
# The main Flask Backend
app = Flask(__name__)
@app.route('/', methods=['GET'])
def index():
user_obj = request.cookies.get('uuid')
if user_obj == None:
msg = "Seems like you didn't have a cookie. No worries! I'll set one now!"
response = make_response(msg)
user_obj = UserID()
# ruleid:insecure-deserialization
response.set_cookie('uuid', b64encode(pickle.dumps(user_obj)))
return response
else:
# ruleid:insecure-deserialization
return "Hey there! {}!".format(pickle.loads(b64decode(user_obj)))
@app.route("/ok")
def ok():
# ok:insecure-deserialization
novellist = pickle.load(open('./novel/list.dat', "rb"))
if __name__ == "__main__":
# Using host='0.0.0.0' to accept connections from all IPs
app.run(host='0.0.0.0')
Short Link: https://sg.run/N45z