Skip to content

Security: duki-core/amamiya

Security

SECURITY.md

Security Update — v1.1

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.

Summary

# 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

Details

1. TLS certificate verification disabled (ssl=False)

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.

2. Path traversal in site database loader

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.

3. ReDoS via unbounded regex input

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.

4. Output report path traversal (-o / --output)

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.

5. Unvalidated proxy URL (-p / --proxy)

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.

6. Unsanitized username in output filename

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.

7. Static User-Agent

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.

Notes on severity

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.

Upgrading

No breaking changes to the CLI. Just pull the latest version:

git pull
pip install -r requirements.txt

There aren't any published security advisories