
CVE-2026-77818 - Yordam Kütüphane Otomasyon Sistemi - Riflessione di HTML injection in tre punti distinti, intercettazione dell'azione del modulo e furto di credenziali (CWE-79)
CVE-2026-77818 · CVSS 3.1 6.1 (Media) · Presidenza per la Sicurezza Informatica · Pubblicazione 2026-09-04 · TR-26-1011
Stato: Le vulnerabilità sono state risolte nella versione v22.2. Le installazioni interessate devono essere aggiornate alla v22.2 o successiva.
Il Sistema di Automazione Bibliotecaria Yordam è un software commerciale di automazione bibliotecaria e catalogo online (OPAC) ampiamente utilizzato nelle biblioteche universitarie, pubbliche e istituzionali in Turchia. L'installazione è on-premise; ogni cliente esegue una copia separata presso la propria istituzione.
Nella versione v22.1 del prodotto sono presenti iniezioni HTML riflesse in tre punti distinti e indipendenti. Nessuno dei tre richiede autenticazione e tutti e tre vengono attivati con un singolo collegamento.
| # | Punto | Causa principale |
|---|---|---|
| 1 | Pagina di accesso, parametro devam | Nessun escaping applicato |
| 2 | Attributo value del campo modulo nascosto | Doppio URL decode dopo l'escaping |
| 3 | Attributo name del campo modulo nascosto | L'escaping è applicato solo al valore, non al nome |
Poiché i tre punti riguardano la stessa versione dello stesso prodotto e la stessa classe di vulnerabilità, sono stati raggruppati in un'unica segnalazione e pubblicati sotto un unico identificativo CVE. In termini di impatto, il punto 1 è il più grave.
devamQuesto è il più critico. Il punto di iniezione è direttamente il tag HTML del modulo di autenticazione stesso.
Il parametro devam trasporta l'indirizzo a cui l'utente tornerà dopo l'accesso e arriva codificato in hex — il valore 2f796f7264616d2f significa /yordam/. L'applicazione decodifica questo valore dall'hex e lo scrive nel tag di apertura del modulo di accesso. Non c'è alcuna operazione di escaping nel mezzo:
<form class='girisForm collapse show ikiAdimliGiris' method='post'
action='inc/islem.fm.inc.php'
data-url='<INPUT UTENTE DECODIFICATO DA HEX>'
autocomplete="off">
Nell'output, i caratteri <, > e le virgolette compaiono grezzi. L'unica cosa che contiene il payload è il fatto che l'attributo data-url è racchiuso tra virgolette singole. Quando si inserisce una virgoletta singola nell'input, anche quella termina: l'attributo si chiude, il tag <form> si chiude e l'HTML scritto dall'attaccante prende il posto del modulo di autenticazione della pagina.
L'azione del modulo viene dirottata. Qui non viene disegnato un modulo falso — il modulo dell'applicazione viene lasciato vuoto e chiuso, e subito dopo viene aperto un nuovo <form> con le stesse classi CSS. Poiché i campi per nome utente, password e codice di verifica nella pagina sono tutti HTML originale dell'applicazione, rimangono all'interno di questo nuovo modulo. L'utente vede il modulo reale, compila il modulo reale; le informazioni inserite vengono inviate al server dell'attaccante. Non c'è alcuna differenza visivamente distinguibile.
Il punto critico: l'iniezione non avviene su una pagina qualsiasi, ma sulla pagina in cui ci si aspetta già che l'utente inserisca la propria password. In un'iniezione riflessa ordinaria, l'attaccante deve convincere la vittima; qui è l'interfaccia stessa dell'applicazione a fare il lavoro di convincimento.
value del Campo Modulo Nascosto — Doppio URL DecodeNella pagina di ricerca, i valori dei parametri GET vengono scritti in campi modulo nascosti. A questo punto viene applicato l'escaping — ma nell'ordine sbagliato.
Lo stesso valore q viene utilizzato in tre contesti diversi all'interno della stessa risposta, ciascuno con una diversa profondità di decodifica:
| Contesto | Decodifica | Stato |
|---|---|---|
Stringa JS nel blocco <script> | 1 volta | Sicuro |
Casella di ricerca principale <input value="…"> | 1 volta | Sicuro |
Campi modulo nascosti <input type='hidden' value="…"> | 2 volte | Vulnerabile |
La sequenza delle operazioni è la seguente:
Input del client : %2522
↓ analisi $_GET
Variabile PHP : %22
↓ filtro di ingresso → non vede contenuto dannoso, nessuna virgoletta presente
↓ htmlspecialchars → nessun carattere da escapare, nessuna modifica
↓ urldecode → %22 viene decodificato
Stampato sulla pagina : " ← virgoletta grezza, uscita dall'attributo
Il filtro di ingresso e l'escaping operano sul primo livello di decodifica, mentre l'output viene alimentato dal secondo livello. Confrontando le versioni a codifica singola e doppia dello stesso payload, la differenza è chiaramente visibile:
| Inviato | Risposta | Output del campo nascosto |
|---|---|---|
q=foo%22… (codifica singola) | 302 Found | value="foo"…" — il filtro intercetta |
q=foo%2522… (doppia codifica) | 200 OK | value="foo"><…>" — HTML grezzo |
La vulnerabilità non è specifica del parametro q. Il blocco che genera i campi nascosti itera su tutti i parametri GET della richiesta; è stata verificata anche su tip e alan.
name del Campo Modulo Nascosto — Iniezione nel Nome del ParametroLo stesso blocco genera la seguente struttura per ogni parametro GET:
<input type='hidden' name="<NOME PARAMETRO>" value="<VALORE PARAMETRO>"/>
L'escaping viene applicato solo al lato value. Non viene mai applicato al lato name. A questo punto non serve nemmeno la doppia codifica — la codifica singola è sufficiente, perché non c'è alcun escaping da aggirare.
Un nome di parametro inventato viene scritto direttamente e grezzo nell'attributo name, consentendo l'uscita dall'attributo. Poiché il nome del parametro è sotto il controllo dell'attaccante, non è necessario che sia un parametro riconosciuto dall'applicazione.
I punti 2 e 3 di queste tre vulnerabilità derivano dallo stesso blocco di codice, e questo blocco si ripete in sei moduli diversi: dilForm, adetForm, siralaForm, tkForm, ekForm, tmForm. In una singola richiesta, l'iniezione avviene quindi sei volte.
La natura dinamica del blocco è stata verificata confrontando l'output di due richieste:
Richiesta A: ?p=1&dil=0&alan=&tip=basit&gorunum=liste&q=…
Output A: name="p" · name="alan" · name="tip" · name="gorunum" · name="q"
Richiesta B: ?p=2&dil=0&devam=…
Output B: name="p" · name="devam"
I campi generati non derivano da un elenco fisso, ma direttamente dai parametri della richiesta. Pertanto, sia il contenuto scritto nell'attributo name che quello nell'attributo value sono sotto il controllo dell'attaccante.
L'unica cosa di cui l'attaccante ha bisogno è un collegamento che la vittima apra. Non è necessario che acceda né che abbia un account.
action del modulo di accesso viene reindirizzata all'attaccante. Verificato.Poiché la piattaforma interessata contiene le credenziali e i dati personali degli utenti della biblioteca, attraverso gli account compromessi è possibile accedere ai registri degli iscritti.
L'applicazione utilizza CSP e script-src e object-src sono basati su nonce; quindi il classico XSS basato su script non funziona su queste pagine. A prima vista, ciò sembrerebbe ridurre il risultato al livello di "sola manomissione dei contenuti".