Class: Fluent::VulnerabilityChecker

Inherits:
Object
  • Object
show all
Defined in:
lib/fluent/vulnerability_checker.rb

Defined Under Namespace

Classes: Rule

Constant Summary collapse

CHUNK_ID_PLACEHOLDER_PATTERN =
/\$\{chunk_id\}/
PLACEHOLDER_PATTERN =
/\$\{.*?\}/

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeVulnerabilityChecker

Returns a new instance of VulnerabilityChecker.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/fluent/vulnerability_checker.rb', line 38

def initialize
  @vulnerabilities = 0
  @rules = []

  # Fluentd: RCE via ${tag} in file in output/buffer/secondary/store sections
  @rules << Rule.new(['match', 'buffer', 'secondary', 'store'], 'file') { |element|
    # replace the safe ${chunk_id} with an empty string to clear it, and check if the remaining string contains ${...}
    element['path']&.gsub(CHUNK_ID_PLACEHOLDER_PATTERN, '')&.match?(PLACEHOLDER_PATTERN)
  }.register_report_message do |element|
    <<~"MSG"
      # Remote Code Execution (RCE) via Arbitrary File Write in Dynamic Placeholder
      * Severity:   Critical
      * CVSS Score: 10.0
      * Location:   <#{element.name}> - @type #{element['@type']}
      * State:      path = '#{element['path']}'
      * Description:
        * EN: If the ${tag} placeholder is used in the path parameter of the file output plugin, there is a risk that
              an attacker could write files to arbitrary paths, potentially leading to RCE.
        * JA: pathでプレースホルダーにtagを指定している場合、設定ファイルの書き方や実行権限が不適切だと、任意のパスに
              ファイルを書き込まれ、リモートからコード実行可能になる危険があります。
      * Workaround:
        * EN: If you cannot immediately update the package, apply mitigations such as restricting access,
              running with non-root privileges, modifying the configuration file, or removing untrusted tags.
        * JA: すぐにパッケージを更新できない場合、アクセスの制限、非root権限での実行、設定ファイルの修正、信頼できない
              tagを除去するなどの緩和策を適用してください。
    MSG
  end

  # Fluentd: RCE via ${tag} in secondary_file
  @rules << Rule.new('secondary', 'secondary_file') { |element|
    # replace the safe ${chunk_id} with an empty string to clear it, and check if the remaining string contains ${...}
    element['directory']&.gsub(CHUNK_ID_PLACEHOLDER_PATTERN, '')&.match?(PLACEHOLDER_PATTERN) ||
      element['basename']&.gsub(CHUNK_ID_PLACEHOLDER_PATTERN, '')&.match?(PLACEHOLDER_PATTERN)
  }.register_report_message do |element|
    state_msg = ['directory', 'basename'].map { |k| "#{k} = '#{element[k]}'" if element[k]&.match?(PLACEHOLDER_PATTERN) }.compact.join(', ')
    <<~"MSG"
      # Remote Code Execution (RCE) via Arbitrary File Write in Dynamic Placeholder
      * Severity:   Critical
      * CVSS Score: 10.0
      * Location:   <#{element.name}> - @type #{element['@type']}
      * State:      #{state_msg}
      * Description:
        * EN: If the ${tag} placeholder is used in the directory or basename parameter of the secondary_file plugin, 
              there is a risk that an attacker could write files to arbitrary paths, potentially leading to RCE.
        * JA: directoryまたはbasenameでプレースホルダーにtagを指定している場合、設定ファイルの書き方や実行権限が不適切だと、任意のパスに
              ファイルを書き込まれ、リモートからコード実行可能になる危険があります。
      * Workaround:
        * EN: If you cannot immediately update the package, apply mitigations such as restricting access,
              running with non-root privileges, modifying the configuration file, or removing untrusted tags.
        * JA: すぐにパッケージを更新できない場合、アクセスの制限、非root権限での実行、設定ファイルの修正、信頼できない
              tagを除去するなどの緩和策を適用してください。
    MSG
  end

  # Fluentd: Exposure of Sensitive Information
  @rules << Rule.new('source', 'monitor_agent') { |element| element['bind'].nil? || element['bind'] == '0.0.0.0' }.register_report_message do |element|
    <<~"MSG"
      # Exposure of Sensitive Information via Monitor Agent API
      * Severity:   High
      * CVSS Score: 7.5
      * Location:   <#{element.name}> - @type #{element['@type']}
      * State:      bind = '#{element['bind'] || 'default'}'.
                    (Note: In Fluentd 1.19.2 and earlier, the default value of bind is 0.0.0.0.)
      * Description:
        * EN: monitor_agent is exposed externally, allowing attackers to read Fluentd configuration details via its API.
        * JA: monitor_agentによって公開されているAPIを悪用して、Fluentdの設定内容を読み取られる危険性があります。
      * Workaround:
        * EN: If you cannot immediately update the package, apply mitigations such as restricting access,
              or allowing access only from localhost.
        * JA: すぐにパッケージを更新できない場合、アクセスの制限、ローカルホストからのみのアクセスを受け付けるなどの
              緩和策を適用してください。
    MSG
  end

  # Fluentd: DoS via Gzip Decompression in http input plugin
  @rules << Rule.new('source', 'http') { |element| true }.register_report_message do |element|
    <<~"MSG"
      # Denial of Service (DoS) via Gzip Decompression Bomb
      * Severity:   High
      * CVSS Score: 7.5
      * Location:   <#{element.name}> - @type #{element['@type']}
      * Description:
        * EN: Sending maliciously crafted gzip-compressed data to Fluentd can consume excessive memory during
              decompression, potentially causing it to crash.
        * JA: 細工したgzip圧縮データをFluentdへと送りつけることで、展開時に大量のメモリを消費させてFluentdをクラッシュ
              する危険性があります。
      * Workaround:
        * EN: If you cannot immediately update the package, apply mitigations such as restricting access, or enforcing
              size limits when decompressing content using a reverse proxy.
        * JA: すぐにパッケージを更新できない場合、アクセスの制限、リバースプロキシ等を用いたGZIP展開時のサイズ制限等の
              緩和策を適用してください。
    MSG
  end

  # Fluentd: DoS via Gzip Decompression in forward input plugin
  @rules << Rule.new('source', 'forward') { |element| true }.register_report_message do |element|
    <<~"MSG"
      # Denial of Service (DoS) via Gzip Decompression Bomb
      * Severity:   High
      * CVSS Score: 7.5
      * Location:   <#{element.name}> - @type #{element['@type']}
      * Description:
        * EN: Sending maliciously crafted gzip-compressed data to Fluentd can consume excessive memory during
              decompression, potentially causing it to crash.
        * JA: 細工したgzip圧縮データを受信することで、展開時に大量のメモリを消費してFluentdがクラッシュする危険性が
              あります。
      * Workaround:
        * EN: If you cannot immediately update the package, apply mitigations such as restricting access, or enforcing
              size limits when decompressing content using a reverse proxy.
        * JA: すぐにパッケージを更新できない場合、アクセスの制限、リバースプロキシ等を用いたGZIP展開時のサイズ制限等の
              緩和策を適用してください。
    MSG
  end

  # fluent-plugin-s3: DoS via Gzip Decompression
  @rules << Rule.new('source', 's3') { |element| true }.register_report_message do |element|
    <<~"MSG"
      # Denial of Service (DoS) via Gzip Decompression Bomb
      * Severity:   Low
      * CVSS Score: 2.7
      * Location:   <#{element.name}> - @type #{element['@type']}
      * Description:
        * EN: Sending maliciously crafted gzip-compressed data from S3 to Fluentd can consume excessive memory when
              processing requests, potentially causing it to crash.
        * JA: 細工したgzip圧縮データをS3から受信することで、展開時に大量のメモリを消費してFluentdがクラッシュする
              危険性があります。
      * Workaround:
        * EN: If you cannot immediately update the package, apply mitigations such as restricting access, or enforcing
              size limits when decompressing content using a reverse proxy.
        * JA: すぐにパッケージを更新できない場合、アクセスの制限、リバースプロキシ等を用いたGZIP展開時のサイズ制限等の
              緩和策を適用してください。
    MSG
  end

  # fluent-plugin-opentelemetry: DoS
  @rules << Rule.new('source', 'opentelemetry') { |element| true }.register_report_message do |element|
    <<~"MSG"
      # Denial of Service (DoS) via Gzip Decompression Bomb or Malicious HTTP Requests
      * Severity:   Moderate
      * CVSS Score: 5.3
      * Location:   <#{element.name}> - @type #{element['@type']}
      * Description:
        * EN: Sending maliciously crafted gzip-compressed data to Fluentd can consume excessive memory when processing
              requests, potentially causing it to crash.
        * JA: 細工したgzip圧縮データやHTTPリクエストを受信することで、リクエスト処理時に大量のメモリを消費してFluentdが
              クラッシュする危険性があります。
      * Workaround:
        * EN: If you cannot immediately update the package, apply mitigations such as restricting access, or enforcing
              size limits when processing requests using a reverse proxy.
        * JA: すぐにパッケージを更新できない場合、アクセスの制限、リバースプロキシ等を用いたリクエストサイズ制限等の
              緩和策を適用してください。
    MSG
  end

  # Fluentd: SSRF via ${endpoint} in http output plugin
  @rules << Rule.new('match', 'http') { |element| element['endpoint']&.match?(%r[https?://[^/]*\$\{]) }.register_report_message do |element|
    <<~"MSG"
      # Server-Side Request Forgery (SSRF) via Placeholder Expansion in out_http
      * Severity:   Moderate
      * CVSS Score: 5.8
      * Location:   <#{element.name}> - @type #{element['@type']}
      * Description:
        * EN: When out_http determines destination servers for data transmission based on tags, this vulnerability
              allows attackers to manipulate data transmission by sending crafted data, resulting in data being sent
              to servers other than the intended ones.
        * JA: out_httpでデータを別のサーバーに送る際の送信先をタグから決定している場合、細工したデータを送りつけられると、
              本来の意図とは異なるサーバーへとデータを送信してしまうことが可能な脆弱性です。
      * Workaround:
        * EN: If you cannot immediately update the package, apply mitigation measures such as:
              * not dynamically setting hostnames with placeholders
              * restricting access from untrusted networks
              * allowing only specific hosts
        * JA: すぐにパッケージを更新できない場合、プレースホルダーでホスト名を動的に設定しない、信頼できない
              ネットワークからのアクセスの制限、特定のホストのみ許可するなどの緩和策を適用してください。
    MSG
  end
end

Instance Attribute Details

#vulnerabilitiesObject (readonly)

for test



36
37
38
# File 'lib/fluent/vulnerability_checker.rb', line 36

def vulnerabilities
  @vulnerabilities
end

Instance Method Details

#validate(config_path) ⇒ Object



216
217
218
219
220
221
222
# File 'lib/fluent/vulnerability_checker.rb', line 216

def validate(config_path)
  parsed_config = Fluent::Config.build(config_path: config_path, type: :guess)

  parsed_config.elements.each do |element|
    check_element(element)
  end
end