From 8408fedf5a23570d2395bc313ace483406b786cd Mon Sep 17 00:00:00 2001 From: Username Date: Thu, 25 Dec 2025 20:43:28 +0100 Subject: [PATCH] fix lint errors (unused vars, line length, formatting) --- app/config.py | 4 +-- app/pki.py | 4 +-- tests/fuzz/run_fuzz.py | 58 ++++++++++++++++++++---------------------- 3 files changed, 30 insertions(+), 36 deletions(-) diff --git a/app/config.py b/app/config.py index 8ea44f1..0725662 100644 --- a/app/config.py +++ b/app/config.py @@ -104,9 +104,7 @@ class Config: # Maximum unique IPs tracked in rate limit storage (RATE-001: memory DoS protection) RATE_LIMIT_MAX_ENTRIES = int(os.environ.get("FLASKPASTE_RATE_MAX_ENTRIES", "10000")) # RATE-002: Cleanup threshold (0.0-1.0) - trigger cleanup when entries exceed this ratio - RATE_LIMIT_CLEANUP_THRESHOLD = float( - os.environ.get("FLASKPASTE_RATE_CLEANUP_THRESHOLD", "0.8") - ) + RATE_LIMIT_CLEANUP_THRESHOLD = float(os.environ.get("FLASKPASTE_RATE_CLEANUP_THRESHOLD", "0.8")) # ENUM-001: Rate limiting for paste lookups (prevents enumeration attacks) # Separate from creation limits - allows more reads but prevents brute-force diff --git a/app/pki.py b/app/pki.py index f7ac53e..d28d3ce 100644 --- a/app/pki.py +++ b/app/pki.py @@ -276,9 +276,7 @@ class PKI: Raises: PKIError: If unable to generate unique serial after max retries """ - existing_serials = { - cert["serial"] for cert in self._certificates.values() - } + existing_serials = {cert["serial"] for cert in self._certificates.values()} for _ in range(_SERIAL_MAX_RETRIES): serial = x509.random_serial_number() diff --git a/tests/fuzz/run_fuzz.py b/tests/fuzz/run_fuzz.py index 4e64a6b..f2ad738 100755 --- a/tests/fuzz/run_fuzz.py +++ b/tests/fuzz/run_fuzz.py @@ -13,15 +13,13 @@ Examples: ./run_fuzz.py --phases 1,2,3 # Run specific phases ./run_fuzz.py --quick # Quick smoke test """ + from __future__ import annotations import argparse -import asyncio -import hashlib import json import os import random -import shutil import signal import socket import string @@ -114,9 +112,7 @@ class FlaskPasteFuzzer: def log(self, msg: str, level: str = "INFO") -> None: """Log message.""" if self.verbose or level in ("ERROR", "CRITICAL", "FINDING"): - symbol = {"INFO": "●", "ERROR": "✗", "FINDING": "⚠", "OK": "✓"}.get( - level, "●" - ) + symbol = {"INFO": "●", "ERROR": "✗", "FINDING": "⚠", "OK": "✓"}.get(level, "●") print(f"{symbol} {msg}") def start_server(self) -> bool: @@ -139,9 +135,11 @@ class FlaskPasteFuzzer: ) project_root = Path(__file__).parent.parent.parent - log_file = open(self.fuzz_dir / "logs" / "server.log", "w") + self.log_file = open( # noqa: SIM115 + self.fuzz_dir / "logs" / "server.log", "w" + ) - self.server_proc = subprocess.Popen( + self.server_proc = subprocess.Popen( # noqa: S603 [ str(project_root / "venv" / "bin" / "python"), "run.py", @@ -152,7 +150,7 @@ class FlaskPasteFuzzer: ], cwd=project_root, env=env, - stdout=log_file, + stdout=self.log_file, stderr=subprocess.STDOUT, ) @@ -165,7 +163,7 @@ class FlaskPasteFuzzer: sock.close() self.log("Server started successfully", "OK") return True - except (ConnectionRefusedError, socket.timeout): + except (TimeoutError, ConnectionRefusedError): time.sleep(0.5) self.log("Server failed to start", "ERROR") @@ -283,7 +281,7 @@ class FlaskPasteFuzzer: # HTTP method enumeration methods = ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD", "TRACE"] for method in methods: - status, body, _ = self.http_request(method, "/") + status, _body, _ = self.http_request(method, "/") requests += 1 if method == "TRACE" and status == 200: findings.append( @@ -333,7 +331,7 @@ class FlaskPasteFuzzer: ] for payload in payloads: - status, body, duration = self.http_request( + status, body, _duration = self.http_request( "POST", "/", data=payload, @@ -427,7 +425,7 @@ class FlaskPasteFuzzer: encoded = quote(payload, safe="") # Test in paste ID - status, body, duration = self.http_request("GET", f"/{encoded}") + _status, body, duration = self.http_request("GET", f"/{encoded}") requests += 1 # Timing-based detection @@ -469,7 +467,7 @@ class FlaskPasteFuzzer: ] for payload in traversal_payloads: - status, body, _ = self.http_request("GET", f"/{payload}") + _status, body, _ = self.http_request("GET", f"/{payload}") requests += 1 if b"root:" in body: @@ -494,7 +492,7 @@ class FlaskPasteFuzzer: ] for payload, indicator in ssti_payloads: - status, body, _ = self.http_request( + _status, body, _ = self.http_request( "POST", "/", data=payload.encode(), @@ -578,9 +576,7 @@ class FlaskPasteFuzzer: ] for fp in fake_fingerprints: - status, body, _ = self.http_request( - "GET", "/pastes", headers={"X-SSL-Client-SHA1": fp} - ) + status, body, _ = self.http_request("GET", "/pastes", headers={"X-SSL-Client-SHA1": fp}) requests += 1 if status == 200: @@ -609,9 +605,7 @@ class FlaskPasteFuzzer: ] for headers, desc in pow_bypasses: - status, body, _ = self.http_request( - "POST", "/", data=b"test", headers=headers - ) + status, body, _ = self.http_request("POST", "/", data=b"test", headers=headers) requests += 1 if status == 201: @@ -705,7 +699,9 @@ class FlaskPasteFuzzer: endpoint="POST /", vector="X-Expiry", description=f"Expiry manipulation ({desc}) accepted", - reproduction=f'curl -X POST {self.target}/ -d test -H "X-Expiry: {value}"', + reproduction=( + f'curl -X POST {self.target}/ -d test -H "X-Expiry: {value}"' + ), impact="Paste lifetime manipulation", ) ) @@ -734,7 +730,10 @@ class FlaskPasteFuzzer: endpoint="POST /", vector="Body size", description=f"Large payload ({size // 1024 // 1024}MB) accepted", - reproduction=f"dd if=/dev/urandom bs=1M count={size // 1024 // 1024} | curl -X POST {self.target}/ --data-binary @-", + reproduction=( + f"dd if=/dev/urandom bs=1M count={size // 1024 // 1024} | " + f"curl -X POST {self.target}/ --data-binary @-" + ), impact="Resource exhaustion", evidence=f"Upload time: {duration:.2f}s", ) @@ -747,7 +746,10 @@ class FlaskPasteFuzzer: endpoint="POST /", vector="Body size", description=f"Server crash on large payload ({size // 1024 // 1024}MB)", - reproduction=f"dd if=/dev/urandom bs=1M count={size // 1024 // 1024} | curl -X POST {self.target}/ --data-binary @-", + reproduction=( + f"dd if=/dev/urandom bs=1M count={size // 1024 // 1024} | " + f"curl -X POST {self.target}/ --data-binary @-" + ), impact="Denial of service", ) ) @@ -821,9 +823,7 @@ class FlaskPasteFuzzer: def generate_report(self) -> str: """Generate final report.""" severity_order = {"CRITICAL": 0, "HIGH": 1, "MEDIUM": 2, "LOW": 3, "INFO": 4} - sorted_findings = sorted( - self.findings, key=lambda f: severity_order.get(f.severity, 5) - ) + sorted_findings = sorted(self.findings, key=lambda f: severity_order.get(f.severity, 5)) report = [] report.append("=" * 79) @@ -931,9 +931,7 @@ class FlaskPasteFuzzer: def main() -> None: parser = argparse.ArgumentParser(description="FlaskPaste Offensive Security Tester") - parser.add_argument( - "--phases", type=str, help="Comma-separated phase numbers (e.g., 1,2,3)" - ) + parser.add_argument("--phases", type=str, help="Comma-separated phase numbers (e.g., 1,2,3)") parser.add_argument("--quick", action="store_true", help="Quick smoke test") parser.add_argument("--verbose", "-v", action="store_true", help="Verbose output") parser.add_argument("--fuzz-dir", type=str, help="Fuzzing workspace directory")