v2: t:utf8toUnicode drops the last hex digit of code points above U+FFFF (regression since 2.9.9)
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 78/100
Direzione di ricerca
Il bug si trova in utf8_unicode_inplace_ex() in apache2/msc_util.c, nel ramo che chiama sprintf(data, "%%u%04x", d) e poi esegue data += 6. Inizia da lì: l'avanzamento del puntatore dovrebbe seguire la lunghezza restituita da sprintf(), e bytes_left dovrebbe tenere traccia dell'input rimanente. Aggiungi un caso di sequenza a quattro byte in tests/tfn/utf8toUnicode.t. È fatto quando U+1F600 viene trasformato in %u1f600 e i casi BMP esistenti continuano a passare.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
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.
- Lingua principale
- C++
- Stelle
- 9.8k
- Fork
- 1.8k
- Merge medio
- 1g 1h
- PR unite (30g)
- 13
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Nessuna guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di owasp-modsecurity/ModSecurity
-
IIS: ReadFileChunk allocates only 1 byte but reads m_dwPageSize (latent overflow)Forse già presa Una pull request collegata a questa issue è aperta o già unita. Aperta2.x bug Platform - IIS pr available windows
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 90/100
owasp-modsecurity/ModSecurity#3623 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
IIS: Host header fallback is dead code (r->hostname == NULL can never be true)Forse già presa Una pull request collegata a questa issue è aperta o già unita. Aperta2.x bug Platform - IIS pr available windows
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
owasp-modsecurity/ModSecurity#3621 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
IIS: Content-Length header corrupted/truncated for large responses (wrong printf format + off-by-one buffer size)Forse già presa Una pull request collegata a questa issue è aperta o già unita. Aperta2.x bug Platform - IIS pr available windows
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
owasp-modsecurity/ModSecurity#3619 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
2.x bug Platform - IIS pr available windows
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
owasp-modsecurity/ModSecurity#3612 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Multipart: data after the final boundary in a later chunk sets MULTIPART_DATA_BEFORE instead of MULTIPART_DATA_AFTERForse già presa @airween l’ha presa 2 giorni fa. Aperta2.x 3.x bug
owasp-modsecurity/ModSecurity#3695 · 1 commento · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di owasp-modsecurity/ModSecurity
Issue simili
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
I maintainer di solito rispondono entro 1 giorno
-
Mac mini M6 (16 GB): Q2_0 streaming works - measured 11.7->27.2 tok/s + arena fix for sub-32 GB MacsAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
I maintainer di solito rispondono entro 1 giorno
-
champion good first issue remake source/qq
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
metasequoiaime/msime-windows#1025 ·
I maintainer di solito rispondono entro 1 giorno
-
backlog bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
EchoTools/nevr-runtime#653 ·
I maintainer di solito rispondono entro 1 giorno
-
`--fail-require-skip` never fires: run_tests.py searches stdout, but the unittest binary writes the skip summary to stderrForse già presa Una pull request collegata a questa issue è aperta o già unita. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
I maintainer di solito rispondono entro 1 giorno