From 72a99def518c71c5350cf1027ac02e32914d23fa Mon Sep 17 00:00:00 2001 From: Jeff Cantrill Date: Mon, 28 Sep 2026 16:37:56 -0400 Subject: [PATCH] fix(security): pin journalctl_path in generated journald source The Vector journald source exposes an optional `journalctl_path`. When it is unset Vector performs a PATH search for the `journalctl` binary, and the field is config-controllable, so an injected config could point it at an attacker-placed binary and achieve arbitrary binary execution (LOG-9759 / FIND-003, CWE-73). Harden the operator-generated collector config by pinning `journalctl_path` to the trusted absolute path `/usr/bin/journalctl` (where journalctl ships in the collector image). The deployed collector no longer relies on a PATH search or a defaultable/overridable value. Co-Authored-By: Claude Opus 4.8 --- internal/generator/vector/api/sources/journald_source.go | 6 ++++++ internal/generator/vector/conf/complex.toml | 1 + internal/generator/vector/conf/complex_http_receiver.toml | 1 + internal/generator/vector/input/infrastructure.toml | 1 + internal/generator/vector/input/infrastructure_journal.toml | 1 + 5 files changed, 10 insertions(+) diff --git a/internal/generator/vector/api/sources/journald_source.go b/internal/generator/vector/api/sources/journald_source.go index 2ae472cfc..4b647e2b8 100644 --- a/internal/generator/vector/api/sources/journald_source.go +++ b/internal/generator/vector/api/sources/journald_source.go @@ -9,12 +9,18 @@ type Journald struct { Type types.SourceType `json:"type" yaml:"type" toml:"type"` JournalDirectory string `json:"journal_directory" yaml:"journal_directory" toml:"journal_directory"` + + // JournalctlPath is pinned to the absolute path of the trusted journalctl binary so the + // collector never falls back to a PATH search or a config-controlled override, which could + // otherwise be used to execute an attacker-placed binary (LOG-9759 / FIND-003). + JournalctlPath string `json:"journalctl_path" yaml:"journalctl_path" toml:"journalctl_path"` } func NewJournalD() Journald { return Journald{ Type: types.SourceTypeJournald, JournalDirectory: "/var/log/journal", + JournalctlPath: "/usr/bin/journalctl", } } diff --git a/internal/generator/vector/conf/complex.toml b/internal/generator/vector/conf/complex.toml index 8f1a20fdb..f5763f532 100644 --- a/internal/generator/vector/conf/complex.toml +++ b/internal/generator/vector/conf/complex.toml @@ -468,6 +468,7 @@ if !exists(._internal.level) { [sources.input_infrastructure_journal] type = "journald" journal_directory = "/var/log/journal" +journalctl_path = "/usr/bin/journalctl" [transforms.input_infrastructure_journal_meta] type = "remap" diff --git a/internal/generator/vector/conf/complex_http_receiver.toml b/internal/generator/vector/conf/complex_http_receiver.toml index 82b3459ff..c6f74e490 100644 --- a/internal/generator/vector/conf/complex_http_receiver.toml +++ b/internal/generator/vector/conf/complex_http_receiver.toml @@ -470,6 +470,7 @@ if exists(._internal.file) && !exists(._internal.kubernetes.namespace_name) { [sources.input_infrastructure_journal] type = "journald" journal_directory = "/var/log/journal" +journalctl_path = "/usr/bin/journalctl" [transforms.input_infrastructure_journal_meta] type = "remap" diff --git a/internal/generator/vector/input/infrastructure.toml b/internal/generator/vector/input/infrastructure.toml index caf4dbce6..30d6d51e4 100644 --- a/internal/generator/vector/input/infrastructure.toml +++ b/internal/generator/vector/input/infrastructure.toml @@ -148,6 +148,7 @@ if !exists(._internal.level) { [sources.input_infrastructure_journal] type = "journald" journal_directory = "/var/log/journal" +journalctl_path = "/usr/bin/journalctl" [transforms.input_infrastructure_journal_meta] type = "remap" diff --git a/internal/generator/vector/input/infrastructure_journal.toml b/internal/generator/vector/input/infrastructure_journal.toml index 1f4a7847c..59f4c58c9 100644 --- a/internal/generator/vector/input/infrastructure_journal.toml +++ b/internal/generator/vector/input/infrastructure_journal.toml @@ -1,6 +1,7 @@ [sources.input_myinfra_journal] type = "journald" journal_directory = "/var/log/journal" +journalctl_path = "/usr/bin/journalctl" [transforms.input_myinfra_journal_meta] type = "remap"