This release addresses several security issues found during a self-audit of the codebase. None were exploited in the wild — this tool has always been run locally by individual users — but all are fixed as defense-in-depth and to bring the code up to a standard suitable for a public OSINT tool.
| # | Issue | Severity | Status |
|---|---|---|---|
| 1 | TLS certificate verification disabled | High | ✅ Fixed |
| 2 | Path traversal in site database loader | Medium | ✅ Fixed |
| 3 | ReDoS via unbounded regex input | Medium | ✅ Fixed |
| 4 | Output report path traversal | Medium | ✅ Fixed |
| 5 | Unvalidated proxy URL | Low | ✅ Fixed |
| 6 | Unsanitized username in output filename | Low | ✅ Fixed |
| 7 | Static, easily fingerprintable User-Agent | Low | ✅ Fixed |
Where: checker.py, HTTP request configuration.
Issue: All outgoing requests were made with ssl=False, which disables TLS certificate validation entirely. This means the tool would silently accept a connection even if the certificate was invalid, expired, or presented by an attacker performing a man-in-the-middle attack — for example on a compromised network or a malicious proxy.
Fix: Changed to ssl=True. Certificates are now properly validated on every request.
Where: sites_loader.py, load_sites().
Issue: The function opened a file path without verifying it stayed within the intended project directory. The path is currently hardcoded ("data.json"), so this wasn't actively exploitable — but if a future version exposes this as a CLI flag (e.g. --data-file), an input like ../../etc/passwd could read arbitrary files.
Fix: Added path resolution and a check that the final resolved path stays within the expected base directory, rejecting anything that escapes it.
Where: checker.py, is_valid_username().
Issue: Username-format validation applies regex_check patterns (sourced from data.json) directly to user-supplied usernames with no length limit. A crafted, very long username could in theory trigger catastrophic backtracking on a vulnerable pattern, freezing the process.
Fix: Added a hard cap (MAX_USERNAME_LENGTH = 64) — usernames longer than this are rejected before any regex is evaluated. No legitimate username on any supported platform approaches this length, and bounding input length is a standard, dependency-free mitigation for backtracking blowup.
Where: main.py, report-saving logic.
Issue: The -o flag took a filename and passed it directly to open() without validation. A path like -o ../../important_file.json could overwrite files outside the intended output location.
Fix: Added resolve_output_path(), which resolves the target path and verifies it stays inside the current working directory before writing.
Where: main.py, proxy argument handling.
Issue: The proxy URL was passed straight through with no format check, leading to confusing low-level errors on malformed input, and no guardrail against obviously wrong values.
Fix: Added validate_proxy() — rejects any proxy URL that doesn't start with http://, https://, or socks5://, with a clear error message instead of a raw exception.
Where: main.py, auto-generated report filename.
Issue: The username was inserted directly into the output filename. Certain characters (< > : " / \ | ? *) are invalid in Windows filenames and could cause the write to fail or behave unexpectedly.
Fix: Added sanitize_filename_component(), which replaces unsafe characters with _ before the filename is built.
Where: main.py, request headers.
Issue: Every request used the exact same hardcoded User-Agent string, making the tool trivially fingerprintable and easy to block as a whole by any site that wanted to.
Fix: Added a small pool of real browser User-Agent strings; one is chosen at random per run.
A couple of these were flagged elsewhere as "SSRF" — worth clarifying: classic SSRF describes an attacker remotely controlling which internal/external host a server contacts. In this tool's threat model, target URLs come either from the trusted data.json database or are built from the user's own input on their own machine — so the traditional SSRF scenario doesn't really apply here. That said, the underlying ssl=False issue was real and worth fixing regardless of what it's labeled.
No breaking changes to the CLI. Just pull the latest version:
git pull
pip install -r requirements.txt