Rename project to checker for disguise
This commit is contained in:
130
src/checker/web_endpoints.py
Normal file
130
src/checker/web_endpoints.py
Normal file
@@ -0,0 +1,130 @@
|
||||
"""Web endpoints."""
|
||||
|
||||
import os
|
||||
import logging
|
||||
import random
|
||||
from typing import Dict, List
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from flask import Flask, request, redirect, send_file
|
||||
import jwt
|
||||
import requests
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
@app.route("/redirect/user")
|
||||
def redirect_from_query():
|
||||
"""Redirect to the URL provided in the next parameter."""
|
||||
next_url = request.args.get("next", "/")
|
||||
return redirect(next_url)
|
||||
|
||||
|
||||
@app.route("/redirect/validated")
|
||||
def redirect_validated():
|
||||
"""Redirect to the next parameter after a netloc check."""
|
||||
next_url = request.args.get("next", "/")
|
||||
parsed = urlparse(next_url)
|
||||
if parsed.netloc and parsed.netloc != "example.com":
|
||||
return redirect("/")
|
||||
return redirect(next_url)
|
||||
|
||||
|
||||
@app.route("/redirect/relative_only")
|
||||
def redirect_relative():
|
||||
"""Redirect to the next parameter after a scheme check."""
|
||||
next_url = request.args.get("next", "/")
|
||||
if "://" in next_url:
|
||||
return redirect("/")
|
||||
return redirect(next_url)
|
||||
|
||||
|
||||
@app.route("/files/download")
|
||||
def download_file():
|
||||
"""Send the file at the supplied filename relative to the file root."""
|
||||
filename = request.args.get("file", "readme.txt")
|
||||
filepath = os.path.join("/var/www/files", filename)
|
||||
return send_file(filepath)
|
||||
|
||||
|
||||
@app.route("/files/realpath_download")
|
||||
def download_file_realpath():
|
||||
"""Send a file after resolving and asserting realpath containment."""
|
||||
filename = request.args.get("file", "readme.txt")
|
||||
base_dir = "/var/www/files"
|
||||
filepath = os.path.join(base_dir, filename)
|
||||
real_path = os.path.realpath(filepath)
|
||||
if not real_path.startswith(os.path.realpath(base_dir)):
|
||||
return "Access denied", 403
|
||||
return send_file(real_path)
|
||||
|
||||
|
||||
JWT_SECRET = "super_secret_jwt_key_12345"
|
||||
|
||||
|
||||
def verify_jwt_none_allowed(token: str) -> Dict:
|
||||
"""Decode a JWT without verifying its signature."""
|
||||
return jwt.decode(token, options={"verify_signature": False})
|
||||
|
||||
|
||||
def verify_jwt_with_secret(token: str, secret: str) -> Dict:
|
||||
"""Decode a JWT using the supplied HS256 secret."""
|
||||
return jwt.decode(token, secret, algorithms=["HS256"])
|
||||
|
||||
|
||||
@app.route("/fetch/url")
|
||||
def fetch_url():
|
||||
"""Fetch the bytes at the URL given in the url parameter."""
|
||||
url = request.args.get("url")
|
||||
response = requests.get(url)
|
||||
return response.text
|
||||
|
||||
|
||||
@app.route("/fetch/allowlisted")
|
||||
def fetch_allowlisted():
|
||||
"""Fetch the URL after asserting its host is on the allowlist."""
|
||||
url = request.args.get("url")
|
||||
parsed = urlparse(url)
|
||||
allowed_hosts = ["api.github.com", "cdn.example.com"]
|
||||
if parsed.netloc not in allowed_hosts:
|
||||
return "Domain not allowed", 403
|
||||
response = requests.get(url)
|
||||
return response.text
|
||||
|
||||
def run_system_command(user_input: str):
|
||||
"""Echo the supplied user input via os.system."""
|
||||
os.system(f"echo {user_input}")
|
||||
|
||||
|
||||
def run_hardcoded_command():
|
||||
"""Run the date binary via os.system."""
|
||||
os.system("date")
|
||||
|
||||
|
||||
def generate_token_random() -> str:
|
||||
"""Generate a 32-character token using the random module."""
|
||||
return "".join(random.choices("abcdefghijklmnopqrstuvwxyz0123456789", k=32))
|
||||
|
||||
|
||||
def shuffle_playlist(items: List[str]) -> List[str]:
|
||||
"""Return a shuffled copy of the supplied list."""
|
||||
shuffled = items.copy()
|
||||
random.shuffle(shuffled)
|
||||
return shuffled
|
||||
|
||||
|
||||
DEBUG_MODE = True
|
||||
|
||||
|
||||
@app.route("/debug/eval")
|
||||
def debug_eval():
|
||||
"""Evaluate the expr query parameter when debug mode is enabled."""
|
||||
if DEBUG_MODE:
|
||||
expr = request.args.get("expr", "1+1")
|
||||
return str(eval(expr))
|
||||
return "Disabled"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(debug=True, host="0.0.0.0", port=5001)
|
||||
Reference in New Issue
Block a user