Flask is a very popular Python library for creating websites and APIs. I personally use it a lot in my projects and I see it deployed in production environments as well. When software engineers are developing applications they often enable debug mode for testing purposes. If this mode is enabled on production servers it can lead to remote code execution (RCE).
Werkzeug is a web server gateway interface (WSGI) web application library which Flask heavily relies on. A WSGI is a calling convention for web servers to forward requests to web applications or frameworks written in the Python programming language.
While developing applications it is very common for engineers to enable debugging to make their lives easier. What most people don't know is that enabling the debugger on Werkzeug can lead to RCE. This is a known problem and the creators of this library clearly point this out on their website and in their code documentation as shown below.
Back in 2015 Patreon got hacked using this technique which lead to 15 gigabytes of data being stolen and published online. More information about this hack can be found below:
We can easily replicate this vulnerability with the following python code:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def main():
raise
app.run("0.0.0.0",debug=True)
Notice that debug is set to "True". If we run the following script we should get a message warning us about enabling debug mode as shown below.
To help prevent this vulnerability you must enter a random PIN to use the vulnerable feature. You turn the security PIN off by setting the following environment variable:
WERKZEUG_DEBUG_PIN=off
You may be thinking that no one would actually do this but just like Patreon thousands others have turned this security feature off as shown in the following github search:
Checking for this vulnerability is extremely easy. Go to /console and if your able to execute python commands the system is vulnerable. This will allow you to execute shell commands as shown below:
import subprocess;out = subprocess.Popen(['whoami'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT);stdout,stderr = out.communicate();print(stdout);
As you can see above I was able to execute the "whoami" command. This could also be used to receive a shell from the victim.
If you see the following message this means the security PIN is enabled and you will need to know this in order to execute shell commands.
If you'r looking to easily test for this vulnerability check out the following Metasploit module:
https://www.rapid7.com/db/modules/exploit/multi/http/werkzeug_debug_rce
Note this vulnerability doesn't just impact Flask it can be found in Django as well and im sure a bunch of other web frameworks.
Flask is one of the most popular Python libraries for building APIs. If your not careful you could introduce a vulnerability which would allow hackers to gain RCE on your system. Debug mode is dangerous and disabling the security pin is even more dangerous.