diff --git a/flask.py b/flask.py new file mode 100644 index 0000000..d0595aa --- /dev/null +++ b/flask.py @@ -0,0 +1,32 @@ +import os +from flask import Flask, request, abort + +app = Flask(__name__) + +# The directory where user files are stored +UPLOAD_DIR = "/app/user_uploads/" + +@app.route('/download') +def download_file(): + # Get the filename from a URL parameter (e.g., /download?file=report.pdf) + filename = request.args.get('file') + + if not filename: + return "Missing 'file' parameter", 400 + + # !!! VULNERABLE LINE !!! + # The user's input is directly joined to the directory path. + file_path = os.path.join(UPLOAD_DIR, filename) + + try: + # The server attempts to read and return the file + with open(file_path, 'r') as f: + return f.read() + except FileNotFoundError: + abort(404, "File not found.") + except Exception: + abort(500, "An error occurred.") + +if __name__ == '__main__': + # Note: This is a dev server, not for production. + app.run(debug=True) diff --git a/secure_code.py b/secure_code.py new file mode 100644 index 0000000..e66a4e8 --- /dev/null +++ b/secure_code.py @@ -0,0 +1,19 @@ +import subprocess + +# Get untrusted input from a user +hostname = input("Please enter the hostname to ping: ") + +# VULNERABLE: Building a command string and using shell=True +# The f-string directly inserts the user's text into the command. +command = f"ping -c 3 {hostname}" + +print(f"--- Running command: {command} ---") + +# shell=True tells Python to pass the entire string to the system's shell +# (like /bin/sh or cmd.exe) to be interpreted. +try: + subprocess.run(command, shell=True, check=True) +except subprocess.CalledProcessError as e: + print(f"Command failed: {e}") + +print("--- Ping finished ---")