CVE-2026-110910
Açıklama
### Özet `allowEmptyArrays: true` ile kullanılan `qs.stringify`, anahtarlar varsayılan olarak kodlansa bile boş bir dizinin anahtarını kodlamadan yazar. Bu nedenle `&` (veya yapılandırılmış `delimiter`), `=` veya `#` içeren bir anahtar, veri yerine sorgu dizesi sözdizimine dönüşür; böylece çağırıcı tarafından sağlanan bir anahtar adı, serileştirilmiş sorgu dizesine parametreler ekleyebilir veya dizeyi erken kesebilir. ### Detaylar `lib/stringify.js` dosyasında, `allowEmptyArrays` dalı, diğer tüm anahtarları `encoder` ve `formatter` üzerinden geçiren koddan önce `adjustedPrefix + '[]'` değerini erkenden döndürür. Bu nedenle `{ "x&k=v": ["1"] }` ifadesi `x%26k%3Dv%5B0%5D=1` olarak serileştirilirken, `{ "x&k=v": [] }` ifadesi `x&k=v[]` olarak serileştirilir. Erken döndürme işlemi her derinlikte (`{ "a": { "b&k=v": [] } }` sonucu `a[b&k=v][]` verir), her `arrayFormat` altında, `allowDots` ile ve o anahtar için hiçbir zaman çağrılmayan özel bir `encoder` ile geçerlidir. `encode: false` veya `encodeValuesOnly: true` durumlarında anahtarlar her yolda kasıtlı olarak kodlanmadan bırakılır; bu yapılandırmalar etkilenmez. #### PoC ```js var qs = require("qs"); var query = qs.stringify({ q: "hi", "x&apiKey=evil&y": [] }, { allowEmptyArrays: true }); // "q=hi&x&apiKey=evil&y[]" qs.parse(query); // { q: "hi", x: "", apiKey: "evil", y: [""] } qs.stringify({ "x#": [], z: "1" }, { allowEmptyArrays: true }); // "x#[]&z=1": bir URL'de, "#" işaretinden sonraki her şey fragman olur ``` #### Çözüm `main` üzerinde 234d505 ile uygulanan ve v6.17.0 olarak yayınlanan; ayrıca v6.16.2, v6.15.4, v6.14.3, v6.13.4 ve v6.12.6 sürümlerine geri port edilen düzeltme ile: boş bir dizinin anahtarı, herhangi bir diğer değerin anahtarıyla tıpkı aynı şekilde `encoder` ve `formatter` üzerinden geçer, böylece `{ "x&apiKey=evil&y": [] }` artık `x%26apiKey%3Devil%26y[]` olarak serileştirilir. Kodlama gerektirmeyen anahtarlar, diğer tüm yollarla eşleşen iki istisna dışında eskisi gibi serileştirilir: iç içe geçmiş bir anahtarın köşeli parantezleri artık kodlanır (`a[b][]` ifadesi, `qs.parse` tarafından aynı şekilde okunan `a%5Bb%5D[]` haline gelir) ve `encodeDotInKeys` ile anahtardaki bir nokta, `%2E` yerine `%252E` olur (`decodeDotInKeys` daha önce bunu yanlışlıkla iç içe geçme olarak okuyordu). ### Etkilenen Sürümler - `>=6.12.0 <6.12.6`, v6.12.6 sürümünde düzeltildi - `>=6.13.0 <6.13.4`, v6.13.4 sürümünde düzeltildi - `>=6.14.0 <6.14.3`, v6.14.3 sürümünde düzeltildi - `>=6.15.0 <6.15.4`, v6.15.4 sürümünde düzeltildi - `>=6.16.0 <6.16.2`, v6.16.2 sürümünde düzeltildi v6.17.0 ve sonrası etkilenmemektedir. `allowEmptyArrays`, f22b2bc ile tanıtılmış ve ilk kez v6.12.0 sürümünde bu erken döndürme işlemiyle sunulmuştur. Daha önceki sürümlerde `allowEmptyArrays` seçeneği yoktur ve etkilenmezler. ### Etki Anahtar adları güvenilmeyen girdilerden gelen bir nesneyi `allowEmptyArrays: true` ile `qs.stringify` fonksiyonuna aktaran bir uygulama (örneğin, ayrıştırılmış bir JSON gövdesini veya kullanıcı tarafından seçilen alanları üst servisere yönlendirmek için), sonuçtaki sorgu dizesine parametrelerin enjekte edilmesine neden olabilir. Enjekte edilen parametreler nesnenin anahtarları değildir, dolayısıyla nesne üzerindeki bir anahtarı silmek veya üzerine yazmak (kullanıcının alanlarını kopyaladıktan sonra güvenilir bir `apiKey` ayarlamak gibi) bunları kaldırmaz; saldırganın değerinin mi yoksa uygulamanın değerinin mi baskın geleceği, alıcı tarafın yinelenen bir parametreyi nasıl işlediğine bağlıdır. Böyle bir anahtardaki `#` karakteri, sonuç bir URL'ye yerleştirildiğinde sorgu dizesini erken sonlandırır. `allowEmptyArrays` varsayılan olarak kapalıdır ve yalnızca değeri (herhangi bir `filter` işleminden sonra) boş bir dizi olan anahtarlar etkilenir.
Nasıl düzeltilir
- ljharb qs6.12.6, 6.13.4, 6.14.3, 6.15.4, 6.16.2 ya da sonraki bir sürüm
- github.com/ljharb/qs/commit/234d5051f5071efaa025a7ca9e4d34a56a460a1b
- github.com/ljharb/qs/commit/6b8bf1a53d7b0c5e7e434eaae8e2c0cffd5c2492
- github.com/ljharb/qs/commit/033526fc82f2e80a3d896df2bce9137e34cb5dc5
- github.com/ljharb/qs/commit/f9dd4830cb922363822cdfdca2cceb3ed9792224
- github.com/ljharb/qs/commit/ad445aa23e4c3a97394c3b9a5f9d7a7159eb1f17
- github.com/ljharb/qs/commit/5d3b1b9ec6afd0cfc760c8e12862873789a32fc8
- github.com/ljharb/qs/pull/561
Etkilenen ürünler
| Ürün | Etkilenen sürümler | Düzeltildiği sürüm |
|---|---|---|
| ljharb qs | 6.12.0 ≤ v < 6.12.6, 6.13.0 ≤ v < 6.13.4, 6.14.0 ≤ v < 6.14.3, 6.15.0 ≤ v < 6.15.4, 6.16.0 ≤ v < 6.16.2 | 6.12.6, 6.13.4, 6.14.3, 6.15.4, 6.16.2 |
Sürümünüzü kontrol edin
Ürünü seçin ve kullandığınız sürümü yazın; sürümün etkilenen aralıkta olup olmadığını görün.
Attack Surface Management
Alan adlarınıza bağlı varlıkları, bu varlıklarda çalışan teknolojileri ve bilinen zafiyetleri tek listede görün.