https://github.com/securityronin/snss-forensic
Chromium/Brave/Edge SNSS session-file forensic decoder — panic-free, read-only; validates the SNSS command stream, decodes navigation base::Pickle payloads, replays per-window tab state. No runtime deps.
https://github.com/securityronin/snss-forensic
brave browser-forensics chrome chromium dfir digital-forensics forensics incident-response rust session-restore snss
Last synced: 3 days ago
JSON representation
Chromium/Brave/Edge SNSS session-file forensic decoder — panic-free, read-only; validates the SNSS command stream, decodes navigation base::Pickle payloads, replays per-window tab state. No runtime deps.
- Host: GitHub
- URL: https://github.com/securityronin/snss-forensic
- Owner: SecurityRonin
- License: other
- Created: 2026-06-15T13:30:05.000Z (9 days ago)
- Default Branch: main
- Last Pushed: 2026-06-16T01:46:22.000Z (8 days ago)
- Last Synced: 2026-06-16T03:20:56.901Z (8 days ago)
- Topics: brave, browser-forensics, chrome, chromium, dfir, digital-forensics, forensics, incident-response, rust, session-restore, snss
- Language: Rust
- Size: 46.9 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Security: SECURITY.md
Awesome Lists containing this project
README
# snss-forensic
[](https://crates.io/crates/snss-core)
[](https://docs.rs/snss-core)
[](https://www.rust-lang.org)
[](LICENSE)
[](https://github.com/sponsors/h4x0r)
[](https://github.com/SecurityRonin/snss-forensic/actions/workflows/ci.yml)
[](https://github.com/SecurityRonin/snss-forensic/actions/workflows/ci.yml)
[](https://github.com/rust-secure-code/safety-dance/)
[](deny.toml)
**Chromium/Brave/Edge SNSS session-file forensics for Rust — a panic-free,
read-only decoder that validates the `SNSS` command stream, splits it into
length-prefixed records, decodes navigation-command `base::Pickle` payloads, and
replays them into the per-window tab state a browser restores on launch.**
SNSS is the append-only command-log format Chromium-family browsers use to persist
session and tab state — the `Session_*`, `Tabs_*`, and `Apps_*` files (and the
modern `Sessions/` folder) behind "restore your tabs". Each file is a 4-byte
`SNSS` magic plus a version header, followed by `u16`-length-prefixed command
records; navigation commands carry a Chromium `base::Pickle` payload.
[`snss-core`](https://crates.io/crates/snss-core) decodes that structure faithfully
and makes no judgments — no `unsafe`, no C bindings, no write path.
## Read a session file in 30 seconds
```toml
[dependencies]
snss-core = "0.1"
```
```rust
use std::io::Cursor;
// 1. Validate the SNSS header and split the command stream into records.
let stream = snss::read_records(Cursor::new(bytes))?;
// 2. Replay the commands into the per-window tab tree the browser would restore.
let replayed = snss::replay(&stream, snss::Dialect::Session);
for window in &replayed.windows {
for tab in &window.tabs {
let nav = tab.current_nav(); // the current entry of each open tab
println!("tab {} -> {} ({})", tab.id, nav.url, nav.title);
}
}
// Non-fatal anomalies (a truncated live-file tail, a bad navigation Pickle) are
// surfaced, never silently dropped:
for w in &stream.warnings { eprintln!("{w:?}"); }
# Ok::<(), snss::SnssError>(())
```
`Tabs_*` files (the recently-closed restore list) use the `Tabs` dialect; pass
`snss::Dialect::Tabs`. To walk every session source in a profile directory at
once, use `snss::SessionStore::open_dir(profile_dir)` (or
`open_default_profile()`), which reads each source and keeps per-source warnings.
## What it decodes
| Entry point | Reads | Produces |
|---|---|---|
| `read_records` | `SNSS` magic + version header, `u16`-length records | `RecordStream { version, records, warnings }` |
| `decode_navigation` | a navigation command's `base::Pickle` payload | `NavCommand { tab_id, index, url, title }` |
| `replay` | a `RecordStream` + dialect | `Replayed { windows }` — `Window`/`Tab`/`Nav` tree |
| `SessionStore::open_dir` | a profile directory | every discovered `Source` + warnings |
The `base::Pickle` decoder is 4-byte-aligned and length-prefixed exactly as
Chromium writes it (UTF-8 URLs, UTF-16-LE titles); replay applies last-write-wins
per `(tab, index)` and resolves each tab's current entry and pinned state.
## Trust but verify
SNSS files are untrusted, attacker-controllable input, so the crate is hardened
by construction:
- **`#![forbid(unsafe_code)]`** across the whole workspace — no `unsafe`, anywhere.
- **Read-only by construction** — the decoder exposes **no write path**; mutating
a browser's session store is structurally impossible through this API.
- **Panic-free** — every record length, Pickle field length, and alignment step
is bounds-checked before use; a crafted length field cannot drive an
out-of-bounds read or an allocation bomb. Malformed input surfaces as a typed
`SnssError` or a non-fatal `Warning`, never a silent default.
- **Fuzzed** — `cargo-fuzz` targets cover the record-stream reader (`records`) and
the navigation `base::Pickle` decoder (`navigation`); the invariant is "must not
panic."
- **Validated against real Chromium data** — real Brave `Session_*`/`Tabs_*`/`Apps_*`
files are read and replayed (the fixtures are gitignored — they hold personal
history), alongside byte-exact synthetic command streams. See
[`docs/validation.md`](docs/validation.md).
## Planned: the `snss-forensic` analyzer
This workspace ships the reader (`snss-core`) today. A sibling `snss-forensic`
analyzer crate — emitting severity-graded
[`forensicnomicon::report`](https://crates.io/crates/forensicnomicon) findings for
session-restore anomalies (e.g. dangling or forward-referenced tab indices,
truncated-tail recovery, replay inconsistencies) — is a planned follow-up so a
session file's anomalies aggregate uniformly with every other artifact layer. No
analyzer logic exists yet; it is not stubbed or fabricated here.
## References
- **Chromium `components/sessions`** — the canonical SNSS writer/reader (command
framing, `SNSS` magic + version header, append-only log):
- **Chromium `base::Pickle`** — the field-encoding format navigation payloads use:
---
[Privacy Policy](https://securityronin.github.io/snss-forensic/privacy/) · [Terms of Service](https://securityronin.github.io/snss-forensic/terms/) · © 2026 Security Ronin Ltd