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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9b7b016592779771f517e36e82a0d21f7834bd39a856808765bbda9e5a3e090b
4
- data.tar.gz: 104bfc90898a715a10723349b8049b7ac57e9221370d7d67258666d2b11f3b69
3
+ metadata.gz: 96e4204851a5608ae47199c15728b16f99f3b4cf49bbe6c5ea15610a63f84993
4
+ data.tar.gz: 6847a3517038edaf8490bbc09acd32e99c164c610eac5629fcebd8fb6ebad254
5
5
  SHA512:
6
- metadata.gz: f657e1541199274621a99060deae71440be81f8011d02519010eb8a3276956e26b85bf63a25458f0668f7f4f507a5b5059c3dab9ee78d043676c9d5e25b2c7f5
7
- data.tar.gz: 14d93635f7c948b18826be70c30a6955a9ed6be8f68e11e7b77e58065ce055b92ba67032f228695c13e4bf4d6d4d525321202d7cc83a9cb28577ebce0388f287
6
+ metadata.gz: 2e30a73a70ccc10fd8f22dcaabdf51180dc3280bba3c7490761da659bc4b035b61994682542986bd387d163d2640fd8a4884c7a48efc9ab3d35e2280c75d693f
7
+ data.tar.gz: 072174336f375fcae7209fe7e71daf436fc94563c05c65d81308fe89365c52570be6e39d33d4eca969c1bdd09faf111aae2712c755adc578f93bc42921823fe3
@@ -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
@@ -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@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
29
- - uses: ruby/setup-ruby@6ca151fd1bfcfd6fe0c4eb6837eb0584d0134a0c # v1.290.0
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@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
29
- - uses: ruby/setup-ruby@6ca151fd1bfcfd6fe0c4eb6837eb0584d0134a0c # v1.290.0
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
- def initialize(plugin_categories, plugin_name = nil, &condition_proc)
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 register_report_message(&report_proc)
19
- @report_proc = report_proc
24
+ def register_state_message(&state_proc)
25
+ @state_proc = state_proc
20
26
  self
21
27
  end
22
28
 
23
- def report(element)
24
- @report_proc&.call(element)
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
- }.register_report_message do |element|
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
- }.register_report_message do |element|
72
- state_msg = ['directory', 'basename'].map { |k| "#{k} = '#{element[k]}'" if element[k]&.match?(PLACEHOLDER_PATTERN) }.compact.join(', ')
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| element['bind'].nil? || element['bind'] == '0.0.0.0' }.register_report_message do |element|
94
- <<~"MSG"
95
- # Exposure of Sensitive Information via Monitor Agent API
96
- * Severity: High
97
- * CVSS Score: 7.5
98
- * Location: <#{element.name}> - @type #{element['@type']}
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 }.register_report_message do |element|
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 }.register_report_message do |element|
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 }.register_report_message do |element|
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 }.register_report_message do |element|
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| element['endpoint']&.match?(%r[https?://[^/]*\$\{]) }.register_report_message do |element|
194
- <<~"MSG"
195
- # Server-Side Request Forgery (SSRF) via Placeholder Expansion in out_http
196
- * Severity: Moderate
197
- * CVSS Score: 5.8
198
- * Location: <#{element.name}> - @type #{element['@type']}
199
- * Description:
200
- * EN: When out_http determines destination servers for data transmission based on tags, this vulnerability
201
- allows attackers to manipulate data transmission by sending crafted data, resulting in data being sent
202
- to servers other than the intended ones.
203
- * JA: out_httpでデータを別のサーバーに送る際の送信先をタグから決定している場合、細工したデータを送りつけられると、
204
- 本来の意図とは異なるサーバーへとデータを送信してしまうことが可能な脆弱性です。
205
- * Workaround:
206
- * EN: If you cannot immediately update the package, apply mitigation measures such as:
207
- * not dynamically setting hostnames with placeholders
208
- * restricting access from untrusted networks
209
- * allowing only specific hosts
210
- * JA: すぐにパッケージを更新できない場合、プレースホルダーでホスト名を動的に設定しない、信頼できない
211
- ネットワークからのアクセスの制限、特定のホストのみ許可するなどの緩和策を適用してください。
212
- MSG
213
- end
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 rule.report(element)
184
+ puts @report.render(rule, element)
231
185
  puts "=" * 115
232
186
  end
233
187
  end
@@ -0,0 +1,7 @@
1
+ <match>
2
+ @type file
3
+ <buffer tag>
4
+ @type file
5
+ compress gzip
6
+ </buffer>
7
+ </match>
@@ -0,0 +1,7 @@
1
+ <match>
2
+ @type file
3
+ <buffer tag>
4
+ @type file
5
+ compress gzip
6
+ </buffer>
7
+ </match>
@@ -0,0 +1,4 @@
1
+ <match>
2
+ @type file
3
+ compress gzip
4
+ </match>
@@ -0,0 +1,4 @@
1
+ <match>
2
+ @type file
3
+ compress zstd
4
+ </match>
@@ -0,0 +1,7 @@
1
+ <match>
2
+ @type file
3
+ <buffer tag>
4
+ @type file_single
5
+ compress gzip
6
+ </buffer>
7
+ </match>
@@ -0,0 +1,7 @@
1
+ <match>
2
+ @type file
3
+ <buffer tag>
4
+ @type file_single
5
+ compress gzip
6
+ </buffer>
7
+ </match>
@@ -0,0 +1,4 @@
1
+ <source>
2
+ @type http
3
+ message_length_limit 4096
4
+ </source>
@@ -0,0 +1,3 @@
1
+ <source>
2
+ @type syslog
3
+ </source>
@@ -0,0 +1,5 @@
1
+ <source>
2
+ @type syslog
3
+ <transport tcp>
4
+ </transport>
5
+ </source>
@@ -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.1
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: 4.0.15
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: []