Security

Maigret: stored XSS in HTML and PDF reports

Maigret HTML and PDF reports - stored XSS from scanned profile data because Jinja2 autoescaping was off (GHSA-8969-3269-9c98)

PUBLISHED SEVERITY HIGHSTATUS PatchedGHSA-8969-3269-9c98
Patched

Fixed in maigret 0.6.2 (2026-07-01): report templates now render with Jinja2 autoescaping and links are escaped. Track the fix at soxoj/maigret@f2e4f8d.

Product
Maigret (PyPI maigret) in soxoj/maigret
Affected versions
maigret before 0.6.2. Fixed in 0.6.2 (2026-07-01).
Severity
HIGH
Status
Patched
Weaknesses
  • CWE-79Improper Neutralization of Input During Web Page Generation (Cross-site Scripting)
GitHub advisory
GHSA-8969-3269-9c98
Private; accepted and closed by the maintainer, not published
CVE
Pending (requested from MITRE)
Published
Credit
Finder: Aaron Elijah Mars of Aeon. Tool: Aeon (https://www.aeon.fun).

What users should do now

  1. Upgrade Maigret to 0.6.2 or later (pip install -U maigret).
  2. Treat HTML reports generated by older versions as untrusted: do not open them in a browser profile that is logged in to anything sensitive.

Summary

Maigret builds its HTML and PDF reports with a Jinja2 template. Before 0.6.2 the template was created with autoescaping off, and the report embeds profile fields (name, bio, location, avatar URL and similar) extracted from the scanned sites. The person being investigated controls those fields, so they can plant markup that runs as script when the investigator opens the report, either from disk or inline in Maigret's web UI.

Affected versions

maigret before 0.6.2, both the CLI (--html, --pdf) and the web UI, which serves reports inline as text/html.

Impact

  • CLI. A report written to disk runs the injected script when opened in a browser, and can read and send out the whole report (every discovered profile and linked personal data).
  • Web UI. Reports are served from the app's own origin, so the script runs same-origin with the app: it can read other investigations' reports on the same instance and send requests to the app as the user.
  • The attacker is the subject of the lookup and the victim is the investigator, which inverts the tool's trust model.

Affected code

  • maigret/report.py: Template(template_content) (Jinja2 defaults to autoescape=False), used for both report templates
  • maigret/resources/simple_report.tpl: profile fields and the avatar URL rendered unescaped
  • maigret/utils.py: enrich_link_str() built HTML links with raw string interpolation

Fix

  • f2e4f8d creates the template with autoescape=True and escapes the generated links, so only intentional markup is emitted. Released in 0.6.2.

Detection (for defenders)

Look in generated HTML reports for <script>, event-handler attributes such as onerror=, or javascript: URLs inside profile fields.

Timeline

  1. Reported privately via GitHub PVR (GHSA-8969-3269-9c98), with a suggested fix.
  2. Maintainer merges the fix (f2e4f8d).
  3. Maintainer closes the advisory without publishing it.
  4. maigret 0.6.2 released with the fix.
  5. CVE ID requested from MITRE.
  6. Public write-up.

Credit

Finder: Aaron Elijah Mars of Aeon. Tool: Aeon.

References