- Katılım
- 1 Ocak 2026
- Mesajlar
- 138
- Tepkime puanı
- 177
- Puan
- 43
Merhaba arkadaşlar
Uzun zamandır kafamda bir fikir vardı: gerçek, ifşa edilmiş (disclosed) bug bounty raporlarını alıp, sadece "bakın ne bulunmuş" diye özetlemek değil, araştırmacının kafasından neler geçmiş, hangi adımı hangi mantıkla atmış diye didik didik etmek. Çünkü bana göre bir raporu okuyup vay be, Elasticsearch'te RCE varmış demek hiçbir şey öğretmiyor. Asıl değerli olan, o araştırmacının dur, burada bir şey var dediği o ilk an ve sonrasında attığı her adımın arkasındaki mantık. Sürekli size bahsettiğim bakış açısı fikri.
İşte bu yüzden böyle bir seri başlatmaya karar verdim ve ilk yazı da bu oldu. Seçtiğim rapor biraz özel çünkü hedef başka bir şirket değil. HackerOne'ın kendi platformu. Kendi bug bounty programına gelen bu rapor, $7.000 ödül almış ve bana göre kör (blind) bir code injection'ı nasıl kanıtlayacağınızın ders kitabı niteliğinde bir örneği. Gelin birlikte sökelim.
CVSS vektörüne baktığımda (AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:H) şunu görüyorum: ağ üzerinden, düşük karmaşıklıkla, kimlik doğrulaması gerektiren (PR:N ama "Authenticated" diyor, yani özel bir yetki değil, sıradan bir hesap yeterli) ve kullanıcı etkileşimi gerektirmeyen bir zafiyet. Gizlilik ve kullanılabilirlik üzerinde etkisi yüksek, bütünlük etkisi yok çünkü araştırmacı hiçbir veri değiştirmemiş, sadece okuma kanıtı sunmuş. buna birazdan geleceğiz.
GraphQL bir API şeması tanımlama dili. Her alan, aldığı argümanların tipini ilan eder:
Burada sort_query'nin tipi düz String. Ben bu tür şeyleri görünce hep dururum, çünkü bir "sıralama" parametresi iyi tasarlanmış bir API'de genelde bir enum (ASC/DESC) veya yapılandırılmış bir input olur ({field: "name", direction: ASC} gibi). Düz string olması bana "bu değer hiç işlenmeden, ham haliyle bir alt sisteme geçiyor olabilir" dedirtir.
Elasticsearch (ES), büyük veri kümelerinde hızlı arama için kullanılan bir motor. HackerOne gibi platformlar milyonlarca raporu/bildirimi aranabilir tutmak için bunu kullanıyor. Normal bir sıralama isteği şöyle görünür:
Gayet masum. Ama ES'in çok daha güçlü bir modu var: _script sort. Bu mod, sıralama anahtarını sabit bir değer yerine, her doküman için çalıştırılan bir script'in döndürdüğü değer olarak alıyor:
Painless, Elasticsearch'ün kendi geliştirdiği, Java'ya benzeyen bir script dili. Amaç basit: kullanıcıların ES içinde özel hesaplamalar yapabilmesi. Sandbox'lanmış — yani teoride dosya sistemine, ağa, işletim sistemine direkt erişemiyor. Ama sandbox içinde bile doküman içeriğine erişim (doc['alan_adı'].value) tamamen mümkün.
Ve işte kritik nokta: bir uygulama, kullanıcıdan gelen bir string'i doğrudan bu _script.source alanına koyuyorsa, kullanıcı artık ES cluster'ı üzerinde kendi kodunu çalıştırabilir hale geliyor. Klasik "eval() kullanıcı girdisiyle" hatasının arama motoru versiyonu diyebiliriz.
sort_query'nin değeri, hiçbir şema doğrulaması veya keyword engelleme katmanı olmadan, doğrudan Elasticsearch'e sort parametresi olarak gidiyordu. Backend kodunu hayal etsem, kabaca şuna benzerdi:
Bu satırı görseniz sorunu anlarsınız. Ama biz bunu görmüyoruz. dışarıdan sadece bir GraphQL API'si görüyoruz. Araştırmacının yaptığı şey, dışarıdan gözlemlenebilir davranışlardan içerideki bu satırın var olduğunu çıkarmaktı. Bence asıl ustalık da burada.
Bunu neden yapıyoruz? Sıradan, özel yetkisi olmayan bir hesapla test ettiğimizi kanıtlamak için. Zafiyet sadece admin hesaplarından tetiklenebilseydi etkisi çok daha düşük olurdu. CVSS'teki PR:N (privileges required: none) buradan geliyor.
Burada henüz script falan yok — sadece sort_query'nin JSON olarak parse edilip etkili olduğunu görmek istiyorum. Dönen ID'ler gerçekten artan sırada geliyorsa, "bu string'i JSON.parse edip ES'e geçiren bir kod var" çıkarımım doğrulanıyor. Riskli bir adıma geçmeden önce zemin yoklamak benim için her zaman ilk kural.
Aynı sorgu şeklini, sadece script.source değerini değiştirerek 5 farklı şekilde gönderiyorum:
Bu tablo bana göre çok kıymetli, çünkü bu 5 payload GraphQL/JSON açısından yapısal olarak birbirinin aynısı — aynı anahtarlar, aynı tipte değerler. Sunucu sadece "JSON şeması doğru mu" diye bakıyor olsaydı hepsi aynı sonucu verirdi. Ama vermiyor — geçerli Painless kodu 200 dönüyor, geçersiz olan 500 dönüyor. Bu farkı yaratabilecek tek şey, girdimize ulaşan gerçek bir Painless derleyicisi.
Bir script'in derlenmesi çalıştırılması ile aynı şey değil. derlenip sonucu hiç kullanılmayabilir. Bunu ayırt etmek için iki isteği karşılaştırıyoruz, tek değişken farkıyla:
İstek A — sabit değer döndüren script:
İstek B — her dokümanın _seq_no'sunu (ES'in iç metadata alanı, dokümanın index'lenme sırası) okuyan script:
İlk 5 sonucun ID'leri:
İki sonuç kümesi arasında hiçbir örtüşme yok. İstek B'nin sıralaması, bağımsız bilinen bir baseline'la (Adım 2'deki "id":"asc" sıralaması) birebir eşleşiyor — çünkü _seq_no, dokümanın ID'siyle orantılı artan bir değer.
Bu bana neyi kanıtlıyor? Eğer script derlenip çalıştırılmıyor olsaydı, A ile B aynı (varsayılan) sonucu verirdi, çünkü ikisinin de etkisi sıfır olurdu. Ama vermiyorlar. Tek açıklama: script her doküman için bir kez çalışıyor, doc["_seq_no"].value'yu gerçekten okuyor ve bunu sıralama anahtarı olarak gerçekten kullanıyor.
görüyoruz ki potansiyel etki hiç de küçük değil. En kritik tespit şu: _script sort, GraphQL resolver seviyesindeki yetkilendirme filtresinden ÖNCE, Elasticsearch query fazında çalışıyor. Index tenant bazında ES seviyesinde bölümlenmemişse, script teorik olarak yetkisiz dokümanların alanlarını da okuyabilir.
Araştırmacının şu notu bence raporun en olgun kısmı: "Cross-tenant erişimin mümkün olup olmadığını doğrulamadım ve doğrulamayacağım. Bu araştırma HackerOne'ın iç ekibi tarafından yapılmalı." En kritik olabilecek etkiyi bilinçli olarak test etmeden rapor ediyor.
Bir de ikincil risk var: Painless sort script'leri her dokümanda çalıştığı için, döngü/yoğun hesaplama içeren kötü niyetli scriptler paylaşılan ES cluster'ında DoS yaratabilir.
Bence bu, "ne kadar ileri gidebilirim"i göstermek isteyen araştırmacılardan ayıran en önemli fark. Kanıtı en ucuz şekilde elde edip durmak, hem etik hem de profesyonel bir tercih.
HackerOne bunu harfiyen uyguladı: sort_query tamamen kaldırıldı, yerine SortInput { field: String!, direction: OrderDirection } (enum tipli, JSON-blob taşımayan, yapısal bir input) getirildi — hem ana yüzeyde hem işaret edilen kardeş yüzeyde. Ben de bunu daha sonra kendi testimde doğruladım, fix gerçekten sağlam.
Bu ilk yazıydı umarım faydalı olmuştur. Aklınıza takılan bir şey olursa yorumlarda buluşalım, bir dahaki vakada görüşmek üzere. Talep olursa YT videosu da çekebilirim.
Bu yazı, hackerone.com/reports/3694007 raporunun kamuya açık metninden derlenmiştir.
Uzun zamandır kafamda bir fikir vardı: gerçek, ifşa edilmiş (disclosed) bug bounty raporlarını alıp, sadece "bakın ne bulunmuş" diye özetlemek değil, araştırmacının kafasından neler geçmiş, hangi adımı hangi mantıkla atmış diye didik didik etmek. Çünkü bana göre bir raporu okuyup vay be, Elasticsearch'te RCE varmış demek hiçbir şey öğretmiyor. Asıl değerli olan, o araştırmacının dur, burada bir şey var dediği o ilk an ve sonrasında attığı her adımın arkasındaki mantık. Sürekli size bahsettiğim bakış açısı fikri.
İşte bu yüzden böyle bir seri başlatmaya karar verdim ve ilk yazı da bu oldu. Seçtiğim rapor biraz özel çünkü hedef başka bir şirket değil. HackerOne'ın kendi platformu. Kendi bug bounty programına gelen bu rapor, $7.000 ödül almış ve bana göre kör (blind) bir code injection'ı nasıl kanıtlayacağınızın ders kitabı niteliğinde bir örneği. Gelin birlikte sökelim.
Kaynak: hackerone.com/reports/3694007. halka açık, tüm teknik detaylar HackerOne ve araştırmacı (brumbelow) tarafından zaten yayınlanmış. Ben burada kendi yorumumu ve çıkardığım dersleri ekliyorum.
Bu Rapor Neden Beni Bu Kadar Etkiledi?
Bug bounty'de "RCE buldum" demek kolay, kanıtlamak zor. özellikle çıktıyı doğrudan göremediğiniz durumlarda. Bu raporu okurken beni en çok etkileyen şey, araştırmacının hiçbir veri sızdırmadan, sadece mantıksal çıkarımla kör bir code injection'ı nasıl ispatladığıydı. Bu yazıda birlikte şunlara bakacağız:- Elasticsearch'ün "sort" mekanizması neden bazen bir RCE kapısı olabiliyor,
- "Blind" bir code injection'ı veri sızdırmadan nasıl ispatlarsınız (ben buna oracle tekniği diyorum),
- Bir API şemasında hangi tasarım kokuları (code smell) beni böyle bir araştırmaya yönlendirir,
- Ve nerede durmak gerektiği. çünkü bu rapor sorumlu araştırmanın da güzel bir örneği.
Önce Künyeye Bakalım
| Alan | Değer |
|---|---|
| Program | HackerOne Security (hackerone.com/security) |
| Araştırmacı | brumbelow |
| Rapor başlığı | Authenticated Elasticsearch Painless script execution via Query.search.sort_query |
| Severity | High — CVSS 4.0: 8.8 |
| Weakness sınıfı | Code Injection |
| Ödül | $7.000 |
| Durum | Resolved, ardından disclosed |
| Oy sayısı (hacktivity) | 57 |
CVSS vektörüne baktığımda (AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:H) şunu görüyorum: ağ üzerinden, düşük karmaşıklıkla, kimlik doğrulaması gerektiren (PR:N ama "Authenticated" diyor, yani özel bir yetki değil, sıradan bir hesap yeterli) ve kullanıcı etkileşimi gerektirmeyen bir zafiyet. Gizlilik ve kullanılabilirlik üzerinde etkisi yüksek, bütünlük etkisi yok çünkü araştırmacı hiçbir veri değiştirmemiş, sadece okuma kanıtı sunmuş. buna birazdan geleceğiz.
Önce Şu Kavramları Netleştirelim
Devam etmeden önce üç şeyi anlamamız gerekiyor, yoksa gerisi havada kalır.GraphQL bir API şeması tanımlama dili. Her alan, aldığı argümanların tipini ilan eder:
Kod:
search(index: IndexEnum!, sort_query: String): SearchResultConnection
Burada sort_query'nin tipi düz String. Ben bu tür şeyleri görünce hep dururum, çünkü bir "sıralama" parametresi iyi tasarlanmış bir API'de genelde bir enum (ASC/DESC) veya yapılandırılmış bir input olur ({field: "name", direction: ASC} gibi). Düz string olması bana "bu değer hiç işlenmeden, ham haliyle bir alt sisteme geçiyor olabilir" dedirtir.
Benim kuralım: Bir API'de "sort", "filter", "query" gibi yapısal bir kavramı temsil eden ama tipi düz String olan bir argüman görürsem, orası benim için araştırmaya başlama noktası olur.
Elasticsearch (ES), büyük veri kümelerinde hızlı arama için kullanılan bir motor. HackerOne gibi platformlar milyonlarca raporu/bildirimi aranabilir tutmak için bunu kullanıyor. Normal bir sıralama isteği şöyle görünür:
JSON:
{ "sort": [ { "created_at": "desc" } ] }
Gayet masum. Ama ES'in çok daha güçlü bir modu var: _script sort. Bu mod, sıralama anahtarını sabit bir değer yerine, her doküman için çalıştırılan bir script'in döndürdüğü değer olarak alıyor:
JSON:
{
"sort": [{
"_script": {
"type": "number",
"script": { "source": "doc['some_field'].value * 2", "lang": "painless" },
"order": "asc"
}
}]
}
Painless, Elasticsearch'ün kendi geliştirdiği, Java'ya benzeyen bir script dili. Amaç basit: kullanıcıların ES içinde özel hesaplamalar yapabilmesi. Sandbox'lanmış — yani teoride dosya sistemine, ağa, işletim sistemine direkt erişemiyor. Ama sandbox içinde bile doküman içeriğine erişim (doc['alan_adı'].value) tamamen mümkün.
Ve işte kritik nokta: bir uygulama, kullanıcıdan gelen bir string'i doğrudan bu _script.source alanına koyuyorsa, kullanıcı artık ES cluster'ı üzerinde kendi kodunu çalıştırabilir hale geliyor. Klasik "eval() kullanıcı girdisiyle" hatasının arama motoru versiyonu diyebiliriz.
Peki Burada Tam Olarak Ne Bozuk?
HackerOne'ın hackerone.com/graphql endpoint'inde Query.search alanı şuna benziyordu:
Kod:
search(
index: IndexEnum!
query_string: String
sort_query: String # ← sorun burada
size: Int
): SearchResultConnection
sort_query'nin değeri, hiçbir şema doğrulaması veya keyword engelleme katmanı olmadan, doğrudan Elasticsearch'e sort parametresi olarak gidiyordu. Backend kodunu hayal etsem, kabaca şuna benzerdi:
Ruby:
es_query = {
query: build_query(query_string),
sort: JSON.parse(sort_query) # kullanıcı girdisi hiç süzülmeden ES'e gidiyor
}
Bu satırı görseniz sorunu anlarsınız. Ama biz bunu görmüyoruz. dışarıdan sadece bir GraphQL API'si görüyoruz. Araştırmacının yaptığı şey, dışarıdan gözlemlenebilir davranışlardan içerideki bu satırın var olduğunu çıkarmaktı. Bence asıl ustalık da burada.
Araştırmacı Buraya Nasıl Geldi?
- Şüpheli parametre tespiti: sort_query: String argümanı, yukarıda bahsettiğim "kırmızı bayrak" sezgisiyle işaretleniyor.
- Backend teknolojisi bilgisi: HackerOne'ın arama altyapısının Elasticsearch olduğu biliniyor (büyük SaaS platformlarında yaygın bir tercih, dolaylı kaynaklardan da teyit edilebilir).
- Spesifik tehlikeli özellik eşleştirmesi: "Bu ham JSON ES'e gidiyorsa, ES'in en tehlikeli sort özelliği olan _script'i deneyebilirim" çıkarımı yapılıyor. Bu, rastgele zafiyet taramaktan çok daha derin bir adım — hedefin teknolojisini bilmeyi gerektiriyor.
Asıl Mesele: Kör Bir RCE'yi Nasıl Kanıtlarsınız?
Bence raporun kalbi burası. Script'in çalıştığı görünmüyor. hiçbir yerde "merhaba dünya" basılmıyor. Tek belirti, arama sonuçlarının sıralamasındaki değişim. Araştırmacı da SQL injection'da kullandığımız blind/boolean-based teknikleri buraya taşımış.
Bash:
curl 'https://hackerone.com/graphql' -H "..." -b "$COOKIE" \
--data-raw '{"query":"{me{_id username}}"}'
Bunu neden yapıyoruz? Sıradan, özel yetkisi olmayan bir hesapla test ettiğimizi kanıtlamak için. Zafiyet sadece admin hesaplarından tetiklenebilseydi etkisi çok daha düşük olurdu. CVSS'teki PR:N (privileges required: none) buradan geliyor.
Kod:
search(index: NotificationsIndex, query_string: "*", sort_query: "[{\"id\":\"asc\"}]", size: 5)
Burada henüz script falan yok — sadece sort_query'nin JSON olarak parse edilip etkili olduğunu görmek istiyorum. Dönen ID'ler gerçekten artan sırada geliyorsa, "bu string'i JSON.parse edip ES'e geçiren bir kod var" çıkarımım doğrulanıyor. Riskli bir adıma geçmeden önce zemin yoklamak benim için her zaman ilk kural.
Aynı sorgu şeklini, sadece script.source değerini değiştirerek 5 farklı şekilde gönderiyorum:
| script.source değeri | Sonuç | Anlamı |
|---|---|---|
| (hiç script anahtarı yok) | HTTP 500 | Yapısal hata |
| "" (boş) | HTTP 500 | Painless derleme hatası |
| "unterminated (bozuk syntax) | HTTP 500 | Painless derleme hatası |
| "1" | HTTP 200 | Painless derleme başarılı |
| "1+1" | HTTP 200 | Painless derleme başarılı |
Bu tablo bana göre çok kıymetli, çünkü bu 5 payload GraphQL/JSON açısından yapısal olarak birbirinin aynısı — aynı anahtarlar, aynı tipte değerler. Sunucu sadece "JSON şeması doğru mu" diye bakıyor olsaydı hepsi aynı sonucu verirdi. Ama vermiyor — geçerli Painless kodu 200 dönüyor, geçersiz olan 500 dönüyor. Bu farkı yaratabilecek tek şey, girdimize ulaşan gerçek bir Painless derleyicisi.
Benim genel ilkem: Bir sistemin girdimi anlamlı işlediğini kanıtlamak istediğimde, yapısal olarak özdeş ama anlamsal olarak farklı (biri geçerli, biri geçersiz "alt dilde") iki payload gönderirim. Farklı sonuç çıkıyorsa, girdim gerçekten o alt dilin yorumlayıcısına ulaşıyor demektir.
Bir script'in derlenmesi çalıştırılması ile aynı şey değil. derlenip sonucu hiç kullanılmayabilir. Bunu ayırt etmek için iki isteği karşılaştırıyoruz, tek değişken farkıyla:
İstek A — sabit değer döndüren script:
JSON:
"_script": { "script": { "source": "1" }, "order": "asc" }
İstek B — her dokümanın _seq_no'sunu (ES'in iç metadata alanı, dokümanın index'lenme sırası) okuyan script:
JSON:
"_script": { "script": { "source": "doc[\"_seq_no\"].value" }, "order": "asc" }
İlk 5 sonucun ID'leri:
| Pozisyon | İstek A (sabit) | İstek B (_seq_no) |
|---|---|---|
| 1 | 451190393 | 404547633 |
| 2 | 433571802 | 408446504 |
| 3 | 444651582 | 416737094 |
| ... | ... | ... |
İki sonuç kümesi arasında hiçbir örtüşme yok. İstek B'nin sıralaması, bağımsız bilinen bir baseline'la (Adım 2'deki "id":"asc" sıralaması) birebir eşleşiyor — çünkü _seq_no, dokümanın ID'siyle orantılı artan bir değer.
Bu bana neyi kanıtlıyor? Eğer script derlenip çalıştırılmıyor olsaydı, A ile B aynı (varsayılan) sonucu verirdi, çünkü ikisinin de etkisi sıfır olurdu. Ama vermiyorlar. Tek açıklama: script her doküman için bir kez çalışıyor, doc["_seq_no"].value'yu gerçekten okuyor ve bunu sıralama anahtarı olarak gerçekten kullanıyor.
Benim genel ilkem: "Kod çalıştı mı?" sorusuna cevap ararken kontrollü bir deney kurarım — tek bir değişkeni değiştirip (sabit dönüş ↔ bağlama-bağımlı dönüş) gerisini sabit tutarım. Aradaki fark, ortadaki kara kutunun gerçekten çalıştığının kanıtıdır. A/B testi mantığının güvenlik araştırmasına uygulanmış hali diyebiliriz.
- Her dokümanda garanti var — null/hata riski yok, test her zaman çalışır.
- Insertion-order ile monoton artıyor — beklenen sonucu önceden tahmin edip gerçekle çapraz doğrulayabiliyorum.
- ES-internal bir metadata, kullanıcı/program verisi değil — yani hiçbir gizlilik ihlaline girmeden "okuma erişimi var" kanıtı sunuyorum.
Peki Etkisi Ne Olabilirdi?
Painless script'i Elasticsearch'ün JVM süreci içinde çalışıyor. Query.search'ün döndürdüğü DocumentUnion üzerinden erişilebilen doküman tiplerine bakınca:- ReportDocument, FindingDocument — rapor içerikleri
- NotificationDocument — bildirim içerikleri
- OpportunityDocument — program metadata
- StructuredScopeDocument — program scope tanımları
- OrganizationMemberDocument — organizasyon üyelik bilgisi
- AnalyticsGatewayHttpStreamDocument — yakalanan HTTP trafiği metadata'sı
görüyoruz ki potansiyel etki hiç de küçük değil. En kritik tespit şu: _script sort, GraphQL resolver seviyesindeki yetkilendirme filtresinden ÖNCE, Elasticsearch query fazında çalışıyor. Index tenant bazında ES seviyesinde bölümlenmemişse, script teorik olarak yetkisiz dokümanların alanlarını da okuyabilir.
Araştırmacının şu notu bence raporun en olgun kısmı: "Cross-tenant erişimin mümkün olup olmadığını doğrulamadım ve doğrulamayacağım. Bu araştırma HackerOne'ın iç ekibi tarafından yapılmalı." En kritik olabilecek etkiyi bilinçli olarak test etmeden rapor ediyor.
Bir de ikincil risk var: Painless sort script'leri her dokümanda çalıştığı için, döngü/yoğun hesaplama içeren kötü niyetli scriptler paylaşılan ES cluster'ında DoS yaratabilir.
Burada Durmak da Bir Beceridir
Araştırmacının test kapsamına bakınca:- Sadece "1", "1+1", "3+4" ve doc["_seq_no"].value denemiş. Başka alan okuma, metod çağrısı, döngü — hiçbiri yok.
- _seq_no kullanıcı/program verisi değil.
- Tüm denemeler kendi authenticated session'ının kendi sonuç kümesinde (NotificationsIndex, kendine ait 716 bildirim).
- Sandbox sınırları (dosya sistemi, network) hiç test edilmemiş.
- Başka kullanıcıya ait veri okunmamış, cross-tenant erişim denenmemiş.
- Benzer sort_query argümanına sahip diğer alanlar (Organization.findings_search) test edilmemiş ama rapor edilmiş — HackerOne kendi içinde kontrol etsin diye.
- Execution kanıtlandığı an tüm test durdurulmuş.
Bence bu, "ne kadar ileri gidebilirim"i göstermek isteyen araştırmacılardan ayıran en önemli fark. Kanıtı en ucuz şekilde elde edip durmak, hem etik hem de profesyonel bir tercih.
Çözüm Ne Oldu?
Araştırmacının önerisi: sort_query: String argümanını tamamen kaldırmak, mevcut tip-güvenli sort: SortInput zaten yeterliydi. Aynı tedaviyi Organization.findings_search.sort_query'ye de uygulamak.HackerOne bunu harfiyen uyguladı: sort_query tamamen kaldırıldı, yerine SortInput { field: String!, direction: OrderDirection } (enum tipli, JSON-blob taşımayan, yapısal bir input) getirildi — hem ana yüzeyde hem işaret edilen kardeş yüzeyde. Ben de bunu daha sonra kendi testimde doğruladım, fix gerçekten sağlam.
Benden Size Çıkarımlar
Bu raporu kendi avlarınızda kullanabileceğiniz bir kontrol listesine dökersem:- API şemasını okurken, "sort/filter/query/format" gibi yapısal bir kavramı temsil eden ama tipi düz String/JSON olan argümanları işaretleyin.
- Hedefin backend teknolojisini öğrenin. "Injection arayayım" demek yerine "bu teknolojinin en tehlikeli özelliği ne?" diye sorun.
- Riskli bir payload atmadan önce zararsız bir prob ile zemin yoklayın.
- Çıktıyı göremiyorsanız bir oracle kurun:
- Compile oracle: yapısal özdeş, anlamsal farklı iki payload → farklı hata = yorumlayıcıya ulaşıyorsunuz.
- Execution oracle: sabit dönüş ↔ bağlama-bağımlı dönüş → davranış farkı = kod gerçekten çalışıyor.
- Kanıtı elde ettiğiniz an durun. Daha riskli adımları (sandbox kaçışı, cross-tenant erişim) denemeyin, not edip raporlayın.
- Ampirik olarak kanıtlamadığınız etkileri bile mimari çıkarımla yazabilirsiniz — bu, risk almadan raporun değerini artırır.
Bu ilk yazıydı umarım faydalı olmuştur. Aklınıza takılan bir şey olursa yorumlarda buluşalım, bir dahaki vakada görüşmek üzere. Talep olursa YT videosu da çekebilirim.
Bu yazı, hackerone.com/reports/3694007 raporunun kamuya açık metninden derlenmiştir.