You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Even if the user is unauthorized, files send via a form will be processed. In case of large files, even local temp files will be created. This can be used for DoS attacks, by flooding the Flask service with large files, filling the temp drive and/or keeping the service threads occupied until the whole service becomes unresponsive 💣 .
Please run this example code, upload a large file and authenticate yourself with a wrong username/password combination. Watch the service process the large file (response takes some time, service is occupied by this task) or even debug and watch the temporary file being created on the disk, despite a wrong authentication was given 😢 .
"""Flask-Restx is used for easier file upload, as it provides a Swagger-UI user interface, otherwise it is not neededNavigate to http://127.0.0.1:5000/ and use the GUI to upload a large filePlace a debug-point in the last line `return self.cls(fields), self.cls(files)` of werkzeug.formparser.MultiPartParserclass and observe, how the temporary file is created and stored locally, despite no authorization was provided."""fromflaskimportFlaskfromflask_httpauthimportHTTPBasicAuthfromflask_restximportApifromflask_restximportreqparse, Resourcefromwerkzeug.datastructuresimportFileStoragefromwerkzeug.securityimportgenerate_password_hash, check_password_hashapp=Flask(__name__)
auth=HTTPBasicAuth()
api=Api(app)
# doesn't matter:users= {
"john": generate_password_hash("hello"),
"susan": generate_password_hash("bye")
}
parser=reqparse.RequestParser()
parser.add_argument('some_file', location='files', type=FileStorage, required=True,
help="Please upload a large file (GBytes) and authenticate yourself with a wrong username")
@auth.verify_passworddefverify_password(username, password):
""" This doesn't matter, call the service with a wrong user, send file will still be processed """ifusernameinusersandcheck_password_hash(users.get(username),
password):
returnusername@api.route('/upload')classHelloWorld(Resource):
@api.expect(parser)@auth.login_requireddefpost(self):
return {'hello': 'world'}
if__name__=='__main__':
app.run(debug=True, host='127.0.0.1')
I would suggest, NOT to clear the TCP receive buffer of any pending data, when the authentication is invalid.
For others: My workaround is to use flask.abort(401) immediately, after the username and password verification fails in the verify_password function.
The text was updated successfully, but these errors were encountered:
This is a change that was contributed many years ago (#38 and #39). I don't remember much about that bug report, but yeah, seems it would be best for this extension to not read the request, considering the possibility that resources (memory, disk space) have to be used. For any cases where this is a problem, the application and read the request itself at their own risk.
I discovered, that when using Flask Swagger-UI and uploading 100 MByte files via formdata fields, not clearing the TCP receive buffer leads to a "Failed to Fetch" when using the browser. By emptying the TCP receive buffer, like it was done prior to version 4.5.0, the actual response is transported back to the user and no failed to fetch error occurs.
I hope I'm wrong, but maybe I found a security issue 🔓
Line 166 is problematic:
Flask-HTTPAuth/src/flask_httpauth.py
Lines 164 to 166 in dc6de2d
Even if the user is unauthorized, files send via a form will be processed. In case of large files, even local temp files will be created. This can be used for DoS attacks, by flooding the Flask service with large files, filling the temp drive and/or keeping the service threads occupied until the whole service becomes unresponsive 💣 .
Please run this example code, upload a large file and authenticate yourself with a wrong username/password combination. Watch the service process the large file (response takes some time, service is occupied by this task) or even debug and watch the temporary file being created on the disk, despite a wrong authentication was given 😢 .
I would suggest, NOT to clear the TCP receive buffer of any pending data, when the authentication is invalid.
For others: My workaround is to use
flask.abort(401)
immediately, after the username and password verification fails in theverify_password
function.The text was updated successfully, but these errors were encountered: