Now that installed module packages load automatically, record where every
module came from:
- --list-modules groups the available modules by source, one line per
source with the modules comma-separated: MVT itself with its version,
each installed package with its version and VCS commit when recorded
(PEP 610 direct_url.json), and each --load-module/MVT_CUSTOM_MODULES
file with its SHA-256 hash.
- Commands log one line per module source with its version or hash and
the modules loaded from it, so command.log records exactly which
modules ran and where they came from.
- Make init_logging() idempotent: a loaded module package importing an
MVT CLI module would previously add a second console handler and
duplicate every console log line.
Python packages can already register custom CLI commands which load
automatically, but custom modules still require --load-module or the
MVT_CUSTOM_MODULES environment variable on every invocation.
Add an mvt.modules entry-point group so installed packages can register
forensic modules which load automatically into every module-running
check-* command. An entry point resolves to an iterable of MVTModule
subclasses, or a callable returning one. Broken entry points are
skipped with a warning so a faulty package cannot break MVT.
* fix(ios): scan Safari profile databases for history and browser state
Safari profiles (iOS 17 and later) keep their own databases under
Library/Safari/Profiles/<UUID>/, but SafariHistory and SafariBrowserState
only ever looked at the default profile's Library/Safari/History.db and
Library/Safari/BrowserState.db.
On a device where browsing happens inside a profile, MVT silently skipped
that history and still reported no detections, so an indicator only ever
visited within a profile went unnoticed.
Both modules now also match Library/Safari/Profiles/*/ in backups and in
filesystem dumps. No helper changes were needed: the Manifest.db lookup
already translates "*" into a SQL LIKE wildcard, and the filesystem lookup
already globs.
Found while examining an encrypted iOS 26.5.2 backup that contained 14
per-profile History.db files under
AppDomain-com.apple.mobilesafari::Library/Safari/Profiles/<UUID>/.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(ios): scope Safari redirects to history database
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Janik Besendorf <janik@besendorf.org>
* intrusion_logs: alert on certificate events and run heuristics without IOCs
SecurityEvent.check_indicators() returned early when no indicator set was
loaded, so none of its heuristic alerts (key integrity, wipe failure, crypto
self-test, certificate events) reached the alert store on a default run. On
top of that, cert_authority_installed and cert_validation_failure only emitted
log.warning and never alerted even when indicators were present.
Run the heuristic alerts independently of the loaded indicators (matching the
accessibility fix in #807) and surface the two certificate events through the
alert store at medium severity. A successfully installed root CA and a
certificate validation failure are interception/MITM-relevant signals that
belong in the alert report.
Adds regression tests for both certificate events and for heuristics firing
with no indicators loaded.
* intrusion_logs: gate certificate authority install alert on success
Failed install attempts log a warning instead of raising the
"Certificate authority installed" alert. Add a regression test
covering success encoded as bool and as int.
---------
Co-authored-by: John Kavanagh <668351+kavanista@users.noreply.github.com>
Co-authored-by: besendorf <janik@besendorf.org>