fluent-vulnerability_checker 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +17 -0
- data/.github/workflows/linux.yml +2 -2
- data/.github/workflows/windows.yml +2 -2
- data/README.md +4 -0
- data/lib/fluent/vulnerability_checker/messages.yaml +183 -0
- data/lib/fluent/vulnerability_checker.rb +111 -157
- data/test/fluent/resources/unsafe/dos_in_out_file_buffer_compress_gzip.conf +7 -0
- data/test/fluent/resources/unsafe/dos_in_out_file_buffer_compress_zstd.conf +7 -0
- data/test/fluent/resources/unsafe/dos_in_out_file_compress_gzip.conf +4 -0
- data/test/fluent/resources/unsafe/dos_in_out_file_compress_zstd.conf +4 -0
- data/test/fluent/resources/unsafe/dos_in_out_file_single_buffer_compress_gzip.conf +7 -0
- data/test/fluent/resources/unsafe/dos_in_out_file_single_buffer_compress_zstd.conf +7 -0
- data/test/fluent/resources/unsafe/oom_in_http_ndjson.conf +4 -0
- data/test/fluent/resources/unsafe/oom_in_syslog.conf +3 -0
- data/test/fluent/resources/unsafe/oom_in_syslog_tcp.conf +5 -0
- data/test/fluent/test_vulnerability_checker.rb +38 -0
- metadata +14 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 96e4204851a5608ae47199c15728b16f99f3b4cf49bbe6c5ea15610a63f84993
|
|
4
|
+
data.tar.gz: 6847a3517038edaf8490bbc09acd32e99c164c610eac5629fcebd8fb6ebad254
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2e30a73a70ccc10fd8f22dcaabdf51180dc3280bba3c7490761da659bc4b035b61994682542986bd387d163d2640fd8a4884c7a48efc9ab3d35e2280c75d693f
|
|
7
|
+
data.tar.gz: 072174336f375fcae7209fe7e71daf436fc94563c05c65d81308fe89365c52570be6e39d33d4eca969c1bdd09faf111aae2712c755adc578f93bc42921823fe3
|
data/.github/dependabot.yml
CHANGED
|
@@ -4,3 +4,20 @@ updates:
|
|
|
4
4
|
directory: '/'
|
|
5
5
|
schedule:
|
|
6
6
|
interval: 'monthly'
|
|
7
|
+
groups:
|
|
8
|
+
# PR: "Security update [package] from [old] to [new]"
|
|
9
|
+
# This PR should be merged in hurry
|
|
10
|
+
security-updates:
|
|
11
|
+
applies-to: security-updates
|
|
12
|
+
patterns:
|
|
13
|
+
- '*'
|
|
14
|
+
|
|
15
|
+
# PR: "Bump [package] from [old] to [new]"
|
|
16
|
+
# No need to be merged this PR in hurry. It is enough to merge
|
|
17
|
+
# once in a month.
|
|
18
|
+
monthly-updates:
|
|
19
|
+
applies-to: version-updates
|
|
20
|
+
patterns:
|
|
21
|
+
- '*'
|
|
22
|
+
# Allow to create PR both of security and normal updates.
|
|
23
|
+
open-pull-requests-limit: 1
|
data/.github/workflows/linux.yml
CHANGED
|
@@ -25,8 +25,8 @@ jobs:
|
|
|
25
25
|
- ubuntu-latest
|
|
26
26
|
name: Ruby ${{ matrix.ruby }} unit testing on ${{ matrix.os }}
|
|
27
27
|
steps:
|
|
28
|
-
- uses: actions/checkout@
|
|
29
|
-
- uses: ruby/setup-ruby@
|
|
28
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
29
|
+
- uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
|
|
30
30
|
with:
|
|
31
31
|
ruby-version: ${{ matrix.ruby }}
|
|
32
32
|
rubygems: latest
|
|
@@ -25,8 +25,8 @@ jobs:
|
|
|
25
25
|
- windows-latest
|
|
26
26
|
name: Ruby ${{ matrix.ruby }} unit testing on ${{ matrix.os }}
|
|
27
27
|
steps:
|
|
28
|
-
- uses: actions/checkout@
|
|
29
|
-
- uses: ruby/setup-ruby@
|
|
28
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
29
|
+
- uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
|
|
30
30
|
with:
|
|
31
31
|
ruby-version: ${{ matrix.ruby }}
|
|
32
32
|
rubygems: latest
|
data/README.md
CHANGED
|
@@ -11,6 +11,10 @@ Detects configurations leading to the following vulnerabilities:
|
|
|
11
11
|
* CVE-2026-44161 [Server-Side Request Forgery (SSRF)](https://github.com/fluent/fluentd/security/advisories/GHSA-72f5-rr8c-r6gr)
|
|
12
12
|
* CVE-2026-44160 [Denial of Service (DoS)](https://github.com/fluent/fluentd/security/advisories/GHSA-j9cw-hwqf-85w7)
|
|
13
13
|
* CVE-2026-44025 [Exposure of Sensitive Information](https://github.com/fluent/fluentd/security/advisories/GHSA-pr7j-96cj-549h)
|
|
14
|
+
* [Incomplete Fix for CVE-2026-44024: Path Traversal Bypass via Bare .. Tag in Output Plugins](https://github.com/fluent/fluentd/security/advisories/GHSA-5hq3-r276-rfr5)
|
|
15
|
+
* [Out-of-Memory DoS via Object Allocation Amplification in in_http ndjson parsing](https://github.com/fluent/fluentd/security/advisories/GHSA-g69w-f42r-xp35)
|
|
16
|
+
* [Out-of-Memory DoS via Unbounded TCP/TLS Connection Buffer in in_syslog](https://github.com/fluent/fluentd/security/advisories/GHSA-h3xv-5jpx-r4j2)
|
|
17
|
+
* [Incomplete Fix for CVE-2026-44160: DoS via Unbounded Decompression in Buffer Chunk Streaming](https://github.com/fluent/fluentd/security/advisories/GHSA-x455-r5cg-h9p9)
|
|
14
18
|
|
|
15
19
|
## Installation
|
|
16
20
|
Install the gem by executing:
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# Message catalog for the vulnerabilities this tool detects.
|
|
2
|
+
#
|
|
3
|
+
# Each key should be the CVE ID of the advisory.
|
|
4
|
+
---
|
|
5
|
+
CVE-2026-44024:
|
|
6
|
+
title: Remote Code Execution (RCE) via Arbitrary File Write in Dynamic Placeholder
|
|
7
|
+
severity: Critical
|
|
8
|
+
cvss: 10.0
|
|
9
|
+
description:
|
|
10
|
+
en: |
|
|
11
|
+
If the ${tag} placeholder is used in a file path parameter of the file or secondary_file output plugin,
|
|
12
|
+
there is a risk that an attacker could write files to arbitrary paths, potentially leading to RCE.
|
|
13
|
+
ja: |
|
|
14
|
+
ファイルの出力先パスでプレースホルダーにtagを指定している場合、設定ファイルの書き方や実行権限が不適切だと、
|
|
15
|
+
任意のパスにファイルを書き込まれ、リモートからコード実行可能になる危険があります。
|
|
16
|
+
workaround:
|
|
17
|
+
en: |
|
|
18
|
+
If you cannot immediately update the package, apply mitigations such as restricting access,
|
|
19
|
+
running with non-root privileges, modifying the configuration file, or removing untrusted tags.
|
|
20
|
+
ja: |
|
|
21
|
+
すぐにパッケージを更新できない場合、アクセスの制限、非root権限での実行、設定ファイルの修正、信頼できない
|
|
22
|
+
tagを除去するなどの緩和策を適用してください。
|
|
23
|
+
|
|
24
|
+
CVE-2026-44025:
|
|
25
|
+
title: Exposure of Sensitive Information via Monitor Agent API
|
|
26
|
+
severity: High
|
|
27
|
+
cvss: 7.5
|
|
28
|
+
note: |
|
|
29
|
+
(Note: In Fluentd 1.19.2 and earlier, the default value of bind is 0.0.0.0.)
|
|
30
|
+
description:
|
|
31
|
+
en: |
|
|
32
|
+
monitor_agent is exposed externally, allowing attackers to read Fluentd configuration details via its API.
|
|
33
|
+
ja: |
|
|
34
|
+
monitor_agentによって公開されているAPIを悪用して、Fluentdの設定内容を読み取られる危険性があります。
|
|
35
|
+
workaround:
|
|
36
|
+
en: |
|
|
37
|
+
If you cannot immediately update the package, apply mitigations such as restricting access,
|
|
38
|
+
or allowing access only from localhost.
|
|
39
|
+
ja: |
|
|
40
|
+
すぐにパッケージを更新できない場合、アクセスの制限、ローカルホストからのみのアクセスを受け付けるなどの
|
|
41
|
+
緩和策を適用してください。
|
|
42
|
+
|
|
43
|
+
CVE-2026-44160:
|
|
44
|
+
title: Denial of Service (DoS) via Gzip Decompression Bomb
|
|
45
|
+
severity: High
|
|
46
|
+
cvss: 7.5
|
|
47
|
+
description:
|
|
48
|
+
en: |
|
|
49
|
+
Sending maliciously crafted gzip-compressed data to Fluentd can consume excessive memory during
|
|
50
|
+
decompression, potentially causing it to crash.
|
|
51
|
+
ja: |
|
|
52
|
+
細工したgzip圧縮データをFluentdへと送りつけることで、展開時に大量のメモリを消費させてFluentdをクラッシュ
|
|
53
|
+
する危険性があります。
|
|
54
|
+
workaround:
|
|
55
|
+
en: |
|
|
56
|
+
If you cannot immediately update the package, apply mitigations such as restricting access, or enforcing
|
|
57
|
+
size limits when decompressing content using a reverse proxy.
|
|
58
|
+
ja: |
|
|
59
|
+
すぐにパッケージを更新できない場合、アクセスの制限、リバースプロキシ等を用いたGZIP展開時のサイズ制限等の
|
|
60
|
+
緩和策を適用してください。
|
|
61
|
+
|
|
62
|
+
CVE-2026-44161:
|
|
63
|
+
title: Server-Side Request Forgery (SSRF) via Placeholder Expansion in out_http
|
|
64
|
+
severity: Moderate
|
|
65
|
+
cvss: 5.8
|
|
66
|
+
description:
|
|
67
|
+
en: |
|
|
68
|
+
When out_http determines destination servers for data transmission based on tags, this vulnerability
|
|
69
|
+
allows attackers to manipulate data transmission by sending crafted data, resulting in data being sent
|
|
70
|
+
to servers other than the intended ones.
|
|
71
|
+
ja: |
|
|
72
|
+
out_httpでデータを別のサーバーに送る際の送信先をタグから決定している場合、細工したデータを送りつけられると、
|
|
73
|
+
本来の意図とは異なるサーバーへとデータを送信してしまうことが可能な脆弱性です。
|
|
74
|
+
workaround:
|
|
75
|
+
en: |
|
|
76
|
+
If you cannot immediately update the package, apply mitigation measures such as:
|
|
77
|
+
* not dynamically setting hostnames with placeholders
|
|
78
|
+
* restricting access from untrusted networks
|
|
79
|
+
* allowing only specific hosts
|
|
80
|
+
ja: |
|
|
81
|
+
すぐにパッケージを更新できない場合、プレースホルダーでホスト名を動的に設定しない、信頼できない
|
|
82
|
+
ネットワークからのアクセスの制限、特定のホストのみ許可するなどの緩和策を適用してください。
|
|
83
|
+
|
|
84
|
+
CVE-2026-44162:
|
|
85
|
+
title: Denial of Service (DoS) via Gzip Decompression Bomb
|
|
86
|
+
severity: Low
|
|
87
|
+
cvss: 2.7
|
|
88
|
+
description:
|
|
89
|
+
en: |
|
|
90
|
+
Sending maliciously crafted gzip-compressed data from S3 to Fluentd can consume excessive memory when
|
|
91
|
+
processing requests, potentially causing it to crash.
|
|
92
|
+
ja: |
|
|
93
|
+
細工したgzip圧縮データをS3から受信することで、展開時に大量のメモリを消費してFluentdがクラッシュする
|
|
94
|
+
危険性があります。
|
|
95
|
+
workaround:
|
|
96
|
+
en: |
|
|
97
|
+
If you cannot immediately update the package, apply mitigations such as restricting access, or enforcing
|
|
98
|
+
size limits when decompressing content using a reverse proxy.
|
|
99
|
+
ja: |
|
|
100
|
+
すぐにパッケージを更新できない場合、アクセスの制限、リバースプロキシ等を用いたGZIP展開時のサイズ制限等の
|
|
101
|
+
緩和策を適用してください。
|
|
102
|
+
|
|
103
|
+
CVE-2026-44163:
|
|
104
|
+
title: Denial of Service (DoS) via Gzip Decompression Bomb or Malicious HTTP Requests
|
|
105
|
+
severity: Moderate
|
|
106
|
+
cvss: 5.3
|
|
107
|
+
description:
|
|
108
|
+
en: |
|
|
109
|
+
Sending maliciously crafted gzip-compressed data to Fluentd can consume excessive memory when processing
|
|
110
|
+
requests, potentially causing it to crash.
|
|
111
|
+
ja: |
|
|
112
|
+
細工したgzip圧縮データやHTTPリクエストを受信することで、リクエスト処理時に大量のメモリを消費してFluentdが
|
|
113
|
+
クラッシュする危険性があります。
|
|
114
|
+
workaround:
|
|
115
|
+
en: |
|
|
116
|
+
If you cannot immediately update the package, apply mitigations such as restricting access, or enforcing
|
|
117
|
+
size limits when processing requests using a reverse proxy.
|
|
118
|
+
ja: |
|
|
119
|
+
すぐにパッケージを更新できない場合、アクセスの制限、リバースプロキシ等を用いたリクエストサイズ制限等の
|
|
120
|
+
緩和策を適用してください。
|
|
121
|
+
|
|
122
|
+
CVE-2026-IN_HTTP_OOM:
|
|
123
|
+
title: Out-of-Memory DoS via Object Allocation Amplification in `in_http` ndjson parsing
|
|
124
|
+
severity: High
|
|
125
|
+
cvss: 7.5
|
|
126
|
+
description:
|
|
127
|
+
en: |
|
|
128
|
+
Out-of-Memory DoS via Object Allocation Amplification in `in_http` ndjson parsing
|
|
129
|
+
ja: |
|
|
130
|
+
in_syslogのndjsonのパースに不備があり、OOM由来のサービス拒否(DoS)につながる脆弱性があります
|
|
131
|
+
workaround:
|
|
132
|
+
en: |
|
|
133
|
+
If you cannot immediately update the package, apply mitigation measures such as:
|
|
134
|
+
* Restrict network access for `in_http`, allow connection within a closed, trusted network.
|
|
135
|
+
* Implement reverse proxy limits with forcing strict rate limiting and request
|
|
136
|
+
size limits at the proxy layer to drop anomalous requests before they reach the Fluentd worker.
|
|
137
|
+
ja: |
|
|
138
|
+
すぐに更新できない場合、次のような緩和策を検討してください。
|
|
139
|
+
* in_httpの9880ポートへのアクセスを受け付ける送信元IPをファイアウォール等で制限する
|
|
140
|
+
* Reverse proxyを間に挟み、クライアントのタイムアウトを厳密に管理したり、
|
|
141
|
+
バッファーサイズが異常なFluentdへのリクエストを遮断する
|
|
142
|
+
|
|
143
|
+
CVE-2026-IN_SYSLOG_DOS:
|
|
144
|
+
title: Out-of-Memory DoS via Unbounded TCP/TLS Connection Buffer in in_syslog
|
|
145
|
+
severity: High
|
|
146
|
+
cvss: 7.5
|
|
147
|
+
description:
|
|
148
|
+
en: |
|
|
149
|
+
Out-of-Memory DoS via Unbounded TCP/TLS Connection Buffer in in_syslog
|
|
150
|
+
ja: |
|
|
151
|
+
in_syslogのTCP/TLS接続を受け付けていると、OOM由来でサービス拒否(DoS)につながる脆弱性があります
|
|
152
|
+
workaround:
|
|
153
|
+
en: |
|
|
154
|
+
If you cannot immediately update the package, apply mitigation measures such as:
|
|
155
|
+
* Restrict network access for in_syslog, allow connection within a closed, trusted network.
|
|
156
|
+
* Switch to UDP Transport for a while.
|
|
157
|
+
ja: |
|
|
158
|
+
すぐに更新できない場合、次のような緩和策を検討してください。
|
|
159
|
+
* in_syslogの5140ポートへのアクセスを受け付ける送信元IPをファイアウォール等で制限する
|
|
160
|
+
* TCP/TLSではなく、問題が解決するまで一時的にUDP <transport udp>に置きかえる
|
|
161
|
+
* Reverse proxyを間に挟み、クライアントのタイムアウトを厳密に管理したり、
|
|
162
|
+
バッファーサイズが異常なFluentdへのリクエストを遮断する
|
|
163
|
+
|
|
164
|
+
CVE-2026-BUFFER_FILE_UNBOUNDED_DECOMPRESSION:
|
|
165
|
+
title: "Incomplete Fix for CVE-2026-44160: DoS via Unbounded Decompression in Buffer Chunk Streaming"
|
|
166
|
+
severity: Low
|
|
167
|
+
cvss: 2.9
|
|
168
|
+
description:
|
|
169
|
+
en: |
|
|
170
|
+
DoS via unbounded decompression in buffer chunk streaming. Expanding buffer might cause Out-of-Memory.
|
|
171
|
+
ja: |
|
|
172
|
+
圧縮されたバッファの扱いに不備があり、バッファ展開時にOut-of-Memory由来のサービス拒否(DoS)につながる脆弱性です。
|
|
173
|
+
workaround:
|
|
174
|
+
en: |
|
|
175
|
+
If you cannot immediately update the package, apply mitigation measures such as:
|
|
176
|
+
* Disable Buffer Compression for a while
|
|
177
|
+
* Disable automatic chunk backup with `disaable_chunk_backup`.
|
|
178
|
+
* Restrict network access only from closed, trusted network.
|
|
179
|
+
ja: |
|
|
180
|
+
すぐにパッケージを更新できない場合次のような緩和策を検討してください。
|
|
181
|
+
* <buffer>セクションのcompress gzipやcompress zstdを使わない。ただし、ディスク使用量が増えるデメリットがあります
|
|
182
|
+
* `disable_chunk_backup true`をアウトプットプラグインに指定して不正なチャンクのバックアップを無効化する
|
|
183
|
+
* `in_http`や`in_forward`といったインプットプラグインへのアクセスを信頼できる送信元のみに制限する
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'yaml'
|
|
4
|
+
|
|
3
5
|
require 'fluent/config'
|
|
4
6
|
require 'fluent/env'
|
|
5
7
|
|
|
@@ -7,21 +9,25 @@ module Fluent
|
|
|
7
9
|
class VulnerabilityChecker
|
|
8
10
|
CHUNK_ID_PLACEHOLDER_PATTERN = /\$\{chunk_id\}/
|
|
9
11
|
PLACEHOLDER_PATTERN = /\$\{.*?\}/
|
|
12
|
+
MESSAGES_PATH = File.join(__dir__, 'vulnerability_checker', 'messages.yaml')
|
|
10
13
|
|
|
11
14
|
class Rule
|
|
12
|
-
|
|
15
|
+
attr_reader :cve
|
|
16
|
+
|
|
17
|
+
def initialize(cve, plugin_categories, plugin_name = nil, &condition_proc)
|
|
18
|
+
@cve = cve
|
|
13
19
|
@plugin_categories = Array(plugin_categories)
|
|
14
20
|
@plugin_name = plugin_name
|
|
15
21
|
@condition_proc = condition_proc
|
|
16
22
|
end
|
|
17
23
|
|
|
18
|
-
def
|
|
19
|
-
@
|
|
24
|
+
def register_state_message(&state_proc)
|
|
25
|
+
@state_proc = state_proc
|
|
20
26
|
self
|
|
21
27
|
end
|
|
22
28
|
|
|
23
|
-
def
|
|
24
|
-
@
|
|
29
|
+
def state(element)
|
|
30
|
+
@state_proc&.call(element)
|
|
25
31
|
end
|
|
26
32
|
|
|
27
33
|
def safe?(element)
|
|
@@ -33,184 +39,132 @@ module Fluent
|
|
|
33
39
|
end
|
|
34
40
|
end
|
|
35
41
|
|
|
42
|
+
class Report
|
|
43
|
+
# Width of the "* State: " label. Continuation lines are aligned with it.
|
|
44
|
+
STATE_INDENT = ' ' * 14
|
|
45
|
+
# Width of the " * EN: " label.
|
|
46
|
+
TEXT_INDENT = ' ' * 8
|
|
47
|
+
|
|
48
|
+
def initialize(messages_path = MESSAGES_PATH)
|
|
49
|
+
@messages = YAML.load_file(messages_path)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def render(rule, element)
|
|
53
|
+
message = @messages.fetch(rule.cve)
|
|
54
|
+
state = rule.state(element)
|
|
55
|
+
|
|
56
|
+
lines = [
|
|
57
|
+
"# #{message['title']}",
|
|
58
|
+
"* Severity: #{message['severity']}",
|
|
59
|
+
"* CVSS Score: #{message['cvss']}",
|
|
60
|
+
"* Location: <#{element.name}> - @type #{element['@type']}"
|
|
61
|
+
]
|
|
62
|
+
if state
|
|
63
|
+
lines << "* State: #{state}"
|
|
64
|
+
lines << "#{STATE_INDENT}#{align(message['note'], STATE_INDENT)}" if message['note']
|
|
65
|
+
end
|
|
66
|
+
lines << '* Description:'
|
|
67
|
+
lines.concat(bilingual(message['description']))
|
|
68
|
+
lines << '* Workaround:'
|
|
69
|
+
lines.concat(bilingual(message['workaround']))
|
|
70
|
+
lines.join("\n")
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
private
|
|
74
|
+
|
|
75
|
+
def bilingual(texts)
|
|
76
|
+
['en', 'ja'].map { |lang| " * #{lang.upcase}: #{align(texts.fetch(lang), TEXT_INDENT)}" }
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def align(text, indent)
|
|
80
|
+
text.strip.gsub("\n", "\n#{indent}")
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
36
84
|
attr_reader :vulnerabilities # for test
|
|
37
85
|
|
|
38
86
|
def initialize
|
|
39
87
|
@vulnerabilities = 0
|
|
88
|
+
@report = Report.new
|
|
40
89
|
@rules = []
|
|
41
90
|
|
|
42
91
|
# Fluentd: RCE via ${tag} in file in output/buffer/secondary/store sections
|
|
43
|
-
@rules << Rule.new(['match', 'buffer', 'secondary', 'store'], 'file') { |element|
|
|
92
|
+
@rules << Rule.new('CVE-2026-44024', ['match', 'buffer', 'secondary', 'store'], 'file') { |element|
|
|
44
93
|
# replace the safe ${chunk_id} with an empty string to clear it, and check if the remaining string contains ${...}
|
|
45
94
|
element['path']&.gsub(CHUNK_ID_PLACEHOLDER_PATTERN, '')&.match?(PLACEHOLDER_PATTERN)
|
|
46
|
-
}.
|
|
47
|
-
<<~"MSG"
|
|
48
|
-
# Remote Code Execution (RCE) via Arbitrary File Write in Dynamic Placeholder
|
|
49
|
-
* Severity: Critical
|
|
50
|
-
* CVSS Score: 10.0
|
|
51
|
-
* Location: <#{element.name}> - @type #{element['@type']}
|
|
52
|
-
* State: path = '#{element['path']}'
|
|
53
|
-
* Description:
|
|
54
|
-
* EN: If the ${tag} placeholder is used in the path parameter of the file output plugin, there is a risk that
|
|
55
|
-
an attacker could write files to arbitrary paths, potentially leading to RCE.
|
|
56
|
-
* JA: pathでプレースホルダーにtagを指定している場合、設定ファイルの書き方や実行権限が不適切だと、任意のパスに
|
|
57
|
-
ファイルを書き込まれ、リモートからコード実行可能になる危険があります。
|
|
58
|
-
* Workaround:
|
|
59
|
-
* EN: If you cannot immediately update the package, apply mitigations such as restricting access,
|
|
60
|
-
running with non-root privileges, modifying the configuration file, or removing untrusted tags.
|
|
61
|
-
* JA: すぐにパッケージを更新できない場合、アクセスの制限、非root権限での実行、設定ファイルの修正、信頼できない
|
|
62
|
-
tagを除去するなどの緩和策を適用してください。
|
|
63
|
-
MSG
|
|
64
|
-
end
|
|
95
|
+
}.register_state_message { |element| "path = '#{element['path']}'" }
|
|
65
96
|
|
|
66
97
|
# Fluentd: RCE via ${tag} in secondary_file
|
|
67
|
-
@rules << Rule.new('secondary', 'secondary_file') { |element|
|
|
98
|
+
@rules << Rule.new('CVE-2026-44024', 'secondary', 'secondary_file') { |element|
|
|
68
99
|
# replace the safe ${chunk_id} with an empty string to clear it, and check if the remaining string contains ${...}
|
|
69
100
|
element['directory']&.gsub(CHUNK_ID_PLACEHOLDER_PATTERN, '')&.match?(PLACEHOLDER_PATTERN) ||
|
|
70
101
|
element['basename']&.gsub(CHUNK_ID_PLACEHOLDER_PATTERN, '')&.match?(PLACEHOLDER_PATTERN)
|
|
71
|
-
}.
|
|
72
|
-
|
|
73
|
-
<<~"MSG"
|
|
74
|
-
# Remote Code Execution (RCE) via Arbitrary File Write in Dynamic Placeholder
|
|
75
|
-
* Severity: Critical
|
|
76
|
-
* CVSS Score: 10.0
|
|
77
|
-
* Location: <#{element.name}> - @type #{element['@type']}
|
|
78
|
-
* State: #{state_msg}
|
|
79
|
-
* Description:
|
|
80
|
-
* EN: If the ${tag} placeholder is used in the directory or basename parameter of the secondary_file plugin,
|
|
81
|
-
there is a risk that an attacker could write files to arbitrary paths, potentially leading to RCE.
|
|
82
|
-
* JA: directoryまたはbasenameでプレースホルダーにtagを指定している場合、設定ファイルの書き方や実行権限が不適切だと、任意のパスに
|
|
83
|
-
ファイルを書き込まれ、リモートからコード実行可能になる危険があります。
|
|
84
|
-
* Workaround:
|
|
85
|
-
* EN: If you cannot immediately update the package, apply mitigations such as restricting access,
|
|
86
|
-
running with non-root privileges, modifying the configuration file, or removing untrusted tags.
|
|
87
|
-
* JA: すぐにパッケージを更新できない場合、アクセスの制限、非root権限での実行、設定ファイルの修正、信頼できない
|
|
88
|
-
tagを除去するなどの緩和策を適用してください。
|
|
89
|
-
MSG
|
|
102
|
+
}.register_state_message do |element|
|
|
103
|
+
['directory', 'basename'].map { |k| "#{k} = '#{element[k]}'" if element[k]&.match?(PLACEHOLDER_PATTERN) }.compact.join(', ')
|
|
90
104
|
end
|
|
91
105
|
|
|
92
106
|
# Fluentd: Exposure of Sensitive Information
|
|
93
|
-
@rules << Rule.new('source', 'monitor_agent') { |element|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
* State: bind = '#{element['bind'] || 'default'}'.
|
|
100
|
-
(Note: In Fluentd 1.19.2 and earlier, the default value of bind is 0.0.0.0.)
|
|
101
|
-
* Description:
|
|
102
|
-
* EN: monitor_agent is exposed externally, allowing attackers to read Fluentd configuration details via its API.
|
|
103
|
-
* JA: monitor_agentによって公開されているAPIを悪用して、Fluentdの設定内容を読み取られる危険性があります。
|
|
104
|
-
* Workaround:
|
|
105
|
-
* EN: If you cannot immediately update the package, apply mitigations such as restricting access,
|
|
106
|
-
or allowing access only from localhost.
|
|
107
|
-
* JA: すぐにパッケージを更新できない場合、アクセスの制限、ローカルホストからのみのアクセスを受け付けるなどの
|
|
108
|
-
緩和策を適用してください。
|
|
109
|
-
MSG
|
|
110
|
-
end
|
|
107
|
+
@rules << Rule.new('CVE-2026-44025', 'source', 'monitor_agent') { |element|
|
|
108
|
+
element['bind'].nil? || element['bind'] == '0.0.0.0'
|
|
109
|
+
}.register_state_message { |element| "bind = '#{element['bind'] || 'default'}'." }
|
|
110
|
+
|
|
111
|
+
# "Incomplete Fix for CVE-2026-44024: Path Traversal Bypass via Bare `..` Tag in Output Plugins"
|
|
112
|
+
# That should be covered above cases. (https://github.com/fluent/fluentd/security/advisories/GHSA-5hq3-r276-rfr5)
|
|
111
113
|
|
|
112
114
|
# Fluentd: DoS via Gzip Decompression in http input plugin
|
|
113
|
-
@rules << Rule.new('source', 'http') { |element| true }
|
|
114
|
-
<<~"MSG"
|
|
115
|
-
# Denial of Service (DoS) via Gzip Decompression Bomb
|
|
116
|
-
* Severity: High
|
|
117
|
-
* CVSS Score: 7.5
|
|
118
|
-
* Location: <#{element.name}> - @type #{element['@type']}
|
|
119
|
-
* Description:
|
|
120
|
-
* EN: Sending maliciously crafted gzip-compressed data to Fluentd can consume excessive memory during
|
|
121
|
-
decompression, potentially causing it to crash.
|
|
122
|
-
* JA: 細工したgzip圧縮データをFluentdへと送りつけることで、展開時に大量のメモリを消費させてFluentdをクラッシュ
|
|
123
|
-
する危険性があります。
|
|
124
|
-
* Workaround:
|
|
125
|
-
* EN: If you cannot immediately update the package, apply mitigations such as restricting access, or enforcing
|
|
126
|
-
size limits when decompressing content using a reverse proxy.
|
|
127
|
-
* JA: すぐにパッケージを更新できない場合、アクセスの制限、リバースプロキシ等を用いたGZIP展開時のサイズ制限等の
|
|
128
|
-
緩和策を適用してください。
|
|
129
|
-
MSG
|
|
130
|
-
end
|
|
115
|
+
@rules << Rule.new('CVE-2026-44160', 'source', 'http') { |element| true }
|
|
131
116
|
|
|
132
117
|
# Fluentd: DoS via Gzip Decompression in forward input plugin
|
|
133
|
-
@rules << Rule.new('source', 'forward') { |element| true }
|
|
134
|
-
<<~"MSG"
|
|
135
|
-
# Denial of Service (DoS) via Gzip Decompression Bomb
|
|
136
|
-
* Severity: High
|
|
137
|
-
* CVSS Score: 7.5
|
|
138
|
-
* Location: <#{element.name}> - @type #{element['@type']}
|
|
139
|
-
* Description:
|
|
140
|
-
* EN: Sending maliciously crafted gzip-compressed data to Fluentd can consume excessive memory during
|
|
141
|
-
decompression, potentially causing it to crash.
|
|
142
|
-
* JA: 細工したgzip圧縮データを受信することで、展開時に大量のメモリを消費してFluentdがクラッシュする危険性が
|
|
143
|
-
あります。
|
|
144
|
-
* Workaround:
|
|
145
|
-
* EN: If you cannot immediately update the package, apply mitigations such as restricting access, or enforcing
|
|
146
|
-
size limits when decompressing content using a reverse proxy.
|
|
147
|
-
* JA: すぐにパッケージを更新できない場合、アクセスの制限、リバースプロキシ等を用いたGZIP展開時のサイズ制限等の
|
|
148
|
-
緩和策を適用してください。
|
|
149
|
-
MSG
|
|
150
|
-
end
|
|
118
|
+
@rules << Rule.new('CVE-2026-44160', 'source', 'forward') { |element| true }
|
|
151
119
|
|
|
152
120
|
# fluent-plugin-s3: DoS via Gzip Decompression
|
|
153
|
-
@rules << Rule.new('source', 's3') { |element| true }
|
|
154
|
-
<<~"MSG"
|
|
155
|
-
# Denial of Service (DoS) via Gzip Decompression Bomb
|
|
156
|
-
* Severity: Low
|
|
157
|
-
* CVSS Score: 2.7
|
|
158
|
-
* Location: <#{element.name}> - @type #{element['@type']}
|
|
159
|
-
* Description:
|
|
160
|
-
* EN: Sending maliciously crafted gzip-compressed data from S3 to Fluentd can consume excessive memory when
|
|
161
|
-
processing requests, potentially causing it to crash.
|
|
162
|
-
* JA: 細工したgzip圧縮データをS3から受信することで、展開時に大量のメモリを消費してFluentdがクラッシュする
|
|
163
|
-
危険性があります。
|
|
164
|
-
* Workaround:
|
|
165
|
-
* EN: If you cannot immediately update the package, apply mitigations such as restricting access, or enforcing
|
|
166
|
-
size limits when decompressing content using a reverse proxy.
|
|
167
|
-
* JA: すぐにパッケージを更新できない場合、アクセスの制限、リバースプロキシ等を用いたGZIP展開時のサイズ制限等の
|
|
168
|
-
緩和策を適用してください。
|
|
169
|
-
MSG
|
|
170
|
-
end
|
|
121
|
+
@rules << Rule.new('CVE-2026-44162', 'source', 's3') { |element| true }
|
|
171
122
|
|
|
172
123
|
# fluent-plugin-opentelemetry: DoS
|
|
173
|
-
@rules << Rule.new('source', 'opentelemetry') { |element| true }
|
|
174
|
-
<<~"MSG"
|
|
175
|
-
# Denial of Service (DoS) via Gzip Decompression Bomb or Malicious HTTP Requests
|
|
176
|
-
* Severity: Moderate
|
|
177
|
-
* CVSS Score: 5.3
|
|
178
|
-
* Location: <#{element.name}> - @type #{element['@type']}
|
|
179
|
-
* Description:
|
|
180
|
-
* EN: Sending maliciously crafted gzip-compressed data to Fluentd can consume excessive memory when processing
|
|
181
|
-
requests, potentially causing it to crash.
|
|
182
|
-
* JA: 細工したgzip圧縮データやHTTPリクエストを受信することで、リクエスト処理時に大量のメモリを消費してFluentdが
|
|
183
|
-
クラッシュする危険性があります。
|
|
184
|
-
* Workaround:
|
|
185
|
-
* EN: If you cannot immediately update the package, apply mitigations such as restricting access, or enforcing
|
|
186
|
-
size limits when processing requests using a reverse proxy.
|
|
187
|
-
* JA: すぐにパッケージを更新できない場合、アクセスの制限、リバースプロキシ等を用いたリクエストサイズ制限等の
|
|
188
|
-
緩和策を適用してください。
|
|
189
|
-
MSG
|
|
190
|
-
end
|
|
124
|
+
@rules << Rule.new('CVE-2026-44163', 'source', 'opentelemetry') { |element| true }
|
|
191
125
|
|
|
192
126
|
# Fluentd: SSRF via ${endpoint} in http output plugin
|
|
193
|
-
@rules << Rule.new('match', 'http') { |element|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
127
|
+
@rules << Rule.new('CVE-2026-44161', 'match', 'http') { |element|
|
|
128
|
+
element['endpoint']&.match?(%r[https?://[^/]*\$\{])
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
# Out-of-Memory DoS via Object Allocation Amplification in `in_http` ndjson parsing
|
|
132
|
+
@rules << Rule.new('CVE-2026-IN_HTTP_OOM', 'source', 'http') { |element|
|
|
133
|
+
(
|
|
134
|
+
element['@type'] == 'http' && (
|
|
135
|
+
# no <auth> or <security>
|
|
136
|
+
(element['message_length_limit'] && element.elements.empty?) ||
|
|
137
|
+
# <auth> or <security>
|
|
138
|
+
element.elements.any? { |v| %w[auth security].include?(v.name) })
|
|
139
|
+
)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
# Out-of-Memory DoS via Unbounded TCP/TLS Connection Buffer in in_syslog
|
|
143
|
+
@rules << Rule.new('CVE-2026-IN_SYSLOG_DOS', 'source', 'syslog') { |element|
|
|
144
|
+
element['@type'] == 'syslog' && (
|
|
145
|
+
# no transport section
|
|
146
|
+
element.elements.empty? ||
|
|
147
|
+
# <transport udp> is safe
|
|
148
|
+
element.elements&.any? { |v| v.name == 'transport' && %w[tcp tls].include?(v.arg) }
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
# DoS via Unbounded Decompression in Buffer Chunk Streaming
|
|
153
|
+
@rules << Rule.new('CVE-2026-BUFFER_FILE_UNBOUNDED_DECOMPRESSION', 'match', 'file') { |element|
|
|
154
|
+
# compress in <match> section
|
|
155
|
+
element['@type'] == 'file' && %w[gzip zstd].include?(element['compress'])
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
@rules << Rule.new('CVE-2026-BUFFER_FILE_UNBOUNDED_DECOMPRESSION', 'buffer', 'file') { |element|
|
|
159
|
+
# compress in <match> section
|
|
160
|
+
element['@type'] == 'file' && %w[gzip zstd].include?(element['compress'])
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
# DoS via Unbounded Decompression in Buffer Chunk Streaming
|
|
164
|
+
@rules << Rule.new('CVE-2026-BUFFER_FILE_UNBOUNDED_DECOMPRESSION', 'buffer', 'file_single') { |element|
|
|
165
|
+
# compress in <buffer> section
|
|
166
|
+
element['@type'] == 'file_single' && %w[gzip zstd].include?(element['compress'])
|
|
167
|
+
}
|
|
214
168
|
end
|
|
215
169
|
|
|
216
170
|
def validate(config_path)
|
|
@@ -227,7 +181,7 @@ module Fluent
|
|
|
227
181
|
@rules.each do |rule|
|
|
228
182
|
unless rule.safe?(element)
|
|
229
183
|
@vulnerabilities += 1
|
|
230
|
-
puts
|
|
184
|
+
puts @report.render(rule, element)
|
|
231
185
|
puts "=" * 115
|
|
232
186
|
end
|
|
233
187
|
end
|
|
@@ -138,4 +138,42 @@ class Fluent::VulnerabilityCheckerTest < Test::Unit::TestCase
|
|
|
138
138
|
|
|
139
139
|
assert_equal(3, checker.vulnerabilities)
|
|
140
140
|
end
|
|
141
|
+
|
|
142
|
+
sub_test_case "Out-of-Memory DoS via Object Allocation Amplification in `in_http` ndjson parsing" do
|
|
143
|
+
test "Recommend to use <auth> section" do
|
|
144
|
+
config_path = path("./resources/unsafe/oom_in_http_ndjson.conf")
|
|
145
|
+
checker = Fluent::VulnerabilityChecker.new
|
|
146
|
+
checker.validate(config_path)
|
|
147
|
+
# CVE-2026-44160 is also detected here
|
|
148
|
+
assert_equal(2, checker.vulnerabilities)
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
sub_test_case "Out-of-Memory DoS via Unbounded TCP/TLS Connection Buffer in `in_syslog`" do
|
|
153
|
+
data("no transport" => "./resources/unsafe/oom_in_syslog.conf",
|
|
154
|
+
"udp transport" =>"./resources/unsafe/oom_in_syslog_tcp.conf")
|
|
155
|
+
test "Recommend to use <auth> section" do (data)
|
|
156
|
+
config_path = path(data)
|
|
157
|
+
checker = Fluent::VulnerabilityChecker.new
|
|
158
|
+
checker.validate(config_path)
|
|
159
|
+
|
|
160
|
+
assert_equal(1, checker.vulnerabilities)
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
sub_test_case "DoS via Unbounded Decompression in Buffer Chunk Streaming" do
|
|
165
|
+
data("compress gzip (traditional)" => "./resources/unsafe/dos_in_out_file_compress_gzip.conf",
|
|
166
|
+
"compress zstd (traditional)" => "./resources/unsafe/dos_in_out_file_compress_zstd.conf",
|
|
167
|
+
"buffer compress gzip" => "./resources/unsafe/dos_in_out_file_buffer_compress_gzip.conf",
|
|
168
|
+
"buffer compress zstd" => "./resources/unsafe/dos_in_out_file_buffer_compress_zstd.conf",
|
|
169
|
+
"file_single buffer compress gzip" => "./resources/unsafe/dos_in_out_file_single_buffer_compress_gzip.conf",
|
|
170
|
+
"file_single buffer compress zstd" => "./resources/unsafe/dos_in_out_file_single_buffer_compress_zstd.conf")
|
|
171
|
+
test "Recommend to disable buffer commpression" do (data)
|
|
172
|
+
config_path = path(data)
|
|
173
|
+
checker = Fluent::VulnerabilityChecker.new
|
|
174
|
+
checker.validate(config_path)
|
|
175
|
+
|
|
176
|
+
assert_equal(1, checker.vulnerabilities)
|
|
177
|
+
end
|
|
178
|
+
end
|
|
141
179
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fluent-vulnerability_checker
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Shizuo Fujita
|
|
@@ -41,14 +41,24 @@ files:
|
|
|
41
41
|
- Rakefile
|
|
42
42
|
- exe/fluent-vulnerabilitycheck
|
|
43
43
|
- lib/fluent/vulnerability_checker.rb
|
|
44
|
+
- lib/fluent/vulnerability_checker/messages.yaml
|
|
44
45
|
- test/fluent/resources/safe/in_monitor_agent.conf
|
|
45
46
|
- test/fluent/resources/safe/out_file_buffer_file.conf
|
|
46
47
|
- test/fluent/resources/safe/out_http.conf
|
|
47
48
|
- test/fluent/resources/unsafe/dos_in_forward.conf
|
|
48
49
|
- test/fluent/resources/unsafe/dos_in_http.conf
|
|
49
50
|
- test/fluent/resources/unsafe/dos_in_opentelemetry.conf
|
|
51
|
+
- test/fluent/resources/unsafe/dos_in_out_file_buffer_compress_gzip.conf
|
|
52
|
+
- test/fluent/resources/unsafe/dos_in_out_file_buffer_compress_zstd.conf
|
|
53
|
+
- test/fluent/resources/unsafe/dos_in_out_file_compress_gzip.conf
|
|
54
|
+
- test/fluent/resources/unsafe/dos_in_out_file_compress_zstd.conf
|
|
55
|
+
- test/fluent/resources/unsafe/dos_in_out_file_single_buffer_compress_gzip.conf
|
|
56
|
+
- test/fluent/resources/unsafe/dos_in_out_file_single_buffer_compress_zstd.conf
|
|
50
57
|
- test/fluent/resources/unsafe/dos_in_s3.conf
|
|
51
58
|
- test/fluent/resources/unsafe/exposure_of_sensitive_information.conf
|
|
59
|
+
- test/fluent/resources/unsafe/oom_in_http_ndjson.conf
|
|
60
|
+
- test/fluent/resources/unsafe/oom_in_syslog.conf
|
|
61
|
+
- test/fluent/resources/unsafe/oom_in_syslog_tcp.conf
|
|
52
62
|
- test/fluent/resources/unsafe/remote_code_execution_buffer_file.conf
|
|
53
63
|
- test/fluent/resources/unsafe/remote_code_execution_out_file.conf
|
|
54
64
|
- test/fluent/resources/unsafe/remote_code_execution_out_secondary_file.conf
|
|
@@ -58,7 +68,8 @@ files:
|
|
|
58
68
|
- test/fluent/resources/unsafe/test_vulnerable.yaml
|
|
59
69
|
- test/fluent/test_vulnerability_checker.rb
|
|
60
70
|
homepage: https://github.com/clear-code/fluent-vulnerability_checker
|
|
61
|
-
licenses:
|
|
71
|
+
licenses:
|
|
72
|
+
- Apache-2.0
|
|
62
73
|
metadata:
|
|
63
74
|
homepage_uri: https://github.com/clear-code/fluent-vulnerability_checker
|
|
64
75
|
source_code_uri: https://github.com/clear-code/fluent-vulnerability_checker
|
|
@@ -77,7 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
77
88
|
- !ruby/object:Gem::Version
|
|
78
89
|
version: '0'
|
|
79
90
|
requirements: []
|
|
80
|
-
rubygems_version:
|
|
91
|
+
rubygems_version: 3.6.9
|
|
81
92
|
specification_version: 4
|
|
82
93
|
summary: A security scanner and vulnerability checker for Fluentd configuration files.
|
|
83
94
|
test_files: []
|