/python-source-code-analysis

Python Source Code Analysis

GNU General Public License v3.0GPL-3.0

Python Source Code Analysis

You can access vulnerable web applications written in Python from the links below.

OWASP Vulnerable Flask App

Vulnerable Flask App

Vulnerable SOAP Service

SQL Injection

The SQL injection vulnerability occurred because the parametric query was not used:

cur.execute("select * from test where username = '%s'" % name)

XSS/HTML Injection

XSS and HTML Injection vulnerability occurs as a result of screen suppression by combining the output with the "Welcome" statement without input control.

@app.route("/welcome2/<string:name>")
def welcome2(name):
    data="Welcome "+name
    return data

SSTI

The SSTI vulnerability occurred because the person did not check the input in the template he wrote:

@app.route("/welcome2/<string:name>")
def welcome2(name):
    data="Welcome "+name
    return data
@app.route("/hello")
def hello_ssti():
    if request.args.get('name'):
        name = request.args.get('name')
        template = f'''<div>
        <h1>Hello</h1>
        {name}
</div>
'''
		return render_template_string(template)

Command Injection

In the command injection vulnerability, the input received from the user is run with the subprocess module without any control.

@app.route("/get_users")
def get_users():
    try:
        hostname = request.args.get('hostname')
        command = "dig " + hostname
        data = subprocess.check_output(command, shell=True)
        return data
    except:
        data = str(hostname) + " username didn't found"
        return data
    @rpc( _returns=String)
    def get_log(ctx):
        try:
            command="cat soap_server.log"
            data=subprocess.check_output(command,shell=True)
            return(str(data))
        except:
            return("Command didn't run")

Information Disclosure

Since every transaction made in the application is logged, critical information will occur in the logs.

@app.route("/get_log/")
def get_log():
    try:
        command="cat restapi.log"
        data=subprocess.check_output(command,shell=True)
        return data
    except:
    	pass
    @rpc( _returns=String)
    def get_log(ctx):
        try:
            command="cat soap_server.log"
            data=subprocess.check_output(command,shell=True)
            return(str(data))
        except:
            return("Command didn't run")

LFI

Since the control of the input received with the filename parameter with the GET method is not provided, the files in the system are read, thus LFI vulnerability occurs.

@app.route("/read_file")
def read_file():
    filename = request.args.get('filename')
    file = open(filename, "r")
    data = file.read()
    file.close()
    return jsonify(data=data),200
    @rpc(String, _returns=String)
    def read_file(ctx,file):
        file = open(file, "r")
        data = file.read()
        file.close()
        return(data)

Deserilization

For deserialization vulnerability with Python, pickle.loads statement can be searched in the source code.

data=pickle.loads(received_data)

DOS

DOS vulnerability occurs as a result of searching the username and password information obtained from the user with the GET method, with regex.

@app.route("/user_pass_control")
def user_pass_control():
    import re
    username=request.form.get("username")
    password=request.form.get("password")
    if re.search(username,password):
        return jsonify(data="Password include username"), 200
    else:
        return jsonify(data="Password doesn't include username"), 200

File Upload

Since the file received from the user does not have size, extension, Content-Type control, the selected file is uploaded directly to the system.

@app.route('/upload', methods = ['GET','POST'])
def uploadfile():
   import os
   if request.method == 'POST':
      f = request.files['file']
      filename=secure_filename(f.filename)
      f.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
      return 'File uploaded successfully'
   else:
      return '''
<html>
   <body>
      <form  method = "POST"  enctype = "multipart/form-data">
         <input type = "file" name = "file" />
         <input type = "submit"/>
      </form>   
   </body>
</html>
      '''

Improper Output Neutralization for Logs

With the Improper Output Neutralization for Logs vulnerability, the attacker can understand that any data can be written to the logs and can inject malicious code or cause the logs to be displayed incorrectly.

@app.route('/logs')
def ImproperOutputNeutralizationforLogs():
    data = request.args.get('data')
    import logging
    logging.basicConfig(filename="restapi.log", filemode='w', level=logging.DEBUG)
    logging.debug(data)
    return jsonify(data="Logging ok"), 200