v2: t:utf8toUnicode drops the last hex digit of code points above U+FFFF (regression since 2.9.9)
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 78/100
調査の方向性
バグは apache2/msc_util.c の utf8_unicode_inplace_ex() にあります。sprintf(data, "%%u%04x", d) を呼び出してから data += 6 を実行する分岐です。まずそこから始めてください。ポインタの前進は sprintf() が返す長さに従うべきで、bytes_left は残りの入力を追跡すべきです。tests/tfn/utf8toUnicode.t に4バイトシーケンスのケースを追加してください。U+1F600 が %u1f600 に変換され、既存の BMP のケースが引き続き通れば完了です。
索引モデルが issue の本文から書いたものです。
説明
Summary
In ModSecurity v2 (2.9.9 through 2.9.15, and current v2/master), t:utf8toUnicode emits only four of the five hex digits for any code point above U+FFFF (supplementary planes: emoji, CJK extensions, mathematical alphanumerics, ...). The last digit is overwritten by whatever the function writes next, or by the terminating NUL when the character is the last one in the value.
Related to #1211 (ambiguous output of this transformation), but this is a separate, newer defect: #1211 describes the 4-digit vs. 6-digit ambiguity by design; this issue is a plain truncation introduced by the refactor in #3284 (commit 907d61ad, fix for #3129), first released in 2.9.9. libModSecurity v3 is not affected (its port still writes the digits one by one), although it shares the #1211 ambiguity.
Reproduction
Output of utf8_unicode_inplace_ex() from apache2/msc_util.c at v2.9.15, compiled standalone:
| Input | Output | Expected |
|---|---|---|
U+1F600 (f0 9f 98 80) |
%u1f60 |
%u1f600 |
U+1F600 followed by A |
%u1f60A |
%u1f600A |
a U+1F600 U+00E5 |
a%u1f60%u00e5 |
a%u1f600%u00e5 |
U+20AC (e2 82 ac) |
%u20ac |
%u20ac (BMP characters are fine) |
Cause
if (unicode_len > 0) {
i += unicode_len;
sprintf(data, "%%u%04x", d);
data += 6; /* "%u" + 4 digits, but d > 0xFFFF prints 5 digits */
*changed = 1;
}
Before 907d61ad the four-byte branch wrote the digits individually, so 5-digit code points were preserved.
Two adjacent problems in the same function
bytes_leftis initialised toinput_lenand never decremented, so the "check we have at least N bytes" guards compare against the total length instead of the remaining length. A truncated multibyte sequence at the end of the value reads pastinput_len. In practice the read stops at the NUL that terminates every v2 variable value, so it is bounded to one byte, but the guard is wrong.- The range check only rejects lead bytes
>= 0xF5; an0xF4lead byte with a second byte>= 0x90encodes U+110000 and above, which is outside Unicode, and is currently accepted.
Impact
Correctness only, as far as I can tell: the output buffer is sized at ten bytes per input byte and a 4-byte sequence writes at most eight, so nothing is written outside the allocation, and the transformed string is always a superset of the ASCII input, so I could not construct a rule bypass with it. Rules that match %uXXXXX sequences for supplementary-plane characters do not work, and the transformed value is wrong in the audit log.
Proposed fix
Advance data by the value sprintf() returns instead of a constant 6, decrement bytes_left (or compare against input_len - i), reject code points above U+10FFFF, and add a four-byte sequence to tests/tfn/utf8toUnicode.t, which currently has none. PR to follow.
- 主要言語
- C++
- スター
- 9.8k
- フォーク
- 1.8k
- 平均マージ
- 1日 1時間
- マージ済み PR(30日)
- 13
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドなし
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
owasp-modsecurity/ModSecurity のほかの issue
-
IIS: ReadFileChunk allocates only 1 byte but reads m_dwPageSize (latent overflow)対応中かも このイシューにリンクされたプルリクエストがオープン中、またはマージ済みです。 オープン2.x bug Platform - IIS pr available windows
難易度 1/5 1時間未満 初心者へのやさしさ 90/100
owasp-modsecurity/ModSecurity#3623 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信
-
IIS: Host header fallback is dead code (r->hostname == NULL can never be true)対応中かも このイシューにリンクされたプルリクエストがオープン中、またはマージ済みです。 オープン2.x bug Platform - IIS pr available windows
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
owasp-modsecurity/ModSecurity#3621 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信
-
IIS: Content-Length header corrupted/truncated for large responses (wrong printf format + off-by-one buffer size)対応中かも このイシューにリンクされたプルリクエストがオープン中、またはマージ済みです。 オープン2.x bug Platform - IIS pr available windows
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
owasp-modsecurity/ModSecurity#3619 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信
-
2.x bug Platform - IIS pr available windows
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
owasp-modsecurity/ModSecurity#3612 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信
-
Multipart: data after the final boundary in a later chunk sets MULTIPART_DATA_BEFORE instead of MULTIPART_DATA_AFTER対応中かも @airween が 2 日前に担当しました。 オープン2.x 3.x bug
owasp-modsecurity/ModSecurity#3695 · コメント 1 件 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
owasp-modsecurity/ModSecurity の issue をすべて見る
似ている issue
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
メンテナーはふだん 1 日以内に返信
-
Mac mini M6 (16 GB): Q2_0 streaming works - measured 11.7->27.2 tok/s + arena fix for sub-32 GB Macsオープン
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
メンテナーはふだん 1 日以内に返信
-
champion good first issue remake source/qq
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
metasequoiaime/msime-windows#1025 ·
メンテナーはふだん 1 日以内に返信
-
backlog bug
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
EchoTools/nevr-runtime#653 ·
メンテナーはふだん 1 日以内に返信
-
`--fail-require-skip` never fires: run_tests.py searches stdout, but the unittest binary writes the skip summary to stderr対応中かも このイシューにリンクされたプルリクエストがオープン中、またはマージ済みです。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 1 日以内に返信