Please report security vulnerabilities through GitHub Private Vulnerability Reporting on this repository:
Security tab → Report a vulnerability
This opens a private advisory visible only to the maintainers. Please do not open a public issue for a suspected vulnerability, and please do not disclose it publicly until a fix is available.
Include, as far as you can: the affected version, a description of the issue, and
a minimal reproduction (ideally a failing test that builds a
Cbox\Siem\ValueObjects\SiemEvent and asserts on a formatter's output — no live
network or SIEM is needed).
This is a volunteer, best-effort project. We will acknowledge reports and work a
fix as promptly as we reasonably can, but we do not commit to a fixed response
or remediation SLA, we do not operate a security@ mailbox or a PGP key, and
we are not a CVE Numbering Authority. GitHub's advisory workflow is the single
supported channel.
This library follows semantic versioning. Until a 1.0.0 release, security fixes
land on the latest 0.x line; there is no back-porting to earlier 0.x releases.
This package formats normalized events into SIEM wire schemas. It does no network I/O, opens no sockets, holds no credentials, and has zero runtime dependencies. Its entire security surface is therefore a single concern:
A SIEM record is often a single line (CEF/syslog) or a structured document parsed downstream. If a value that an attacker can influence — a username, a message, a context field — is written into a record without escaping, it can forge record structure: break out of a field, inject an extra key, or (worst) emit a raw newline that a syslog/NDJSON framer reads as a second, attacker-authored event.
The CEF formatter is the sharp edge, because CEF is a pipe-delimited header
plus a key=value extension on one syslog line. All CEF escaping is isolated in
Cbox\Siem\Support\CefEscaper and follows the current Micro Focus CEF rules:
| Context | Escaped | Not escaped |
|---|---|---|
| Header fields | \ → \\, | → \|, CR/LF neutralized |
= |
| Extension values | \ → \\, = → \=, CR/LF neutralized |
| |
Key guarantees:
- Backslash is escaped first, so introduced escapes are never double-escaped.
- Newline neutralization is unconditional. There is no constructor flag or configuration switch that can disable it — a raw CR or LF is never emitted in any field, in any code path. (This is a deliberate response to the class of bug where a config toggle silently re-opened newline injection.)
- The escaping in the extension follows the modern rule (escape
\in extension values); the deprecated 2006 ArcSight guidance that said not to is not followed.
This is proven by an adversarial test (tests/Unit/CefFormatterTest.php): an
event whose action, message, and a context value each contain |, =, \, and
a CR/LF is formatted, and the output is asserted to (a) keep the header field
count stable — no forged header field, (b) keep the extension key set stable — no
forged key, and (c) contain no raw newline — no injected second record. The other
formatters emit JSON via json_encode, which escapes control characters
(including newlines) by construction.
Everything past a formatted string is not this package's responsibility and
is handled by the Laravel wrapper cboxdk/laravel-siem:
- Egress / SSRF protection on the destination endpoint.
- TLS, authentication, and API tokens or HEC keys.
- Encrypted secret storage.
- Batching, retries, back-pressure, and dead-letter handling.
The core deliberately treats a StreamTarget's endpoint as an opaque
string it never dials or validates, precisely so those decisions are made in the
layer equipped to make them safely. Treat this package as a careful formatter,
not a delivery system.