---
title: 'Bypass del WAF tramite Confusione del Charset: La Storia di CVE-2026-21876 | DevSense'
description: "Scopri come la vulnerabilità CVE-2026-21876 consente agli aggressori di eludere l'OWASP ModSecurity Core Rule Set (CRS) utilizzando la confusione del charset multipart e la sovrascrittura di variabili nella regola 922110."
faq:
    - { question: 'Qual è la causa principale della vulnerabilità CVE-2026-21876?', answer: "La causa principale è un problema di sovrascrittura di variabili nella regola OWASP CRS 922110. Durante l'analisi di una richiesta multipart, il WAF scrive il Content-Type e il charset di ogni parte nella stessa variabile globale di transazione. Poiché la validazione rispetto alla whitelist avviene solo dopo l'elaborazione di tutte le parti, viene effettivamente verificato solo il Content-Type dell'ultima parte, lasciando quelle precedenti non controllate." }
    - { question: 'Perché la confusione del charset con IBM037 o UTF-7 porta a un bypass del WAF?', answer: 'Gli aggressori possono codificare i loro payload dannosi in charset non standard come IBM037 (una codifica basata su EBCDIC) o UTF-7. Il WAF non decodifica né ispeziona queste parti perché la validazione del loro Content-Type viene elusa a causa della sovrascrittura della variabile e le sue firme sono scritte per ASCII/UTF-8. Tuttavia, i server di backend (come Undertow o ASP.NET Core) supportano e decodificano automaticamente questi charset, ripristinando il payload in chiaro sul backend.' }
    - { question: "In che modo l'OWASP Core Rule Set risolve questa vulnerabilità?", answer: "La vulnerabilità è stata risolta riscrivendo il set di regole. Invece di sovrascrivere un'unica variabile, la nuova logica inizializza un contatore, memorizza il Content-Type di ciascuna parte multipart in una variabile separata con un nome univoco, e quindi itera su tutte le variabili registrate per garantire che ognuna sia validata rispetto alla whitelist." }
published: '2026-07-09'
---
# Bypass del WAF tramite Confusione del Charset: La Storia di CVE-2026-21876

I Web Application Firewall (WAF) sono componenti critici della moderna sicurezza web. Si posizionano tra i client e i server di backend, ispezionando il traffico in entrata per rilevare e bloccare payload dannosi come SQL Injection (SQLi) e Cross-Site Scripting (XSS). Tuttavia, un WAF è forte solo quanto lo sono le sue regole.

In questo articolo analizzeremo **CVE-2026-21876**, una vulnerabilità ad alta gravità nell'**OWASP ModSecurity Core Rule Set (CRS)**. Questo difetto consentiva agli aggressori di eludere completamente i controlli di sicurezza sfruttando un bug di sovrascrittura delle variabili in combinazione con la decodifica automatica dei set di caratteri (charset) sui backend delle applicazioni moderne.

---

## ModSecurity e l'OWASP Core Rule Set (CRS)

**ModSecurity** è un motore WAF open source basato su firme ampiamente utilizzato che si integra con server web popolari come Nginx, Apache e IIS. Essendo ModSecurity solo un motore, si affida a regole per rilevare gli attacchi.

L'**OWASP ModSecurity Core Rule Set (CRS)** è il set di regole standard del settore per il rilevamento di attacchi generici. Viene distribuito su larga scala dai principali provider cloud e reti CDN, inclusi Azure WAF, configurazioni di AWS WAF, Cloudflare, Fastly e Google Cloud Armor. Con milioni di installazioni attive a livello globale, una vulnerabilità nel set di regole CRS ha un impatto a cascata, esponendo un numero enorme di infrastrutture web.

---

## Le Dinamiche di CVE-2026-21876

La vulnerabilità risiede nella regola **922110**, progettata originariamente per imporre una validazione rigorosa delle intestazioni `Content-Type` delle singole parti di una richiesta multipart (`multipart/form-data`). In particolare, essa garantisce che ogni parte di una richiesta multipart utilizzi un tipo di contenuto e un charset approvati (in whitelist).

### Il Bug della Sovrascrittura delle Variabili

Quando un client invia una richiesta multipart, ModSecurity esegue un ciclo su ogni parte del payload. Durante questo processo, la regola 922110 estrae il `Content-Type` della parte corrente e lo memorizza in una variabile a livello di transazione (ad esempio, `TX:content_type`).

Il bug è semplice ma critico:
1. **Il Ciclo:** ModSecurity itera su tutte le parti, estraendo e scrivendo il Content-Type della parte corrente nella stessa variabile, sovrascrivendo il valore precedente.
2. **La Validazione:** Il controllo di conformità con la whitelist viene eseguito solo **dopo** che il ciclo è terminato, e non per ciascuna parte all'interno del ciclo.
3. **La Conseguenza:** Solo il Content-Type dell'**ultima parte** della richiesta multipart viene validato rispetto alla whitelist. Qualsiasi parte precedente viene ignorata dalla regola 922110.

Rappresentata in uno pseudocodice simile a Python, la logica vulnerabile appare così:

```python
# Logica Vulnerabile (CVE-2026-21876)
content_type_var = None

# Estrazione dei content type in un ciclo
for part in request.multipart_parts:
    content_type_var = part.headers.get("Content-Type")  # Sovrascrive la variabile globale

# La validazione viene eseguita fuori dal ciclo
if not is_whitelisted(content_type_var):
    block_request()
```

Aggiungendo un parametro fittizio (dummy) con un Content-Type approvato alla fine della richiesta, un aggressore può sovrascrivere la variabile globale con un valore "sicuro", eludendo completamente il controllo.

---

## Il Vettore di Attacco: Confusione del Charset

Per sfruttare questo bug, un aggressore combina il difetto di sovrascrittura della variabile con una tecnica chiamata **Confusione del Charset**.

Le regole di firma dei WAF (come quelle che cercano parole chiave come `UNION SELECT` o `<script>`) sono progettate per analizzare i payload codificati in charset standard come UTF-8 o ASCII. Se un aggressore invia un payload codificato in un charset non standard, il WAF non rileverà le firme perché la sequenza di byte grezzi non corrisponderà alle parole chiave dannose.

Normalmente, la regola 922110 bloccherebbe qualsiasi richiesta con una codifica non consentita. Tuttavia, a causa del bug di sovrascrittura, il WAF consente codifiche non autorizzate nelle prime parti purché l'ultima parte sia legittima.

### Costruzione della Richiesta di Attacco

L'aggressore struttura una richiesta `multipart/form-data` con due parti:
1. **Parte 1 (Payload dannoso):** Utilizza un charset non standard come `IBM037` (una codifica basata su EBCDIC). Il WAF salta il controllo del Content-Type (a causa della sovrascrittura) e non analizza il payload poiché è codificato in EBCDIC.
2. **Parte 2 (Parametro fittizio):** Utilizza un charset standard come `utf-8`. Questo sovrascrive la variabile di tracciamento del WAF con un valore consentito, facendo passare l'intera richiesta.

### Esempio di Richiesta HTTP Grezza per il Bypass

```http
POST /vulnerable-endpoint HTTP/1.1
Host: target-app.com
Content-Length: 432
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarySafeAndBypass

------WebKitFormBoundarySafeAndBypass
Content-Disposition: form-data; name="id"
Content-Type: text/plain; charset=ibm037

K@ñ%ÈÊÈÀñKñ
------WebKitFormBoundarySafeAndBypass
Content-Disposition: form-data; name="legitimate_param"
Content-Type: text/plain; charset=utf-8

safe-value
------WebKitFormBoundarySafeAndBypass--
```

> [!NOTE]
> Nell'esempio sopra, il valore `K@ñ%ÈÊÈÀñKñ` rappresenta il payload SQL injection `' OR 1=1 --` codificato in IBM037 (EBCDIC). Per il WAF, questi byte appaiono come caratteri casuali senza senso e non corrispondono a nessuna firma di attacco.

---

## Comportamento di Decodifica del Backend

Il bypass di un WAF è pericoloso solo se l'applicazione di backend elabora effettivamente il payload dannoso.

Molti server e framework di backend moderni analizzano automaticamente le richieste `multipart/form-data`. Quando incontrano una parte con un parametro `charset` specifico nella sua intestazione `Content-Type`, decodificano automaticamente i byte di quella parte utilizzando la codifica indicata.

Alcuni backend noti che mostrano questo comportamento per impostazione predefinita sono:
- **Spring Boot su Undertow:** Undertow estrae e decodifica automaticamente i valori multipart in base al charset specificato nel Content-Type di ciascuna parte.
- **ASP.NET Core:** Il parser multipart integrato rispetta il parametro charset, convertendo automaticamente le stringhe codificate in IBM037 o UTF-7 in stringhe standard UTF-8/Unicode prima che queste raggiungano i controller dell'applicazione.

Quando la richiesta raggiunge il backend:
1. Il backend analizza la Parte 1, rileva `charset=ibm037` e decodifica i byte EBCDIC nel testo in chiaro originario: `' OR 1=1 --`.
2. L'applicazione esegue il parametro, attivando la SQL injection o la vulnerabilità XSS.
3. Il WAF rimane del tutto ignaro dell'attacco poiché ha validato solo il `charset=utf-8` della Parte 2 e ha visto solo dati EBCDIC incomprensibili nella Parte 1.

---

## Mitigazione e Dettagli della Patch del Core Rule Set

Dopo la divulgazione della vulnerabilità, il team di OWASP CRS ha rilasciato una patch che ha ristrutturato il modo in che la regola 922110 convalida le richieste multipart. Invece di una singola variabile globale, il processo è stato diviso in tre fasi distinte:

1. **Inizializzazione del Contatore:** Inizializza un contatore univoco per tracciare le parti multipart.
2. **Memorizzazione Separata:** Estrae e scrive il Content-Type e il charset di *ciascuna* parte in una variabile distinta associata al suo indice (ad esempio, `TX:multipart_content_type_0`, `TX:multipart_content_type_1`, ecc.).
3. **Validazione Completa:** Esegue un ciclo su tutte le variabili registrate e convalida ciascuna individualmente rispetto alla whitelist. Se anche una sola parte fallisce il controllo, il WAF blocca la richiesta.

La logica corretta si comporta come il seguente pseudocodice:

```python
# Logica Corretta
content_types = []

# Raccoglie tutti i Content-Type in una lista
for part in request.multipart_parts:
    content_types.append(part.headers.get("Content-Type"))

# Valida ciascuna parte
for ct in content_types:
    if not is_whitelisted(ct):
        block_request()
        break
```

Questa patch elimina del tutto la possibilità di sovrascrittura delle variabili, garantendo che gli attacchi basati sulla confusione del charset vengano rilevati e bloccati a livello di WAF.