Security #8633
closedsuricata-update: rule archive path traversal allows arbitrary file write
Description
- Summary
`suricata-update` can write attacker-controlled files outside of the rules output directory when installing a downloaded rule archive. The embedded-file copy handling for rule keywords such as `lua`, `filemd5`, `filesha1`, and `filesha256` does not confine the derived output path. A malicious archive member containing `../`, referenced by a matching rule keyword, can escape the rules directory and write to an arbitrary filesystem location writable by the user running `suricata-update`.
This has been reported against suricata-update 1.3.7 and current master at commit `210e0b6`. The reporter did not find a prior CVE or GHSA.
- Affected area
The report identifies the following contributing behavior in current source:
- Archive extraction strips leading `/` but preserves `../` in tar and zip member names before storing non-`.rules` members in the dependency file map.
- File keyword values for `filemd5`, `filesha1`, `filesha256`, `dataset`, and `lua` are stored verbatim.
- `handle_embedded_file()` derives the destination with `os.path.join(config.get_output_dir(), os.path.dirname(dest_filename))`, but `dest_filename` can retain traversal components. Only the leaf filename is reduced with `basename()`, so the directory portion can escape the configured output directory.
The write path is reachable in both merged and non-merged update modes.
- Impact
An attacker who controls a ruleset archive can cause `suricata-update` to write an attacker-controlled UTF-8 text file outside the rules directory. The impact depends on the privileges of the account running `suricata-update`; if it runs as root, this can become code execution, for example by writing cron, profile, authorized key, or configuration files.
This bypasses Suricata rule-content containment because the filesystem write occurs during update processing, before the engine loads or tests the resulting ruleset. The reporter's PoC notes that a subsequent `suricata -T` failure may revert `suricata.rules`, but does not revert the already-written embedded file.
- Preconditions
Exploitation requires:
- A downloaded archive source, such as tar or zip, rather than a single plain `.rules` URL.
- Attacker control of the archive bytes, for example a hostile third-party source or a compromised rule feed, mirror, or CDN.
- A payload suitable for text-mode writing.
Ruleset archives are a common delivery format for managed rule feeds, so this is a realistic supply-chain threat.
- Proof of concept
The reporter provided a docker-compose lab that demonstrates the issue end-to-end with suricata-update 1.3.7. The default demonstration configures a poisoned source, runs `suricata-update` from root cron, writes `/etc/cron.d/suri_autocron` outside the rules directory, and confirms execution as root. Additional manual examples demonstrate tar plus `lua` writing to `/etc/cron.d` and zip plus `filemd5` writing to `/etc/profile.d`.
- Suggested remediation
- Confine embedded-file writes by resolving the intended output path and requiring it to remain within the resolved output directory, for example with `realpath`/`commonpath`.
- Reject absolute paths and `..` components in embedded-file keyword values and extracted archive member names.
- Use Python tar extraction filtering for tar archives and explicit equivalent validation for zip archives.
- Mirror the existing path checks used by dataset save handling.
- Consider signed rule archives as a systemic defense against malicious or compromised rule sources.
- Credit
Reported by Guillem Lefait.
Files
JI Updated by Jason Ish about 2 months ago
- Target version deleted (
TBD)
JI Updated by Jason Ish about 2 months ago
- Project changed from Suricata to Suricata-Update
- Status changed from New to Assigned
- Assignee changed from OISF Dev to Jason Ish
- Target version set to 1.3.8
- Severity set to HIGH
- Affected Versions 1.3.7 added
JI Updated by Jason Ish about 1 month ago
- File lab-su-update-01.zip lab-su-update-01.zip added
- File SU-UPDATE-01.md SU-UPDATE-01.md added
JI Updated by Jason Ish about 1 month ago
- GHSA set to GHSA-6v4p-4w5x-9fp2