<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title><![CDATA[TurkTeam | Türk Siber Güvenlik Topluluğu - Web Uygulama Güvenliği]]></title>
		<link>https://www.turkteam.org/</link>
		<description><![CDATA[TurkTeam | Türk Siber Güvenlik Topluluğu - https://www.turkteam.org]]></description>
		<pubDate>Sun, 25 Oct 2026 18:48:40 +0000</pubDate>
		<generator>MyBB</generator>
		<item>
			<title><![CDATA[postMessage Güvenliği: Storybook CVE-2026-114125 Üzerinden Origin Doğrulama]]></title>
			<link>https://www.turkteam.org/konu-postmessage-guvenligi-storybook-cve-2026-114125-uzerinden-origin-dogrulama.html</link>
			<pubDate>Fri, 23 Oct 2026 11:30:39 +0300</pubDate>
			<dc:creator><![CDATA[<a href="https://www.turkteam.org/member.php?action=profile&uid=3">BilgeKagan</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.turkteam.org/konu-postmessage-guvenligi-storybook-cve-2026-114125-uzerinden-origin-dogrulama.html</guid>
			<description><![CDATA[<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=375" loading="lazy"  alt="[Resim: attachment.php?aid=375]" class="mycode_img" /></div>
<br />
Selamlar,<br />
<br />
Storybook ekibi CVE-2026-114125 (GHSA-f2ph-cmg5-wxc8, CVSS 4.0 <span style="font-weight: bold;" class="mycode_b">9.4</span>) ile ilgili danışmayı yayımladı: çalışan bir <span style="font-weight: bold;" class="mycode_b">storybook dev</span> sunucusunun preview iframe'i herhangi bir web sitesine gömülebiliyor ve her origin'den postMessage olayı kabul ediyordu. Kötü niyetli bir site, kullanıcı etkileşimiyle dev sunucusunun story dosyalarını değiştirmesini sağlayabiliyor; değişen dosya yerel bir runtime tarafından çalıştırılırsa geliştiricinin yetkisiyle kod çalışabiliyordu. Bu konu, olayı özetleyip kendi kodunuzda postMessage'ı nasıl güvenli kullanacağınızı anlatıyor.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Konuda anlatılacaklar</span></span><br />
<ol type="1" class="mycode_list"><li>Storybook açığının özeti ve yamalı sürümler<br />
</li>
<li>postMessage nasıl çalışır?<br />
</li>
<li>Hatalı ve doğru alıcı kodu<br />
</li>
<li>Gönderen tarafta hedef origin<br />
</li>
<li>Kontrol listesi<br />
</li>
</ol>
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Storybook özeti</span></span><ul class="mycode_list"><li>Etkilenen: Storybook 8, 9, 10 ve 11 alpha dev sunucuları (@storybook/addon-mcp ve @storybook/addon-vitest dahil).<br />
</li>
<li>Yamalı: <span style="font-weight: bold;" class="mycode_b">8.6.19, 9.1.21, 10.6.2, 11.0.0-alpha.6</span>. Yükseltmeden storybook dev çalıştırmayın.<br />
</li>
<li>Etkilenmeyen: Build edilmiş statik Storybook'lar ve tarayıcıda hiç açılmayan dev sunucuları.<br />
</li>
<li>Yeni varsayılanlar: farklı host adına iframe gömme kapalı; preview ve manager yalnızca kendi origin'i ve localhost servisleriyle mesajlaşıyor. Eski davranış için security.insecureRemoteIframeEmbed ve security.insecureIframeMessaging bayrakları var ama ekip bunları önermiyor.<br />
</li>
<li>Danışmaya göre Chrome ve Firefox'un yeni sürümleri bir sitenin localhost'a bağlanmadan önce izin isteyebiliyor; güvenmediğiniz sitelere bu izni vermeyin.<br />
</li>
</ul>
CWE listesi de öğretici: CWE-346 (Origin Validation Error), CWE-1021 (iframe kısıtlaması), CWE-22 (path traversal), CWE-862 (eksik yetkilendirme). Yani tek bir hata değil, birkaç zayıf katmanın zinciri.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">postMessage nasıl çalışır?</span></span><br />
window.postMessage farklı origin'deki pencereler (ana sayfa ile iframe, açılan popup) arasında güvenli mesajlaşma için tasarlandı. Ama "güvenli" olması iki tarafın da kontrol yapmasına bağlı. MDN açıkça uyarıyor: mesaj alan taraf event.origin'i doğrulamazsa, herhangi bir site mesaj gönderebilir.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Hatalı alıcı</span></span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>// YANLIS: her origin'den gelen mesaja guveniyor
window.addEventListener("message", (e) =&gt; {
  if (e.data.type === "updateFile") {
    saveFile(e.data.path, e.data.content);   // tehlikeli islem
  }
});</code></div></div><br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Doğru alıcı</span></span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>const ALLOWED = new Set(["https://app.ornek.com", "http://localhost:6006"]);
window.addEventListener("message", (e) =&gt; {
  // 1) Origin'i tam eslesme ile dogrula (includes/startsWith kullanma)
  if (!ALLOWED.has(e.origin)) return;
  // 2) Kaynagin beklenen pencere oldugunu kontrol et
  if (e.source !== expectedFrame.contentWindow) return;
  // 3) Veriyi sema ile dogrula
  const d = e.data;
  if (typeof d !== "object" || d.type !== "setArgs") return;
  // 4) Tehlikeli islemleri mesajla tetikleme; yalnizca dar kapsamli UI durumu
  applyArgs(sanitize(d.args));
});</code></div></div>Sık hata: e.origin.includes("ornek.com") gibi kontroller; "ornek.com.saldirgan.net" bunu geçer. Her zaman tam eşleşme kullanın.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Gönderen taraf</span></span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>// YANLIS: "*" hedefi, mesaji kim yuklenmisse ona verir
frame.contentWindow.postMessage(secretToken, "*");
// DOGRU: hedef origin'i acikca yaz
frame.contentWindow.postMessage({type:"init"}, "https://widget.ornek.com");</code></div></div><br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kontrol listesi</span></span><br />
<ol type="1" class="mycode_list"><li>Her message dinleyicisinde izin listesiyle tam origin eşleşmesi.<br />
</li>
<li>Mesajla dosya yazma, komut çalıştırma, kimlik bilgisi aktarma gibi yan etkili işlem yapmayın.<br />
</li>
<li>Gömülmesini istemediğiniz sayfalarda Content-Security-Policy: frame-ancestors 'self' kullanın.<br />
</li>
<li>Geliştirme sunucularını (Storybook, Vite, Jupyter) yalnızca localhost'a bağlayın ve güncel tutun.<br />
</li>
<li>Kod incelemesinde "addEventListener('message'" araması yapın.<br />
</li>
</ol>
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>grep -rn "addEventListener(&#92;s*['&#92;"]message" src/ | head
grep -rn "postMessage(.*['&#92;"]&#92;*['&#92;"]" src/ | head</code></div></div><br />
Kendi projelerinizde postMessage dinleyicilerini en son ne zaman denetlediniz? Bulduğunuz hatalı kalıpları paylaşın.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Yasal uyarı</span></span><br />
Bu yazı bilgilendirme ve savunma amaçlıdır. Anlatılan kontrolleri yalnızca kendi sistemlerinizde veya yazılı izinle yapın. İzinsiz erişim, tarama ve sömürü girişimleri TCK 243-245 kapsamında suçtur. TurkTeam white-hat bir topluluktur; çalıntı veri, hesap, combo/log paylaşımı ve hack hizmeti talepleri forum kurallarına aykırıdır.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kaynaklar</span></span><ul class="mycode_list"><li><a href="https://github.com/storybookjs/storybook/security/advisories/GHSA-f2ph-cmg5-wxc8" target="_blank" rel="noopener" class="mycode_url">https://github.com/storybookjs/storybook...-cmg5-wxc8</a><br />
</li>
<li><a href="https://www.cve.org/CVERecord?id=CVE-2026-114125" target="_blank" rel="noopener" class="mycode_url">https://www.cve.org/CVERecord?id=CVE-2026-114125</a><br />
</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage" target="_blank" rel="noopener" class="mycode_url">https://developer.mozilla.org/en-US/docs...ostMessage</a><br />
</li>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/HTML5_Security_Cheat_Sheet.html" target="_blank" rel="noopener" class="mycode_url">https://cheatsheetseries.owasp.org/cheat...Sheet.html</a><br />
</li>
</ul>
<br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=375" target="_blank" title="">11-b01-postmessage-origin.png</a> (Dosya Boyutu: 124.37 KB / İndirme Sayısı: 3)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=375" loading="lazy"  alt="[Resim: attachment.php?aid=375]" class="mycode_img" /></div>
<br />
Selamlar,<br />
<br />
Storybook ekibi CVE-2026-114125 (GHSA-f2ph-cmg5-wxc8, CVSS 4.0 <span style="font-weight: bold;" class="mycode_b">9.4</span>) ile ilgili danışmayı yayımladı: çalışan bir <span style="font-weight: bold;" class="mycode_b">storybook dev</span> sunucusunun preview iframe'i herhangi bir web sitesine gömülebiliyor ve her origin'den postMessage olayı kabul ediyordu. Kötü niyetli bir site, kullanıcı etkileşimiyle dev sunucusunun story dosyalarını değiştirmesini sağlayabiliyor; değişen dosya yerel bir runtime tarafından çalıştırılırsa geliştiricinin yetkisiyle kod çalışabiliyordu. Bu konu, olayı özetleyip kendi kodunuzda postMessage'ı nasıl güvenli kullanacağınızı anlatıyor.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Konuda anlatılacaklar</span></span><br />
<ol type="1" class="mycode_list"><li>Storybook açığının özeti ve yamalı sürümler<br />
</li>
<li>postMessage nasıl çalışır?<br />
</li>
<li>Hatalı ve doğru alıcı kodu<br />
</li>
<li>Gönderen tarafta hedef origin<br />
</li>
<li>Kontrol listesi<br />
</li>
</ol>
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Storybook özeti</span></span><ul class="mycode_list"><li>Etkilenen: Storybook 8, 9, 10 ve 11 alpha dev sunucuları (@storybook/addon-mcp ve @storybook/addon-vitest dahil).<br />
</li>
<li>Yamalı: <span style="font-weight: bold;" class="mycode_b">8.6.19, 9.1.21, 10.6.2, 11.0.0-alpha.6</span>. Yükseltmeden storybook dev çalıştırmayın.<br />
</li>
<li>Etkilenmeyen: Build edilmiş statik Storybook'lar ve tarayıcıda hiç açılmayan dev sunucuları.<br />
</li>
<li>Yeni varsayılanlar: farklı host adına iframe gömme kapalı; preview ve manager yalnızca kendi origin'i ve localhost servisleriyle mesajlaşıyor. Eski davranış için security.insecureRemoteIframeEmbed ve security.insecureIframeMessaging bayrakları var ama ekip bunları önermiyor.<br />
</li>
<li>Danışmaya göre Chrome ve Firefox'un yeni sürümleri bir sitenin localhost'a bağlanmadan önce izin isteyebiliyor; güvenmediğiniz sitelere bu izni vermeyin.<br />
</li>
</ul>
CWE listesi de öğretici: CWE-346 (Origin Validation Error), CWE-1021 (iframe kısıtlaması), CWE-22 (path traversal), CWE-862 (eksik yetkilendirme). Yani tek bir hata değil, birkaç zayıf katmanın zinciri.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">postMessage nasıl çalışır?</span></span><br />
window.postMessage farklı origin'deki pencereler (ana sayfa ile iframe, açılan popup) arasında güvenli mesajlaşma için tasarlandı. Ama "güvenli" olması iki tarafın da kontrol yapmasına bağlı. MDN açıkça uyarıyor: mesaj alan taraf event.origin'i doğrulamazsa, herhangi bir site mesaj gönderebilir.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Hatalı alıcı</span></span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>// YANLIS: her origin'den gelen mesaja guveniyor
window.addEventListener("message", (e) =&gt; {
  if (e.data.type === "updateFile") {
    saveFile(e.data.path, e.data.content);   // tehlikeli islem
  }
});</code></div></div><br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Doğru alıcı</span></span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>const ALLOWED = new Set(["https://app.ornek.com", "http://localhost:6006"]);
window.addEventListener("message", (e) =&gt; {
  // 1) Origin'i tam eslesme ile dogrula (includes/startsWith kullanma)
  if (!ALLOWED.has(e.origin)) return;
  // 2) Kaynagin beklenen pencere oldugunu kontrol et
  if (e.source !== expectedFrame.contentWindow) return;
  // 3) Veriyi sema ile dogrula
  const d = e.data;
  if (typeof d !== "object" || d.type !== "setArgs") return;
  // 4) Tehlikeli islemleri mesajla tetikleme; yalnizca dar kapsamli UI durumu
  applyArgs(sanitize(d.args));
});</code></div></div>Sık hata: e.origin.includes("ornek.com") gibi kontroller; "ornek.com.saldirgan.net" bunu geçer. Her zaman tam eşleşme kullanın.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Gönderen taraf</span></span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>// YANLIS: "*" hedefi, mesaji kim yuklenmisse ona verir
frame.contentWindow.postMessage(secretToken, "*");
// DOGRU: hedef origin'i acikca yaz
frame.contentWindow.postMessage({type:"init"}, "https://widget.ornek.com");</code></div></div><br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kontrol listesi</span></span><br />
<ol type="1" class="mycode_list"><li>Her message dinleyicisinde izin listesiyle tam origin eşleşmesi.<br />
</li>
<li>Mesajla dosya yazma, komut çalıştırma, kimlik bilgisi aktarma gibi yan etkili işlem yapmayın.<br />
</li>
<li>Gömülmesini istemediğiniz sayfalarda Content-Security-Policy: frame-ancestors 'self' kullanın.<br />
</li>
<li>Geliştirme sunucularını (Storybook, Vite, Jupyter) yalnızca localhost'a bağlayın ve güncel tutun.<br />
</li>
<li>Kod incelemesinde "addEventListener('message'" araması yapın.<br />
</li>
</ol>
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>grep -rn "addEventListener(&#92;s*['&#92;"]message" src/ | head
grep -rn "postMessage(.*['&#92;"]&#92;*['&#92;"]" src/ | head</code></div></div><br />
Kendi projelerinizde postMessage dinleyicilerini en son ne zaman denetlediniz? Bulduğunuz hatalı kalıpları paylaşın.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Yasal uyarı</span></span><br />
Bu yazı bilgilendirme ve savunma amaçlıdır. Anlatılan kontrolleri yalnızca kendi sistemlerinizde veya yazılı izinle yapın. İzinsiz erişim, tarama ve sömürü girişimleri TCK 243-245 kapsamında suçtur. TurkTeam white-hat bir topluluktur; çalıntı veri, hesap, combo/log paylaşımı ve hack hizmeti talepleri forum kurallarına aykırıdır.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kaynaklar</span></span><ul class="mycode_list"><li><a href="https://github.com/storybookjs/storybook/security/advisories/GHSA-f2ph-cmg5-wxc8" target="_blank" rel="noopener" class="mycode_url">https://github.com/storybookjs/storybook...-cmg5-wxc8</a><br />
</li>
<li><a href="https://www.cve.org/CVERecord?id=CVE-2026-114125" target="_blank" rel="noopener" class="mycode_url">https://www.cve.org/CVERecord?id=CVE-2026-114125</a><br />
</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage" target="_blank" rel="noopener" class="mycode_url">https://developer.mozilla.org/en-US/docs...ostMessage</a><br />
</li>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/HTML5_Security_Cheat_Sheet.html" target="_blank" rel="noopener" class="mycode_url">https://cheatsheetseries.owasp.org/cheat...Sheet.html</a><br />
</li>
</ul>
<br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=375" target="_blank" title="">11-b01-postmessage-origin.png</a> (Dosya Boyutu: 124.37 KB / İndirme Sayısı: 3)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Güvenli Olmayan Deserialization: pickle, YAML ve Java için OWASP Özeti]]></title>
			<link>https://www.turkteam.org/konu-guvenli-olmayan-deserialization-pickle-yaml-ve-java-icin-owasp-ozeti.html</link>
			<pubDate>Thu, 22 Oct 2026 11:35:44 +0300</pubDate>
			<dc:creator><![CDATA[<a href="https://www.turkteam.org/member.php?action=profile&uid=4">KulTigin</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.turkteam.org/konu-guvenli-olmayan-deserialization-pickle-yaml-ve-java-icin-owasp-ozeti.html</guid>
			<description><![CDATA[<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=360" loading="lazy"  alt="[Resim: attachment.php?aid=360]" class="mycode_img" /></div>
<br />
Selamlar,<br />
<br />
CISA'nın SafePay uyarısında Veeam Backup &amp; Replication için adı geçen CVE-2024-40711, CWE-502: Deserialization of Untrusted Data sınıfında. Yani sorun yeni değil; fidye grupları hâlâ bu sınıftan besleniyor. Bu yazıda OWASP Deserialization Cheat Sheet'in pratik kısımlarını Python, Java ve genel prensipler üzerinden özetliyorum.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Konuda anlatılacaklar</span></span><br />
<ol type="1" class="mycode_list"><li>Serialization / deserialization nedir?<br />
</li>
<li>Python: pickle ve YAML<br />
</li>
<li>Java: ObjectInputStream ve filtreler<br />
</li>
<li>Genel kural: güvenilmeyen veriyi native formatta açmayın<br />
</li>
</ol>
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kısa tanım</span></span><br />
Serialization bir nesneyi saklanabilir / gönderilebilir bir formata çevirmektir; deserialization tersidir. JSON ve XML gibi saf veri formatları görece güvenlidir. Birçok dilin yerel (native) formatı ise özelleştirme özellikleri sunar; bu özellikler güvenilmeyen veride RCE, DoS veya erişim kontrolü atlatmaya dönüşebilir.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Python</span></span><br />
OWASP'ın net uyarısı:<ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">pickle.load / pickle.loads:</span> Güvenilmeyen veriyi asla unpickle etmeyin; keyfi kod çalıştırabilir.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">PyYAML:</span> Güvenilmeyen YAML için yaml.safe_load() kullanın; yaml.unsafe_load veya Loader=yaml.Loader / UnsafeLoader kullanmayın.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">jsonpickle.decode:</span> Güvenilmeyen girdiyle kullanmayın.<br />
</li>
</ul>
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Kendi labiniz - guvenli YAML
import yaml
metin = "liste: [1, 2, 3]"
veri = yaml.safe_load(metin)
print(veri)
# pickle: yalnizca tamamen guvendiginiz, sizin urettiginiz baytlar</code></div></div><br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Java</span></span><ul class="mycode_list"><li>ObjectInputStream.readObject / readUnshared, XStream.fromXML, XMLDecoder gibi API'leri güvenilmeyen girdiyle kullanmayın.<br />
</li>
<li>Serialization filter'ları uygulama özel sınıf allow-list'i ve kaynak limitleriyle yapılandırın.<br />
</li>
<li>resolveClass() override'ı tek başına yeterli değildir; grafik derinliği, referans sayısı, dizi uzunluğu ve akış boyutu da sınırlanmalıdır.<br />
</li>
<li>Hex'te AC ED 00 05 veya Base64'te rO0 ile başlayan trafik Java serialization işareti olabilir.<br />
</li>
</ul>
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Genel prensipler</span></span><br />
<ol type="1" class="mycode_list"><li>Mümkünse native format yerine JSON/XML gibi saf veri formatı kullanın.<br />
</li>
<li>Akışın nesne tipini belirlemesine izin vermeyin.<br />
</li>
<li>İmzalı (imzası doğrulanmış) veriyi deserialize edin.<br />
</li>
<li>Hassas alanları transient yapın; asla deserialize edilmemesi gereken sınıflarda readObject her zaman istisna fırlatsın.<br />
</li>
</ol>
<br />
SafePay bağlamında ders basit: yedekleme ürünlerindeki yıllardır bilinen deserialization RCE'leri hâlâ aktif sömürü vektörü. Envanterinizde Veeam, eski Java serileştirme uçları ve pickle kullanan dahili API'ler varsa bunları "teknik borç" değil "açık kapı" olarak işaretleyin.<br />
<br />
Kod tabanınızda pickle veya yaml.load (safe olmayan) kalan yer var mı? Grep sonucunuzu (dosya yolu yeter) paylaşın.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Yasal uyarı</span></span><br />
Bu yazı bilgilendirme ve savunma amaçlıdır. Anlatılan kontrolleri yalnızca kendi sistemlerinizde veya yazılı izinle yapın. İzinsiz erişim, tarama ve sömürü girişimleri TCK 243-245 kapsamında suçtur. TurkTeam white-hat bir topluluktur; çalıntı veri, hesap, combo/log paylaşımı ve hack hizmeti talepleri forum kurallarına aykırıdır.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kaynaklar</span></span><ul class="mycode_list"><li><a href="https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html" target="_blank" rel="noopener" class="mycode_url">https://cheatsheetseries.owasp.org/cheat...Sheet.html</a><br />
</li>
<li><a href="https://www.cisa.gov/news-events/cybersecurity-advisories/aa26-293a" target="_blank" rel="noopener" class="mycode_url">https://www.cisa.gov/news-events/cyberse.../aa26-293a</a><br />
</li>
</ul>
<br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=360" target="_blank" title="">18-k03-deserialization.png</a> (Dosya Boyutu: 121.98 KB / İndirme Sayısı: 11)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=360" loading="lazy"  alt="[Resim: attachment.php?aid=360]" class="mycode_img" /></div>
<br />
Selamlar,<br />
<br />
CISA'nın SafePay uyarısında Veeam Backup &amp; Replication için adı geçen CVE-2024-40711, CWE-502: Deserialization of Untrusted Data sınıfında. Yani sorun yeni değil; fidye grupları hâlâ bu sınıftan besleniyor. Bu yazıda OWASP Deserialization Cheat Sheet'in pratik kısımlarını Python, Java ve genel prensipler üzerinden özetliyorum.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Konuda anlatılacaklar</span></span><br />
<ol type="1" class="mycode_list"><li>Serialization / deserialization nedir?<br />
</li>
<li>Python: pickle ve YAML<br />
</li>
<li>Java: ObjectInputStream ve filtreler<br />
</li>
<li>Genel kural: güvenilmeyen veriyi native formatta açmayın<br />
</li>
</ol>
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kısa tanım</span></span><br />
Serialization bir nesneyi saklanabilir / gönderilebilir bir formata çevirmektir; deserialization tersidir. JSON ve XML gibi saf veri formatları görece güvenlidir. Birçok dilin yerel (native) formatı ise özelleştirme özellikleri sunar; bu özellikler güvenilmeyen veride RCE, DoS veya erişim kontrolü atlatmaya dönüşebilir.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Python</span></span><br />
OWASP'ın net uyarısı:<ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">pickle.load / pickle.loads:</span> Güvenilmeyen veriyi asla unpickle etmeyin; keyfi kod çalıştırabilir.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">PyYAML:</span> Güvenilmeyen YAML için yaml.safe_load() kullanın; yaml.unsafe_load veya Loader=yaml.Loader / UnsafeLoader kullanmayın.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">jsonpickle.decode:</span> Güvenilmeyen girdiyle kullanmayın.<br />
</li>
</ul>
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Kendi labiniz - guvenli YAML
import yaml
metin = "liste: [1, 2, 3]"
veri = yaml.safe_load(metin)
print(veri)
# pickle: yalnizca tamamen guvendiginiz, sizin urettiginiz baytlar</code></div></div><br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Java</span></span><ul class="mycode_list"><li>ObjectInputStream.readObject / readUnshared, XStream.fromXML, XMLDecoder gibi API'leri güvenilmeyen girdiyle kullanmayın.<br />
</li>
<li>Serialization filter'ları uygulama özel sınıf allow-list'i ve kaynak limitleriyle yapılandırın.<br />
</li>
<li>resolveClass() override'ı tek başına yeterli değildir; grafik derinliği, referans sayısı, dizi uzunluğu ve akış boyutu da sınırlanmalıdır.<br />
</li>
<li>Hex'te AC ED 00 05 veya Base64'te rO0 ile başlayan trafik Java serialization işareti olabilir.<br />
</li>
</ul>
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Genel prensipler</span></span><br />
<ol type="1" class="mycode_list"><li>Mümkünse native format yerine JSON/XML gibi saf veri formatı kullanın.<br />
</li>
<li>Akışın nesne tipini belirlemesine izin vermeyin.<br />
</li>
<li>İmzalı (imzası doğrulanmış) veriyi deserialize edin.<br />
</li>
<li>Hassas alanları transient yapın; asla deserialize edilmemesi gereken sınıflarda readObject her zaman istisna fırlatsın.<br />
</li>
</ol>
<br />
SafePay bağlamında ders basit: yedekleme ürünlerindeki yıllardır bilinen deserialization RCE'leri hâlâ aktif sömürü vektörü. Envanterinizde Veeam, eski Java serileştirme uçları ve pickle kullanan dahili API'ler varsa bunları "teknik borç" değil "açık kapı" olarak işaretleyin.<br />
<br />
Kod tabanınızda pickle veya yaml.load (safe olmayan) kalan yer var mı? Grep sonucunuzu (dosya yolu yeter) paylaşın.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Yasal uyarı</span></span><br />
Bu yazı bilgilendirme ve savunma amaçlıdır. Anlatılan kontrolleri yalnızca kendi sistemlerinizde veya yazılı izinle yapın. İzinsiz erişim, tarama ve sömürü girişimleri TCK 243-245 kapsamında suçtur. TurkTeam white-hat bir topluluktur; çalıntı veri, hesap, combo/log paylaşımı ve hack hizmeti talepleri forum kurallarına aykırıdır.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kaynaklar</span></span><ul class="mycode_list"><li><a href="https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html" target="_blank" rel="noopener" class="mycode_url">https://cheatsheetseries.owasp.org/cheat...Sheet.html</a><br />
</li>
<li><a href="https://www.cisa.gov/news-events/cybersecurity-advisories/aa26-293a" target="_blank" rel="noopener" class="mycode_url">https://www.cisa.gov/news-events/cyberse.../aa26-293a</a><br />
</li>
</ul>
<br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=360" target="_blank" title="">18-k03-deserialization.png</a> (Dosya Boyutu: 121.98 KB / İndirme Sayısı: 11)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[ReDoS Nedir? Evil Regex, Backtracking ve GitLab Regex Açıkları Bağlamı]]></title>
			<link>https://www.turkteam.org/konu-redos-nedir-evil-regex-backtracking-ve-gitlab-regex-aciklari-baglami.html</link>
			<pubDate>Thu, 22 Oct 2026 11:34:41 +0300</pubDate>
			<dc:creator><![CDATA[<a href="https://www.turkteam.org/member.php?action=profile&uid=4">KulTigin</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.turkteam.org/konu-redos-nedir-evil-regex-backtracking-ve-gitlab-regex-aciklari-baglami.html</guid>
			<description><![CDATA[<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=359" loading="lazy"  alt="[Resim: attachment.php?aid=359]" class="mycode_img" /></div>
<br />
Selamlar,<br />
<br />
GitLab'ın bu ay üst üste iki CVSS 10 regex derleyici açığı yayınlaması (CVE-2026-97229 ve CVE-2026-110264) birçok ekibi aynı soruya getirdi: düzenli ifadeler neden bu kadar tehlikeli olabiliyor? GitLab açıkları bellek taşması sınıfındaydı; ama aynı ailede daha yaygın görülen bir kardeş var: <span style="font-weight: bold;" class="mycode_b">ReDoS</span> (Regular Expression Denial of Service). Bu yazıda OWASP'ın ReDoS sayfasına dayanarak evil regex kavramını ve kendi kodunuzda nasıl tarayacağınızı anlatıyorum.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Konuda anlatılacaklar</span></span><br />
<ol type="1" class="mycode_list"><li>Naif regex motoru ve backtracking<br />
</li>
<li>Evil regex nedir?<br />
</li>
<li>Saldırı senaryoları<br />
</li>
<li>Lab ve savunma<br />
</li>
</ol>
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Naif algoritma</span></span><br />
OWASP'a göre birçok regex motoru NFA (Nondeterministic Finite Automaton) kurar ve eşleşme bulunana kadar olası yolları tek tek dener. Girdi eşleşmezse motor önceki konumlara dönüp (backtracking) başka yolları dener. Kötü yazılmış bir desende yol sayısı girdi uzunluğuyla üstel büyür; örneğin ^(a+)+&#36; deseni için aaaaX 16 yol, on altı a içeren girdi 65536 yol üretebilir.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Evil regex</span></span><br />
OWASP, şu özelliklere sahip desenleri "evil" sayar:<ul class="mycode_list"><li>Tekrar içeren gruplama<br />
</li>
<li>Tekrarlanan grubun içinde: tekrar veya örtüşen alternasyon<br />
</li>
</ul>
Örnekler: (a+)+&#36; , ([a-zA-Z]+)*&#36; , (a|aa)+&#36; , (a|a?)+&#36;<br />
Bu desenler aaaaaaaaaaaaaaaaaaaaaaaa! gibi bir girdide motoru uzun süre meşgul edebilir.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Saldırı senaryoları</span></span><ul class="mycode_list"><li>Web uygulamasında kullanıcı girdisinin evil bir regex ile doğrulanması (e-posta, sınıf adı vb.)<br />
</li>
<li>Regex'in kendisinin kullanıcı girdisinden etkilenmesi (regex injection) - OWASP örneğinde kullanıcı adı regex olarak derleniyor<br />
</li>
<li>WAF / tarayıcı / veritabanı katmanındaki regex'lerin hedef alınması<br />
</li>
</ul>
GitLab açıkları ReDoS değil, derleyici tamsayı taşması yoluyla RCE idi; ama ortak ders aynı: kullanıcı kontrolündeki veya karmaşık regex'leri güven sınırı olarak görmeyin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Lab</span></span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Python - kendi labiniz (kisa timeout ile)
import re, time
pat = re.compile(r"(a+)+&#36;")
s = "a" * 28 + "!"
t0 = time.time()
try:
    pat.search(s)
finally:
    print("sure_s:", round(time.time() - t0, 3))</code></div></div>Girdi uzunluğunu artırdıkça sürenin hızla büyüdüğünü görürsünüz. Üretimde böyle bir deseni kullanıcı girdisine uygulamayın.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Savunma</span></span><ul class="mycode_list"><li>Kullanıcı girdisini regex'e gömmeyin; sabit bir desen kullanın.<br />
</li>
<li>Mümkünse doğrulamayı regex yerine parser / allow-list ile yapın.<br />
</li>
<li>Backtracking'siz motorlar veya atomic grouping / possessive quantifier kullanın (dile göre).<br />
</li>
<li>Regex çalıştırırken zaman ve bellek limiti koyun.<br />
</li>
<li>Bağımlılıklarınızda ve WAF kurallarınızda evil regex tarayıcıları (ör. rxxr2, regexploit) çalıştırın.<br />
</li>
</ul>
<br />
Kod tabanınızda kullanıcı girdisinden derlenen regex var mı? Son denetimde ne buldunuz?<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Yasal uyarı</span></span><br />
Bu yazı bilgilendirme ve savunma amaçlıdır. Anlatılan kontrolleri yalnızca kendi sistemlerinizde veya yazılı izinle yapın. İzinsiz erişim, tarama ve sömürü girişimleri TCK 243-245 kapsamında suçtur. TurkTeam white-hat bir topluluktur; çalıntı veri, hesap, combo/log paylaşımı ve hack hizmeti talepleri forum kurallarına aykırıdır.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kaynaklar</span></span><ul class="mycode_list"><li><a href="https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS" target="_blank" rel="noopener" class="mycode_url">https://owasp.org/www-community/attacks/...ce_-_ReDoS</a><br />
</li>
<li><a href="https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-5-1-released/" target="_blank" rel="noopener" class="mycode_url">https://docs.gitlab.com/releases/patches...-released/</a><br />
</li>
</ul>
<br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=359" target="_blank" title="">17-k02-redos.png</a> (Dosya Boyutu: 118.88 KB / İndirme Sayısı: 10)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=359" loading="lazy"  alt="[Resim: attachment.php?aid=359]" class="mycode_img" /></div>
<br />
Selamlar,<br />
<br />
GitLab'ın bu ay üst üste iki CVSS 10 regex derleyici açığı yayınlaması (CVE-2026-97229 ve CVE-2026-110264) birçok ekibi aynı soruya getirdi: düzenli ifadeler neden bu kadar tehlikeli olabiliyor? GitLab açıkları bellek taşması sınıfındaydı; ama aynı ailede daha yaygın görülen bir kardeş var: <span style="font-weight: bold;" class="mycode_b">ReDoS</span> (Regular Expression Denial of Service). Bu yazıda OWASP'ın ReDoS sayfasına dayanarak evil regex kavramını ve kendi kodunuzda nasıl tarayacağınızı anlatıyorum.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Konuda anlatılacaklar</span></span><br />
<ol type="1" class="mycode_list"><li>Naif regex motoru ve backtracking<br />
</li>
<li>Evil regex nedir?<br />
</li>
<li>Saldırı senaryoları<br />
</li>
<li>Lab ve savunma<br />
</li>
</ol>
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Naif algoritma</span></span><br />
OWASP'a göre birçok regex motoru NFA (Nondeterministic Finite Automaton) kurar ve eşleşme bulunana kadar olası yolları tek tek dener. Girdi eşleşmezse motor önceki konumlara dönüp (backtracking) başka yolları dener. Kötü yazılmış bir desende yol sayısı girdi uzunluğuyla üstel büyür; örneğin ^(a+)+&#36; deseni için aaaaX 16 yol, on altı a içeren girdi 65536 yol üretebilir.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Evil regex</span></span><br />
OWASP, şu özelliklere sahip desenleri "evil" sayar:<ul class="mycode_list"><li>Tekrar içeren gruplama<br />
</li>
<li>Tekrarlanan grubun içinde: tekrar veya örtüşen alternasyon<br />
</li>
</ul>
Örnekler: (a+)+&#36; , ([a-zA-Z]+)*&#36; , (a|aa)+&#36; , (a|a?)+&#36;<br />
Bu desenler aaaaaaaaaaaaaaaaaaaaaaaa! gibi bir girdide motoru uzun süre meşgul edebilir.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Saldırı senaryoları</span></span><ul class="mycode_list"><li>Web uygulamasında kullanıcı girdisinin evil bir regex ile doğrulanması (e-posta, sınıf adı vb.)<br />
</li>
<li>Regex'in kendisinin kullanıcı girdisinden etkilenmesi (regex injection) - OWASP örneğinde kullanıcı adı regex olarak derleniyor<br />
</li>
<li>WAF / tarayıcı / veritabanı katmanındaki regex'lerin hedef alınması<br />
</li>
</ul>
GitLab açıkları ReDoS değil, derleyici tamsayı taşması yoluyla RCE idi; ama ortak ders aynı: kullanıcı kontrolündeki veya karmaşık regex'leri güven sınırı olarak görmeyin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Lab</span></span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Python - kendi labiniz (kisa timeout ile)
import re, time
pat = re.compile(r"(a+)+&#36;")
s = "a" * 28 + "!"
t0 = time.time()
try:
    pat.search(s)
finally:
    print("sure_s:", round(time.time() - t0, 3))</code></div></div>Girdi uzunluğunu artırdıkça sürenin hızla büyüdüğünü görürsünüz. Üretimde böyle bir deseni kullanıcı girdisine uygulamayın.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Savunma</span></span><ul class="mycode_list"><li>Kullanıcı girdisini regex'e gömmeyin; sabit bir desen kullanın.<br />
</li>
<li>Mümkünse doğrulamayı regex yerine parser / allow-list ile yapın.<br />
</li>
<li>Backtracking'siz motorlar veya atomic grouping / possessive quantifier kullanın (dile göre).<br />
</li>
<li>Regex çalıştırırken zaman ve bellek limiti koyun.<br />
</li>
<li>Bağımlılıklarınızda ve WAF kurallarınızda evil regex tarayıcıları (ör. rxxr2, regexploit) çalıştırın.<br />
</li>
</ul>
<br />
Kod tabanınızda kullanıcı girdisinden derlenen regex var mı? Son denetimde ne buldunuz?<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Yasal uyarı</span></span><br />
Bu yazı bilgilendirme ve savunma amaçlıdır. Anlatılan kontrolleri yalnızca kendi sistemlerinizde veya yazılı izinle yapın. İzinsiz erişim, tarama ve sömürü girişimleri TCK 243-245 kapsamında suçtur. TurkTeam white-hat bir topluluktur; çalıntı veri, hesap, combo/log paylaşımı ve hack hizmeti talepleri forum kurallarına aykırıdır.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kaynaklar</span></span><ul class="mycode_list"><li><a href="https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS" target="_blank" rel="noopener" class="mycode_url">https://owasp.org/www-community/attacks/...ce_-_ReDoS</a><br />
</li>
<li><a href="https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-5-1-released/" target="_blank" rel="noopener" class="mycode_url">https://docs.gitlab.com/releases/patches...-released/</a><br />
</li>
</ul>
<br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=359" target="_blank" title="">17-k02-redos.png</a> (Dosya Boyutu: 118.88 KB / İndirme Sayısı: 10)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Path Traversal Nedir? Dot-Dot-Slash, Encoding ve Güvenli Dosya Erişimi]]></title>
			<link>https://www.turkteam.org/konu-path-traversal-nedir-dot-dot-slash-encoding-ve-guvenli-dosya-erisimi.html</link>
			<pubDate>Wed, 21 Oct 2026 11:22:47 +0300</pubDate>
			<dc:creator><![CDATA[<a href="https://www.turkteam.org/member.php?action=profile&uid=2">Tonyukuk</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.turkteam.org/konu-path-traversal-nedir-dot-dot-slash-encoding-ve-guvenli-dosya-erisimi.html</guid>
			<description><![CDATA[<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=326" loading="lazy"  alt="[Resim: attachment.php?aid=326]" class="mycode_img" /></div>
<br />
Selam,<br />
<br />
Dosya indirme, şablon yükleme, log görüntüleme... Kullanıcı girdisi dosya yoluna karıştığı anda Path Traversal (directory traversal, CWE-22) kapıda. Bu yazıda saldırı mantığını, encoding oyunlarını ve güvenli deseni kendi labınızda (DVWA / Juice Shop) denenecek şekilde anlatıyorum.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Konuda anlatılacaklar</span></span><br />
<ol type="1" class="mycode_list"><li>Saldırının özü: ../ ve mutlak yol ile web kökü dışına çıkmak<br />
</li>
<li>Encoding / çift encoding / null byte notları<br />
</li>
<li>Kırılgan PHP örneği ve düzeltilmiş desen<br />
</li>
<li>Test checklist (yalnızca izinli lab)<br />
</li>
</ol>
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Klasik kırılgan desen</span></span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&lt;?php
// ZAYIF ÖRNEK - lab dışında kullanmayın
&#36;template = &#36;_GET['file'] ?? 'home.txt';
include("/var/www/templates/" . &#36;template);</code></div></div>İstek: <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>?file=../../../../etc/passwd</code></div></div> — include kökün dışına yürür (izinler elverdiği ölçüde).<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Encoding varyasyonları (OWASP)</span></span><ul class="mycode_list"><li>%2e%2e%2f ve ..%2f → ../<br />
</li>
<li>Windows için ..%5c / %2e%2e%5c<br />
</li>
<li>Çift encoding: %252e%252e%255c<br />
</li>
<li>Eski ortamlar: ..%c0%af gibi overlong UTF-8<br />
</li>
<li>Null byte (eski Java/PHP): secret.doc%00.pdf<br />
</li>
</ul>
Konteyner çoğu zaman bir kez decode eder; uygulamanın ikinci kez decode etmesi filtreyi bypass ettirir.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Nasıl kapatılır?</span></span><ul class="mycode_list"><li>Kullanıcıdan ham yol almayın; kimlik (ID) -&gt; sunucu tarafı eşleme kullanın.<br />
</li>
<li>Girdi allowlist: sadece [a-z0-9._-] ve uzantı beyaz listesi.<br />
</li>
<li>realpath() / Path.GetFullPath sonrası kök dizinin altında mı diye <span style="font-weight: bold;" class="mycode_b">öneki</span> doğrulayın.<br />
</li>
<li>Chroot / ayrı kullanıcı / salt-okunur volume ile blast radius küçültün.<br />
</li>
<li>Hassas dosyaları web köküne koymayın.<br />
</li>
</ul>
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Python güvenli iskelet (fikir)
from pathlib import Path
ROOT = Path("/var/www/templates").resolve()
def open_user_file(name: str) -&gt; Path:
    if "/" in name or "&#92;&#92;" in name or name.startswith("."):
        raise ValueError("invalid")
    p = (ROOT / name).resolve()
    if not str(p).startswith(str(ROOT) + os.sep) and p != ROOT:
        raise ValueError("escape")
    return p</code></div></div><br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Labda test fikri</span></span><br />
DVWA File Inclusion / Juice Shop'ta path ile oynayın. Amacınız /etc/passwd okumak değil; filtrenin nasıl kırıldığını ve doğru düzeltmeyi görmek. Burp Repeater'da encoding matrisini tek tek deneyin, her denemeyi not edin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Yasal uyarı</span></span><br />
Yalnızca sahip olduğunuz veya yazılı izinli sistemlerde test edin. TCK 243-245.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kaynaklar</span></span><ul class="mycode_list"><li><a href="https://owasp.org/www-community/attacks/Path_Traversal" target="_blank" rel="noopener" class="mycode_url">https://owasp.org/www-community/attacks/Path_Traversal</a><br />
</li>
<li><a href="https://cwe.mitre.org/data/definitions/22.html" target="_blank" rel="noopener" class="mycode_url">https://cwe.mitre.org/data/definitions/22.html</a><br />
</li>
</ul>
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">WAF ve ikincil kontroller</span></span><br />
WAF ../ imzaları yardımcı olur ama encoding ile aşılabilir; asıl düzeltme uygulama katmanındadır. Loglarda %2e%2e ve ..\ yoğunluğu erken uyarıdır. SecComp / read-only rootfs konteynerde blast radius'u küçültür.<br />
<br />
<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Uygulamada sık gördüğüm hatalar</span></span><br />
Birçok ekip yamayı "planlandı" diye işaretleyip internete açık yüzeyde günlerce bekletiyor. İkinci sık hata: yalnızca CVE numarasına bakıp zincir etkisini görmemek. Üçüncü hata: yama sonrası log ve dosya bütünlüğüne bakmamak; oysa yama öncesi sömürü olmuş olabilir. Bu üç noktayı kendi kontrol listenize eklemenizi öneririm.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Ekip içi iletişim şablonu</span></span><br />
Yönetime veya müşteriye yazarken teknik jargonu azaltın: hangi varlık etkilendi, internete açık mı, yama var mı, geçici azaltma ne, doğrulama nasıl yapılacak. Tek paragrafta risk + eylem + sahiplik yazmak, uzun CVE özetinden daha hızlı karar aldırır.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Lab not defteri</span></span><br />
Bu konuyu kendi defterime şu başlıklarla işliyorum: tarih, kaynak URL, etkilenen ürün/sürüm, internete açık mı, yama komutu, geri alma planı, IOC listesi, kime haber verildi. Siz de benzer basit bir şablon tutarsanız bir ay sonra "ne yapmıştık?" sorusu cevapsız kalmaz.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">İzleme ve doğrulama</span></span><br />
Değişiklikten sonra en az bir negatif ve bir pozitif kontrol tanımlayın. Negatif: alarm boş yere düşmemeli. Pozitif: bilinen kötü örneği veya beklenen log satırını yakalamalı. İkisini de kaydedin; aksi halde "sanırım düzeldi" ile yetinirsiniz.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Sonuç</span></span><br />
Özetle: kaynağı okuyun, kendi envanterinize bağlayın, yama veya azaltmayı uygulayın, sonra doğrulayın. TurkTeam'de yorumlarda kendi ortamınızdan (ürün adı ve sürüm yeter, hassas IP yazmayın) kısa deneyim paylaşırsanız herkes faydalanır.<br />
<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Adım adım kontrol listesi (kopyala-yapıştır)</span></span><br />
<ol type="1" class="mycode_list"><li>Kaynak duyuruyu ve varsa üretici güvenlik sayfasını arşivleyin (PDF/HTML).<br />
</li>
<li>Envanterde etkilenen ürün var mı diye CMDB / agent raporu / netscan ile bakın.<br />
</li>
<li>İnternete açık mı, yoksa yalnızca iç ağda mı? Buna göre SLA seçin.<br />
</li>
<li>Yama veya yapılandırma azaltmasını stagingde deneyin.<br />
</li>
<li>Üretim penceresinde uygulayın; değişiklik kaydı açın.<br />
</li>
<li>Servis sağlık kontrolü + log doğrulaması yapın.<br />
</li>
<li>Gerekliyse IOC avı veya compromise assessment planlayın.<br />
</li>
<li>Kapanış notunu yazın: sürüm, tarih, kim onayladı.<br />
</li>
</ol>
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Sık sorulanlar</span></span><br />
<span style="font-weight: bold;" class="mycode_b">Sadece okumak yeter mi?</span> Hayır. Okuduktan sonra envanter satırına bağlanmayan bilgi operasyonel değildir.<br />
<span style="font-weight: bold;" class="mycode_b">PoC çalıştırmalı mıyım?</span> Yalnızca izole lab ve yazılı izinle. İnternette rastgele deneme hem etik dışı hem yasadışı olabilir.<br />
<span style="font-weight: bold;" class="mycode_b">WAF / EDR tek başına kurtarır mı?</span> Katmanlı savunma işe yarar ama yamanın yerini tutmaz; özellikle kimlik doğrulamasız RCE sınıflarında.<br />
<span style="font-weight: bold;" class="mycode_b">Ne zaman yönetime çıkmalıyım?</span> İnternete açık kritik yüzey, aktif sömürü istihbaratı veya veri sızıntısı şüphesi varsa gecikmeden.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Örnek komut defteri</span></span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Tarih damgası ve ortam notu
date -Is
hostnamectl 2&gt;/dev/null | head -5 || true
# Ağ dinleme özeti (lab)
ss -lntp | head -30
# Son reboot / güncelleme ipucu (systemd)
who -b 2&gt;/dev/null || true</code></div></div>Bu komutlar tanı koymaz; değişiklik öncesi/sonrası basline almak için kullanın.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">İlgili TurkTeam bölümleri</span></span><br />
Bu yazıyı okuduktan sonra aynı kategorideki komşu konulara ve Soru-Cevap bölümüne kendi lab çıktınızı (hassas veri olmadan) taşıyabilirsiniz. Kısa ekran görüntüsü veya komut çıktısı, uzun teoriden daha çok işe yarar.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kapanış ve yasal çerçeve</span></span><br />
TurkTeam white-hat bir topluluktur. Anlatılan teknikler eğitim, savunma ve izinli test içindir. Başkalarının sistemlerinde izinsiz tarama, sömürü, veri çalma veya "hack hizmeti" sunmak forum kurallarına ve TCK 243, 244, 245 maddelerine aykırıdır. Kendi laboratuvarınızı izolasyonla kurun; üretim verisi kullanmayın. Kaynaklardaki bağlantıları birincil referans kabul edin; bu yazı özet ve yol göstericidir, üretici duyurusunun yerini tutmaz.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kişisel deneyim notu</span></span><br />
Ben benzer konuları işlerken önce resmi duyuruyu iki kez okuyup sonra labda en küçük yeniden üretilebilir adımı arıyorum. Yeniden üretemiyorsam bile envanter ve yama doğrulamasını aynı gün bitirmeye çalışıyorum. Siz de "bugün tek iş" diye bir satır seçin: ya yamayı uygulayın ya da etkilenen varlık olmadığını kanıtlayın. İkisi de geçerli kapanıştır.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Okuma listesi</span></span><ul class="mycode_list"><li>Üretici / araştırmacı birincil yazısı (kaynakçada)<br />
</li>
<li>CISA KEV veya CERT duyurusu varsa o<br />
</li>
<li>Kendi iç runbook'unuzun ilgili maddesi<br />
</li>
</ul>
Üçünden fazlasını aynı anda açmak yerine birini bitirip not alın; aksi halde tab kaybı başlar.<br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=326" target="_blank" title="">09-t09-path-traversal.png</a> (Dosya Boyutu: 115.06 KB / İndirme Sayısı: 8)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=326" loading="lazy"  alt="[Resim: attachment.php?aid=326]" class="mycode_img" /></div>
<br />
Selam,<br />
<br />
Dosya indirme, şablon yükleme, log görüntüleme... Kullanıcı girdisi dosya yoluna karıştığı anda Path Traversal (directory traversal, CWE-22) kapıda. Bu yazıda saldırı mantığını, encoding oyunlarını ve güvenli deseni kendi labınızda (DVWA / Juice Shop) denenecek şekilde anlatıyorum.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Konuda anlatılacaklar</span></span><br />
<ol type="1" class="mycode_list"><li>Saldırının özü: ../ ve mutlak yol ile web kökü dışına çıkmak<br />
</li>
<li>Encoding / çift encoding / null byte notları<br />
</li>
<li>Kırılgan PHP örneği ve düzeltilmiş desen<br />
</li>
<li>Test checklist (yalnızca izinli lab)<br />
</li>
</ol>
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Klasik kırılgan desen</span></span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&lt;?php
// ZAYIF ÖRNEK - lab dışında kullanmayın
&#36;template = &#36;_GET['file'] ?? 'home.txt';
include("/var/www/templates/" . &#36;template);</code></div></div>İstek: <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>?file=../../../../etc/passwd</code></div></div> — include kökün dışına yürür (izinler elverdiği ölçüde).<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Encoding varyasyonları (OWASP)</span></span><ul class="mycode_list"><li>%2e%2e%2f ve ..%2f → ../<br />
</li>
<li>Windows için ..%5c / %2e%2e%5c<br />
</li>
<li>Çift encoding: %252e%252e%255c<br />
</li>
<li>Eski ortamlar: ..%c0%af gibi overlong UTF-8<br />
</li>
<li>Null byte (eski Java/PHP): secret.doc%00.pdf<br />
</li>
</ul>
Konteyner çoğu zaman bir kez decode eder; uygulamanın ikinci kez decode etmesi filtreyi bypass ettirir.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Nasıl kapatılır?</span></span><ul class="mycode_list"><li>Kullanıcıdan ham yol almayın; kimlik (ID) -&gt; sunucu tarafı eşleme kullanın.<br />
</li>
<li>Girdi allowlist: sadece [a-z0-9._-] ve uzantı beyaz listesi.<br />
</li>
<li>realpath() / Path.GetFullPath sonrası kök dizinin altında mı diye <span style="font-weight: bold;" class="mycode_b">öneki</span> doğrulayın.<br />
</li>
<li>Chroot / ayrı kullanıcı / salt-okunur volume ile blast radius küçültün.<br />
</li>
<li>Hassas dosyaları web köküne koymayın.<br />
</li>
</ul>
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Python güvenli iskelet (fikir)
from pathlib import Path
ROOT = Path("/var/www/templates").resolve()
def open_user_file(name: str) -&gt; Path:
    if "/" in name or "&#92;&#92;" in name or name.startswith("."):
        raise ValueError("invalid")
    p = (ROOT / name).resolve()
    if not str(p).startswith(str(ROOT) + os.sep) and p != ROOT:
        raise ValueError("escape")
    return p</code></div></div><br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Labda test fikri</span></span><br />
DVWA File Inclusion / Juice Shop'ta path ile oynayın. Amacınız /etc/passwd okumak değil; filtrenin nasıl kırıldığını ve doğru düzeltmeyi görmek. Burp Repeater'da encoding matrisini tek tek deneyin, her denemeyi not edin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Yasal uyarı</span></span><br />
Yalnızca sahip olduğunuz veya yazılı izinli sistemlerde test edin. TCK 243-245.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kaynaklar</span></span><ul class="mycode_list"><li><a href="https://owasp.org/www-community/attacks/Path_Traversal" target="_blank" rel="noopener" class="mycode_url">https://owasp.org/www-community/attacks/Path_Traversal</a><br />
</li>
<li><a href="https://cwe.mitre.org/data/definitions/22.html" target="_blank" rel="noopener" class="mycode_url">https://cwe.mitre.org/data/definitions/22.html</a><br />
</li>
</ul>
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">WAF ve ikincil kontroller</span></span><br />
WAF ../ imzaları yardımcı olur ama encoding ile aşılabilir; asıl düzeltme uygulama katmanındadır. Loglarda %2e%2e ve ..\ yoğunluğu erken uyarıdır. SecComp / read-only rootfs konteynerde blast radius'u küçültür.<br />
<br />
<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Uygulamada sık gördüğüm hatalar</span></span><br />
Birçok ekip yamayı "planlandı" diye işaretleyip internete açık yüzeyde günlerce bekletiyor. İkinci sık hata: yalnızca CVE numarasına bakıp zincir etkisini görmemek. Üçüncü hata: yama sonrası log ve dosya bütünlüğüne bakmamak; oysa yama öncesi sömürü olmuş olabilir. Bu üç noktayı kendi kontrol listenize eklemenizi öneririm.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Ekip içi iletişim şablonu</span></span><br />
Yönetime veya müşteriye yazarken teknik jargonu azaltın: hangi varlık etkilendi, internete açık mı, yama var mı, geçici azaltma ne, doğrulama nasıl yapılacak. Tek paragrafta risk + eylem + sahiplik yazmak, uzun CVE özetinden daha hızlı karar aldırır.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Lab not defteri</span></span><br />
Bu konuyu kendi defterime şu başlıklarla işliyorum: tarih, kaynak URL, etkilenen ürün/sürüm, internete açık mı, yama komutu, geri alma planı, IOC listesi, kime haber verildi. Siz de benzer basit bir şablon tutarsanız bir ay sonra "ne yapmıştık?" sorusu cevapsız kalmaz.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">İzleme ve doğrulama</span></span><br />
Değişiklikten sonra en az bir negatif ve bir pozitif kontrol tanımlayın. Negatif: alarm boş yere düşmemeli. Pozitif: bilinen kötü örneği veya beklenen log satırını yakalamalı. İkisini de kaydedin; aksi halde "sanırım düzeldi" ile yetinirsiniz.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Sonuç</span></span><br />
Özetle: kaynağı okuyun, kendi envanterinize bağlayın, yama veya azaltmayı uygulayın, sonra doğrulayın. TurkTeam'de yorumlarda kendi ortamınızdan (ürün adı ve sürüm yeter, hassas IP yazmayın) kısa deneyim paylaşırsanız herkes faydalanır.<br />
<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Adım adım kontrol listesi (kopyala-yapıştır)</span></span><br />
<ol type="1" class="mycode_list"><li>Kaynak duyuruyu ve varsa üretici güvenlik sayfasını arşivleyin (PDF/HTML).<br />
</li>
<li>Envanterde etkilenen ürün var mı diye CMDB / agent raporu / netscan ile bakın.<br />
</li>
<li>İnternete açık mı, yoksa yalnızca iç ağda mı? Buna göre SLA seçin.<br />
</li>
<li>Yama veya yapılandırma azaltmasını stagingde deneyin.<br />
</li>
<li>Üretim penceresinde uygulayın; değişiklik kaydı açın.<br />
</li>
<li>Servis sağlık kontrolü + log doğrulaması yapın.<br />
</li>
<li>Gerekliyse IOC avı veya compromise assessment planlayın.<br />
</li>
<li>Kapanış notunu yazın: sürüm, tarih, kim onayladı.<br />
</li>
</ol>
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Sık sorulanlar</span></span><br />
<span style="font-weight: bold;" class="mycode_b">Sadece okumak yeter mi?</span> Hayır. Okuduktan sonra envanter satırına bağlanmayan bilgi operasyonel değildir.<br />
<span style="font-weight: bold;" class="mycode_b">PoC çalıştırmalı mıyım?</span> Yalnızca izole lab ve yazılı izinle. İnternette rastgele deneme hem etik dışı hem yasadışı olabilir.<br />
<span style="font-weight: bold;" class="mycode_b">WAF / EDR tek başına kurtarır mı?</span> Katmanlı savunma işe yarar ama yamanın yerini tutmaz; özellikle kimlik doğrulamasız RCE sınıflarında.<br />
<span style="font-weight: bold;" class="mycode_b">Ne zaman yönetime çıkmalıyım?</span> İnternete açık kritik yüzey, aktif sömürü istihbaratı veya veri sızıntısı şüphesi varsa gecikmeden.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Örnek komut defteri</span></span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Tarih damgası ve ortam notu
date -Is
hostnamectl 2&gt;/dev/null | head -5 || true
# Ağ dinleme özeti (lab)
ss -lntp | head -30
# Son reboot / güncelleme ipucu (systemd)
who -b 2&gt;/dev/null || true</code></div></div>Bu komutlar tanı koymaz; değişiklik öncesi/sonrası basline almak için kullanın.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">İlgili TurkTeam bölümleri</span></span><br />
Bu yazıyı okuduktan sonra aynı kategorideki komşu konulara ve Soru-Cevap bölümüne kendi lab çıktınızı (hassas veri olmadan) taşıyabilirsiniz. Kısa ekran görüntüsü veya komut çıktısı, uzun teoriden daha çok işe yarar.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kapanış ve yasal çerçeve</span></span><br />
TurkTeam white-hat bir topluluktur. Anlatılan teknikler eğitim, savunma ve izinli test içindir. Başkalarının sistemlerinde izinsiz tarama, sömürü, veri çalma veya "hack hizmeti" sunmak forum kurallarına ve TCK 243, 244, 245 maddelerine aykırıdır. Kendi laboratuvarınızı izolasyonla kurun; üretim verisi kullanmayın. Kaynaklardaki bağlantıları birincil referans kabul edin; bu yazı özet ve yol göstericidir, üretici duyurusunun yerini tutmaz.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kişisel deneyim notu</span></span><br />
Ben benzer konuları işlerken önce resmi duyuruyu iki kez okuyup sonra labda en küçük yeniden üretilebilir adımı arıyorum. Yeniden üretemiyorsam bile envanter ve yama doğrulamasını aynı gün bitirmeye çalışıyorum. Siz de "bugün tek iş" diye bir satır seçin: ya yamayı uygulayın ya da etkilenen varlık olmadığını kanıtlayın. İkisi de geçerli kapanıştır.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Okuma listesi</span></span><ul class="mycode_list"><li>Üretici / araştırmacı birincil yazısı (kaynakçada)<br />
</li>
<li>CISA KEV veya CERT duyurusu varsa o<br />
</li>
<li>Kendi iç runbook'unuzun ilgili maddesi<br />
</li>
</ul>
Üçünden fazlasını aynı anda açmak yerine birini bitirip not alın; aksi halde tab kaybı başlar.<br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=326" target="_blank" title="">09-t09-path-traversal.png</a> (Dosya Boyutu: 115.06 KB / İndirme Sayısı: 8)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[İzinli Labda İlk XSS Bulgum: Rapor Şablonu ve Yeniden Üretme Adımları]]></title>
			<link>https://www.turkteam.org/konu-izinli-labda-ilk-xss-bulgum-rapor-sablonu-ve-yeniden-uretme-adimlari.html</link>
			<pubDate>Mon, 19 Oct 2026 02:19:15 +0300</pubDate>
			<dc:creator><![CDATA[<a href="https://www.turkteam.org/member.php?action=profile&uid=2">Tonyukuk</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.turkteam.org/konu-izinli-labda-ilk-xss-bulgum-rapor-sablonu-ve-yeniden-uretme-adimlari.html</guid>
			<description><![CDATA[<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=291" loading="lazy"  alt="[Resim: attachment.php?aid=291]" class="mycode_img" /></div>
<br />
Selam,<br />
<br />
İlk XSS bulgunuzu labda yeniden üretebilmek ve düzgün raporlamak, bug bounty / pentest hayatında altın değerinde. Bu yazıda izinli labda (DVWA) bulduğum reflected XSS örneğini nasıl yazdığımı ve şablonumu paylaşıyorum. Gerçek müşteri verisi yok.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Yeniden üretme adımları (net olsun)</span></span><br />
<ol type="1" class="mycode_list"><li>Ortam: DVWA, security low, Firefox, Burp<br />
</li>
<li>Giriş: /dvwa/vulnerabilities/xss_r/<br />
</li>
<li>Payload (eğitim): <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&lt;script&gt;alert(1)&lt;/script&gt;</code></div></div></li>
<li>Gözlenen: sayfada alert kutusu, yanıtta encode edilmeden dönen girdi<br />
</li>
</ol>
Ekran görüntüsü + HTTP request/response ekleyin. "alert çıktı" tek başına zayıf rapordur.<br />
<br />
<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=292" loading="lazy"  alt="[Resim: attachment.php?aid=292]" class="mycode_img" /></div>
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Rapor şablonu</span></span><br />
<span style="font-weight: bold;" class="mycode_b">Başlık:</span> Reflected XSS in /vulnerabilities/xss_r/ (name parameter)<br />
<span style="font-weight: bold;" class="mycode_b">Özet:</span> name parametresi HTML bağlamında encode edilmeden yansıtılıyor; saldırganın JavaScript çalıştırmasına izin veriyor.<br />
<span style="font-weight: bold;" class="mycode_b">Etki:</span> Oturum çerezi hırsızlığı (HttpOnly yoksa), phishing, CSRF ile zincir.<br />
<span style="font-weight: bold;" class="mycode_b">Adımlar:</span> numaralı, kopyala-yapıştır URL/payload.<br />
<span style="font-weight: bold;" class="mycode_b">Kanıt:</span> request, response snippet, screenshot.<br />
<span style="font-weight: bold;" class="mycode_b">Düzeltme:</span> bağlamına uygun encode (OWASP Cheat Sheet), CSP, cookie bayrakları.<br />
<span style="font-weight: bold;" class="mycode_b">CVSS:</span> ortamınıza göre; labda eğitim amaçlı "Medium" örneği verebilirsiniz ama metodolojiyi yazın.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kaliteli rapor alışkanlıkları</span></span><ul class="mycode_list"><li>En kısa çalışan payload + alternatif vektör<br />
</li>
<li>Self-XSS ile reflected/stored ayrımını netleştirin<br />
</li>
<li>WAF bypass hikâyesi uydurmayın; kanıtlayın<br />
</li>
<li>PII / gerçek kullanıcı verisi eklemeyin<br />
</li>
</ul>
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Düzeltme tarafı (geliştiriciye not)</span></span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Örnek düşünce (dil bağımsız):
# HTML context -&gt; entity encode
# JS context -&gt; JSON encode / güvenli API
# URL context -&gt; URL encode</code></div></div>CSP ek katmandır; tek başına input encode yerine geçmez.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kaynaklar</span></span><ul class="mycode_list"><li>OWASP XSS Prevention Cheat Sheet<br />
</li>
<li>PortSwigger XSS lab'ları<br />
</li>
<li>CWE-79<br />
</li>
</ul>
<br />
İlk raporunuz reddedildiyse gerekçe neydi? "Etki yok" cevabına karşı nasıl revize ettiniz?<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Etkiyi abartmadan yazmak</span></span><br />
alert(1) kanıtı teknik doğrulamadır; iş etkisi için cookie HttpOnly mı, CSP var mı, oturum cookie'si hangi path'te yazın. "Hesap ele geçirme" iddiası için gerçekçi zincir gerekir. Triager abartıyı görünce güven kaybeder.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Stored XSS farkı</span></span><br />
Kayıtlı (stored) XSS'te payload'ın nerede saklandığını ve kimlerin gördüğünü yazın. Admin panelinde stored XSS genelde reflected'dan yüksek etki taşır; yine kanıtla.<br />
<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Doğrulama senaryosu</span></span><br />
Bu konuyla ilgili ek bir kontrol: değişikliği yaptıktan sonra en az bir negatif test ve bir pozitif test tanımlayın. Negatif test 'alarm boşyere düşmemeli', pozitif test 'bilinen kötü örneği yakalamalı' der. İkisini de kaydedin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Lab disiplini</span></span><br />
Ortamlar arasında (lab, staging, production) aynı yapılandırmayı kör kopyalamayın. Adresler, sertifikalar ve kimlikler farklıdır. Şablon kullanın, değerleri envanterden doldurun.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Runbook'a taşımak</span></span><br />
İlgili log ve kanıtları olaydan sonra en az kurum politikasının öngördüğü süre kadar saklayın. Disk dolunca en eski güvenlik logunu silmek klasik hatadır; ayrı retention politikası tanımlayın.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Ölçüm ve alarm sağlığı</span></span><br />
Yanlış pozitifleri susturmak ile körleşmek arasındaki çizgi incedir. Suppress kuralına gerekçe ve gözden geçirme tarihi yazın. Süresi dolunca yeniden değerlendirin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kapsam ve izin hatırlatması</span></span><br />
Bu adımları change ticket olmadan production'da uygulamayın. Küçük görünen bir audit ayarı bile uygulama uyumluluğunu bozabilir. Önce staging, sonra kontrollü yayılım.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Yedekleme ve geri dönüş</span></span><br />
Yılda en az iki kez masabaşı tatbikatı yapın: 'bu kontrol kırılırsa kim fark eder?' sorusunu sorunsuz cevaplayabilmelisiniz. Tatbikat notlarını wiki'ye ekleyin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Log saklama süresi</span></span><br />
Araç çıktısını ekran görüntüsü olarak bırakmak yerine makinece okunur formatta (JSON/CSV) arşivleyin. İki yıl sonraki denetimde arama kolaylaşır.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Yanlış pozitif yönetimi</span></span><br />
Yetki ayrımı: bu kontrolü yapılandıran kişi ile alarmı triaj eden kişi mümkünse farklı olsun. Küçük ekiplerde olmasa bile en azından farklı hesap kullanın.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Değişiklik yönetimi ile ilişki</span></span><br />
Sürüüm yükseltmelerinden sonra regresyon testi yapın. 'Aynı config' yeni sürümde farklı varsayılanlara bağlanmış olabilir. Release note'daki breaking change bölümünü okuyun.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Eğitim tatbikatı</span></span><br />
Dış bağımlılık (feed, imza seti, konteyner imajı) için bütünlük doğrulaması yapın. İmzasız feed ile gelen kural seti tedarik zinciri riskidir.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Doğrulama senaryosu</span></span><br />
Bu konuyla ilgili ek bir kontrol: değişikliği yaptıktan sonra en az bir negatif test ve bir pozitif test tanımlayın. Negatif test 'alarm boşyere düşmemeli', pozitif test 'bilinen kötü örneği yakalamalı' der. İkisini de kaydedin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Lab disiplini</span></span><br />
Ortamlar arasında (lab, staging, production) aynı yapılandırmayı kör kopyalamayın. Adresler, sertifikalar ve kimlikler farklıdır. Şablon kullanın, değerleri envanterden doldurun.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Runbook'a taşımak</span></span><br />
İlgili log ve kanıtları olaydan sonra en az kurum politikasının öngördüğü süre kadar saklayın. Disk dolunca en eski güvenlik logunu silmek klasik hatadır; ayrı retention politikası tanımlayın.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Ölçüm ve alarm sağlığı</span></span><br />
Yanlış pozitifleri susturmak ile körleşmek arasındaki çizgi incedir. Suppress kuralına gerekçe ve gözden geçirme tarihi yazın. Süresi dolunca yeniden değerlendirin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kapsam ve izin hatırlatması</span></span><br />
Bu adımları change ticket olmadan production'da uygulamayın. Küçük görünen bir audit ayarı bile uygulama uyumluluğunu bozabilir. Önce staging, sonra kontrollü yayılım.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Yedekleme ve geri dönüş</span></span><br />
Yılda en az iki kez masabaşı tatbikatı yapın: 'bu kontrol kırılırsa kim fark eder?' sorusunu sorunsuz cevaplayabilmelisiniz. Tatbikat notlarını wiki'ye ekleyin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Log saklama süresi</span></span><br />
Araç çıktısını ekran görüntüsü olarak bırakmak yerine makinece okunur formatta (JSON/CSV) arşivleyin. İki yıl sonraki denetimde arama kolaylaşır.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Yanlış pozitif yönetimi</span></span><br />
Yetki ayrımı: bu kontrolü yapılandıran kişi ile alarmı triaj eden kişi mümkünse farklı olsun. Küçük ekiplerde olmasa bile en azından farklı hesap kullanın.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Değişiklik yönetimi ile ilişki</span></span><br />
Sürüüm yükseltmelerinden sonra regresyon testi yapın. 'Aynı config' yeni sürümde farklı varsayılanlara bağlanmış olabilir. Release note'daki breaking change bölümünü okuyun.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Eğitim tatbikatı</span></span><br />
Dış bağımlılık (feed, imza seti, konteyner imajı) için bütünlük doğrulaması yapın. İmzasız feed ile gelen kural seti tedarik zinciri riskidir.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Uygulama notu</span></span><br />
Bu rehberdeki komutları olduğu gibi kopyalamadan önce yolları, arayüz adlarını ve IP adreslerini kendi ortamınıza göre değiştirin. Dağıtım farkları (Debian/Ubuntu/RHEL/Windows sunucu) çıktı biçimini değiştirebilir; man sayfası ve resmi dokümantasyon birincil kaynaktır. Bir adım beklediğiniz sonucu vermezse önce yetki (sudo/Administrator), sonra sürüm, en son da yapılandırma dosyası sırasıyla bakın. Değişiklikleri geri almak için snapshot veya yapılandırma yönetimi (Ansible/Git) kullanın; 'elle bir dokundum' geçmişi denetimde kaybolur. Alarm ve log örneklerini ekip kanalında paylaşırken kişisel veri ve iç IP şemasını maskeleyin.<br />
<span style="font-style: italic;" class="mycode_i">Yasal uyarı: Bu içerik eğitim amaçlıdır. Anlatılanları yalnızca kendi sistemlerinizde veya yazılı izin aldığınız sistemlerde uygulayın. Yetkisiz erişim ve sistemlere müdahale 5237 sayılı TCK'nın 243, 244 ve 245. maddeleri kapsamında suçtur.</span><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=291" target="_blank" title="">100-n21-fec995.png</a> (Dosya Boyutu: 65.51 KB / İndirme Sayısı: 13)
<!-- end: postbit_attachments_attachment --><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=292" target="_blank" title="">n21-inner.png</a> (Dosya Boyutu: 19.74 KB / İndirme Sayısı: 12)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=291" loading="lazy"  alt="[Resim: attachment.php?aid=291]" class="mycode_img" /></div>
<br />
Selam,<br />
<br />
İlk XSS bulgunuzu labda yeniden üretebilmek ve düzgün raporlamak, bug bounty / pentest hayatında altın değerinde. Bu yazıda izinli labda (DVWA) bulduğum reflected XSS örneğini nasıl yazdığımı ve şablonumu paylaşıyorum. Gerçek müşteri verisi yok.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Yeniden üretme adımları (net olsun)</span></span><br />
<ol type="1" class="mycode_list"><li>Ortam: DVWA, security low, Firefox, Burp<br />
</li>
<li>Giriş: /dvwa/vulnerabilities/xss_r/<br />
</li>
<li>Payload (eğitim): <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&lt;script&gt;alert(1)&lt;/script&gt;</code></div></div></li>
<li>Gözlenen: sayfada alert kutusu, yanıtta encode edilmeden dönen girdi<br />
</li>
</ol>
Ekran görüntüsü + HTTP request/response ekleyin. "alert çıktı" tek başına zayıf rapordur.<br />
<br />
<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=292" loading="lazy"  alt="[Resim: attachment.php?aid=292]" class="mycode_img" /></div>
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Rapor şablonu</span></span><br />
<span style="font-weight: bold;" class="mycode_b">Başlık:</span> Reflected XSS in /vulnerabilities/xss_r/ (name parameter)<br />
<span style="font-weight: bold;" class="mycode_b">Özet:</span> name parametresi HTML bağlamında encode edilmeden yansıtılıyor; saldırganın JavaScript çalıştırmasına izin veriyor.<br />
<span style="font-weight: bold;" class="mycode_b">Etki:</span> Oturum çerezi hırsızlığı (HttpOnly yoksa), phishing, CSRF ile zincir.<br />
<span style="font-weight: bold;" class="mycode_b">Adımlar:</span> numaralı, kopyala-yapıştır URL/payload.<br />
<span style="font-weight: bold;" class="mycode_b">Kanıt:</span> request, response snippet, screenshot.<br />
<span style="font-weight: bold;" class="mycode_b">Düzeltme:</span> bağlamına uygun encode (OWASP Cheat Sheet), CSP, cookie bayrakları.<br />
<span style="font-weight: bold;" class="mycode_b">CVSS:</span> ortamınıza göre; labda eğitim amaçlı "Medium" örneği verebilirsiniz ama metodolojiyi yazın.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kaliteli rapor alışkanlıkları</span></span><ul class="mycode_list"><li>En kısa çalışan payload + alternatif vektör<br />
</li>
<li>Self-XSS ile reflected/stored ayrımını netleştirin<br />
</li>
<li>WAF bypass hikâyesi uydurmayın; kanıtlayın<br />
</li>
<li>PII / gerçek kullanıcı verisi eklemeyin<br />
</li>
</ul>
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Düzeltme tarafı (geliştiriciye not)</span></span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Örnek düşünce (dil bağımsız):
# HTML context -&gt; entity encode
# JS context -&gt; JSON encode / güvenli API
# URL context -&gt; URL encode</code></div></div>CSP ek katmandır; tek başına input encode yerine geçmez.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kaynaklar</span></span><ul class="mycode_list"><li>OWASP XSS Prevention Cheat Sheet<br />
</li>
<li>PortSwigger XSS lab'ları<br />
</li>
<li>CWE-79<br />
</li>
</ul>
<br />
İlk raporunuz reddedildiyse gerekçe neydi? "Etki yok" cevabına karşı nasıl revize ettiniz?<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Etkiyi abartmadan yazmak</span></span><br />
alert(1) kanıtı teknik doğrulamadır; iş etkisi için cookie HttpOnly mı, CSP var mı, oturum cookie'si hangi path'te yazın. "Hesap ele geçirme" iddiası için gerçekçi zincir gerekir. Triager abartıyı görünce güven kaybeder.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Stored XSS farkı</span></span><br />
Kayıtlı (stored) XSS'te payload'ın nerede saklandığını ve kimlerin gördüğünü yazın. Admin panelinde stored XSS genelde reflected'dan yüksek etki taşır; yine kanıtla.<br />
<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Doğrulama senaryosu</span></span><br />
Bu konuyla ilgili ek bir kontrol: değişikliği yaptıktan sonra en az bir negatif test ve bir pozitif test tanımlayın. Negatif test 'alarm boşyere düşmemeli', pozitif test 'bilinen kötü örneği yakalamalı' der. İkisini de kaydedin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Lab disiplini</span></span><br />
Ortamlar arasında (lab, staging, production) aynı yapılandırmayı kör kopyalamayın. Adresler, sertifikalar ve kimlikler farklıdır. Şablon kullanın, değerleri envanterden doldurun.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Runbook'a taşımak</span></span><br />
İlgili log ve kanıtları olaydan sonra en az kurum politikasının öngördüğü süre kadar saklayın. Disk dolunca en eski güvenlik logunu silmek klasik hatadır; ayrı retention politikası tanımlayın.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Ölçüm ve alarm sağlığı</span></span><br />
Yanlış pozitifleri susturmak ile körleşmek arasındaki çizgi incedir. Suppress kuralına gerekçe ve gözden geçirme tarihi yazın. Süresi dolunca yeniden değerlendirin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kapsam ve izin hatırlatması</span></span><br />
Bu adımları change ticket olmadan production'da uygulamayın. Küçük görünen bir audit ayarı bile uygulama uyumluluğunu bozabilir. Önce staging, sonra kontrollü yayılım.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Yedekleme ve geri dönüş</span></span><br />
Yılda en az iki kez masabaşı tatbikatı yapın: 'bu kontrol kırılırsa kim fark eder?' sorusunu sorunsuz cevaplayabilmelisiniz. Tatbikat notlarını wiki'ye ekleyin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Log saklama süresi</span></span><br />
Araç çıktısını ekran görüntüsü olarak bırakmak yerine makinece okunur formatta (JSON/CSV) arşivleyin. İki yıl sonraki denetimde arama kolaylaşır.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Yanlış pozitif yönetimi</span></span><br />
Yetki ayrımı: bu kontrolü yapılandıran kişi ile alarmı triaj eden kişi mümkünse farklı olsun. Küçük ekiplerde olmasa bile en azından farklı hesap kullanın.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Değişiklik yönetimi ile ilişki</span></span><br />
Sürüüm yükseltmelerinden sonra regresyon testi yapın. 'Aynı config' yeni sürümde farklı varsayılanlara bağlanmış olabilir. Release note'daki breaking change bölümünü okuyun.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Eğitim tatbikatı</span></span><br />
Dış bağımlılık (feed, imza seti, konteyner imajı) için bütünlük doğrulaması yapın. İmzasız feed ile gelen kural seti tedarik zinciri riskidir.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Doğrulama senaryosu</span></span><br />
Bu konuyla ilgili ek bir kontrol: değişikliği yaptıktan sonra en az bir negatif test ve bir pozitif test tanımlayın. Negatif test 'alarm boşyere düşmemeli', pozitif test 'bilinen kötü örneği yakalamalı' der. İkisini de kaydedin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Lab disiplini</span></span><br />
Ortamlar arasında (lab, staging, production) aynı yapılandırmayı kör kopyalamayın. Adresler, sertifikalar ve kimlikler farklıdır. Şablon kullanın, değerleri envanterden doldurun.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Runbook'a taşımak</span></span><br />
İlgili log ve kanıtları olaydan sonra en az kurum politikasının öngördüğü süre kadar saklayın. Disk dolunca en eski güvenlik logunu silmek klasik hatadır; ayrı retention politikası tanımlayın.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Ölçüm ve alarm sağlığı</span></span><br />
Yanlış pozitifleri susturmak ile körleşmek arasındaki çizgi incedir. Suppress kuralına gerekçe ve gözden geçirme tarihi yazın. Süresi dolunca yeniden değerlendirin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kapsam ve izin hatırlatması</span></span><br />
Bu adımları change ticket olmadan production'da uygulamayın. Küçük görünen bir audit ayarı bile uygulama uyumluluğunu bozabilir. Önce staging, sonra kontrollü yayılım.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Yedekleme ve geri dönüş</span></span><br />
Yılda en az iki kez masabaşı tatbikatı yapın: 'bu kontrol kırılırsa kim fark eder?' sorusunu sorunsuz cevaplayabilmelisiniz. Tatbikat notlarını wiki'ye ekleyin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Log saklama süresi</span></span><br />
Araç çıktısını ekran görüntüsü olarak bırakmak yerine makinece okunur formatta (JSON/CSV) arşivleyin. İki yıl sonraki denetimde arama kolaylaşır.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Yanlış pozitif yönetimi</span></span><br />
Yetki ayrımı: bu kontrolü yapılandıran kişi ile alarmı triaj eden kişi mümkünse farklı olsun. Küçük ekiplerde olmasa bile en azından farklı hesap kullanın.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Değişiklik yönetimi ile ilişki</span></span><br />
Sürüüm yükseltmelerinden sonra regresyon testi yapın. 'Aynı config' yeni sürümde farklı varsayılanlara bağlanmış olabilir. Release note'daki breaking change bölümünü okuyun.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Eğitim tatbikatı</span></span><br />
Dış bağımlılık (feed, imza seti, konteyner imajı) için bütünlük doğrulaması yapın. İmzasız feed ile gelen kural seti tedarik zinciri riskidir.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Uygulama notu</span></span><br />
Bu rehberdeki komutları olduğu gibi kopyalamadan önce yolları, arayüz adlarını ve IP adreslerini kendi ortamınıza göre değiştirin. Dağıtım farkları (Debian/Ubuntu/RHEL/Windows sunucu) çıktı biçimini değiştirebilir; man sayfası ve resmi dokümantasyon birincil kaynaktır. Bir adım beklediğiniz sonucu vermezse önce yetki (sudo/Administrator), sonra sürüm, en son da yapılandırma dosyası sırasıyla bakın. Değişiklikleri geri almak için snapshot veya yapılandırma yönetimi (Ansible/Git) kullanın; 'elle bir dokundum' geçmişi denetimde kaybolur. Alarm ve log örneklerini ekip kanalında paylaşırken kişisel veri ve iç IP şemasını maskeleyin.<br />
<span style="font-style: italic;" class="mycode_i">Yasal uyarı: Bu içerik eğitim amaçlıdır. Anlatılanları yalnızca kendi sistemlerinizde veya yazılı izin aldığınız sistemlerde uygulayın. Yetkisiz erişim ve sistemlere müdahale 5237 sayılı TCK'nın 243, 244 ve 245. maddeleri kapsamında suçtur.</span><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=291" target="_blank" title="">100-n21-fec995.png</a> (Dosya Boyutu: 65.51 KB / İndirme Sayısı: 13)
<!-- end: postbit_attachments_attachment --><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=292" target="_blank" title="">n21-inner.png</a> (Dosya Boyutu: 19.74 KB / İndirme Sayısı: 12)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Burp Intruder ile Labda Parametre Fuzzing: Payload Tipleri ve Örnekler]]></title>
			<link>https://www.turkteam.org/konu-burp-intruder-ile-labda-parametre-fuzzing-payload-tipleri-ve-ornekler.html</link>
			<pubDate>Mon, 19 Oct 2026 01:55:19 +0300</pubDate>
			<dc:creator><![CDATA[<a href="https://www.turkteam.org/member.php?action=profile&uid=2">Tonyukuk</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.turkteam.org/konu-burp-intruder-ile-labda-parametre-fuzzing-payload-tipleri-ve-ornekler.html</guid>
			<description><![CDATA[<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=289" loading="lazy"  alt="[Resim: attachment.php?aid=289]" class="mycode_img" /></div>
<br />
Merhaba,<br />
<br />
Burp Suite Intruder, labda parametre fuzzing için hâlâ en hızlı yollardan biri. Bu yazıda DVWA / Juice Shop labımda Intruder'ı nasıl kullandığımı, payload tiplerini ve rate limit nezaketini anlatıyorum. Yalnızca izinli hedefler.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Hazırlık</span></span><br />
<ol type="1" class="mycode_list"><li>Proxy açık, lab trafiği Burp'tan geçiyor<br />
</li>
<li>Hedef HTTP history'den Intruder'a Send<br />
</li>
<li>Attack type seçimi: Sniper, Battering ram, Pitchfork, Cluster bomb<br />
</li>
</ol>
Tek parametre için Sniper yeter. İki parametreyi birlikte denemek için Pitchfork (eşleşmeli) veya Cluster bomb (kartezyen; patlar, dikkat).<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">İşaretleme</span></span><br />
Payload Positions'ta fuzz edilecek değeri § ile işaretleyin. Örnek: id=§1§. JSON body'de de aynı mantık.<br />
<br />
<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=290" loading="lazy"  alt="[Resim: attachment.php?aid=290]" class="mycode_img" /></div>
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Payload tipleri</span></span><ul class="mycode_list"><li>Simple list: kendi wordlist'iniz<br />
</li>
<li>Numbers: 1..1000 (IDOR avı)<br />
</li>
<li>Runtime file: büyük listeler<br />
</li>
<li>Grep / regex extract ile zincirleme (ileri)<br />
</li>
</ul>
IDOR lab örneği:<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Payload: Numbers 1-200
# Grep match: "email" veya "Welcome"
# Length / status code farkına bak</code></div></div><br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Sonuçları okumak</span></span><br />
Status, Length, Words, Grep Match sütunları. Anormal uzunluk = farklı yetki seviyesi veya hata mesajı sızıntısı olabilir. Response'u elle doğrulamadan "bug" demeyin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Nezaket ve güvenlik</span></span><ul class="mycode_list"><li>Resource Pool / Delay ile saniyede istek sayısını düşürün<br />
</li>
<li>Production bug bounty'de program kurallarındaki rate limit'e uyun<br />
</li>
<li>Login formunda brute force Intruder = çoğu programda yasak<br />
</li>
<li>Oturum çerezini öldürmemek için attack sırasında cookie jar'ı bilinçli yönetin<br />
</li>
</ul>
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Intruder vs ffuf</span></span><br />
Intruder GUI ve tarayıcı akışıyla entegre; ffuf hız ve CLI otomasyonunda önde. Ben keşifte ffuf, oturumlu iş mantığında Intruder kullanıyorum.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kaynaklar</span></span><ul class="mycode_list"><li>PortSwigger Web Security Academy - Burp Intruder<br />
</li>
<li>OWASP Testing Guide<br />
</li>
<li>DVWA / OWASP Juice Shop (yasal lab)<br />
</li>
</ul>
<br />
Siz Cluster bomb'u gerçekten ne zaman kullanıyorsunuz? Ben çoğu senaryoda Pitchfork + manuel ile yetiniyorum.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Grep extract ile zincir</span></span><br />
Önceki yanıttan CSRF token çekip sonraki isteğe yerleştirmek Intruder/macros ile yapılır. Labda login + fuzz akışını kaydedin. Session handling rule ile cookie yenilemek, uzun fuzz sırasında 401 yağmurunu keser.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Payload set hijyeni</span></span><br />
Başkasının "100MB xss.txt" listesini körlemesine kullanmayın; labda önce 50 satırlık hedefli liste. Production bounty'de aynı kural: kalite &gt; megabayt.<br />
<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Doğrulama senaryosu</span></span><br />
Bu konuyla ilgili ek bir kontrol: değişikliği yaptıktan sonra en az bir negatif test ve bir pozitif test tanımlayın. Negatif test 'alarm boşyere düşmemeli', pozitif test 'bilinen kötü örneği yakalamalı' der. İkisini de kaydedin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Lab disiplini</span></span><br />
Ortamlar arasında (lab, staging, production) aynı yapılandırmayı kör kopyalamayın. Adresler, sertifikalar ve kimlikler farklıdır. Şablon kullanın, değerleri envanterden doldurun.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Runbook'a taşımak</span></span><br />
İlgili log ve kanıtları olaydan sonra en az kurum politikasının öngördüğü süre kadar saklayın. Disk dolunca en eski güvenlik logunu silmek klasik hatadır; ayrı retention politikası tanımlayın.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Ölçüm ve alarm sağlığı</span></span><br />
Yanlış pozitifleri susturmak ile körleşmek arasındaki çizgi incedir. Suppress kuralına gerekçe ve gözden geçirme tarihi yazın. Süresi dolunca yeniden değerlendirin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kapsam ve izin hatırlatması</span></span><br />
Bu adımları change ticket olmadan production'da uygulamayın. Küçük görünen bir audit ayarı bile uygulama uyumluluğunu bozabilir. Önce staging, sonra kontrollü yayılım.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Yedekleme ve geri dönüş</span></span><br />
Yılda en az iki kez masabaşı tatbikatı yapın: 'bu kontrol kırılırsa kim fark eder?' sorusunu sorunsuz cevaplayabilmelisiniz. Tatbikat notlarını wiki'ye ekleyin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Log saklama süresi</span></span><br />
Araç çıktısını ekran görüntüsü olarak bırakmak yerine makinece okunur formatta (JSON/CSV) arşivleyin. İki yıl sonraki denetimde arama kolaylaşır.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Yanlış pozitif yönetimi</span></span><br />
Yetki ayrımı: bu kontrolü yapılandıran kişi ile alarmı triaj eden kişi mümkünse farklı olsun. Küçük ekiplerde olmasa bile en azından farklı hesap kullanın.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Değişiklik yönetimi ile ilişki</span></span><br />
Sürüüm yükseltmelerinden sonra regresyon testi yapın. 'Aynı config' yeni sürümde farklı varsayılanlara bağlanmış olabilir. Release note'daki breaking change bölümünü okuyun.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Eğitim tatbikatı</span></span><br />
Dış bağımlılık (feed, imza seti, konteyner imajı) için bütünlük doğrulaması yapın. İmzasız feed ile gelen kural seti tedarik zinciri riskidir.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Doğrulama senaryosu</span></span><br />
Bu konuyla ilgili ek bir kontrol: değişikliği yaptıktan sonra en az bir negatif test ve bir pozitif test tanımlayın. Negatif test 'alarm boşyere düşmemeli', pozitif test 'bilinen kötü örneği yakalamalı' der. İkisini de kaydedin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Lab disiplini</span></span><br />
Ortamlar arasında (lab, staging, production) aynı yapılandırmayı kör kopyalamayın. Adresler, sertifikalar ve kimlikler farklıdır. Şablon kullanın, değerleri envanterden doldurun.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Runbook'a taşımak</span></span><br />
İlgili log ve kanıtları olaydan sonra en az kurum politikasının öngördüğü süre kadar saklayın. Disk dolunca en eski güvenlik logunu silmek klasik hatadır; ayrı retention politikası tanımlayın.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Ölçüm ve alarm sağlığı</span></span><br />
Yanlış pozitifleri susturmak ile körleşmek arasındaki çizgi incedir. Suppress kuralına gerekçe ve gözden geçirme tarihi yazın. Süresi dolunca yeniden değerlendirin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kapsam ve izin hatırlatması</span></span><br />
Bu adımları change ticket olmadan production'da uygulamayın. Küçük görünen bir audit ayarı bile uygulama uyumluluğunu bozabilir. Önce staging, sonra kontrollü yayılım.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Yedekleme ve geri dönüş</span></span><br />
Yılda en az iki kez masabaşı tatbikatı yapın: 'bu kontrol kırılırsa kim fark eder?' sorusunu sorunsuz cevaplayabilmelisiniz. Tatbikat notlarını wiki'ye ekleyin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Log saklama süresi</span></span><br />
Araç çıktısını ekran görüntüsü olarak bırakmak yerine makinece okunur formatta (JSON/CSV) arşivleyin. İki yıl sonraki denetimde arama kolaylaşır.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Yanlış pozitif yönetimi</span></span><br />
Yetki ayrımı: bu kontrolü yapılandıran kişi ile alarmı triaj eden kişi mümkünse farklı olsun. Küçük ekiplerde olmasa bile en azından farklı hesap kullanın.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Değişiklik yönetimi ile ilişki</span></span><br />
Sürüüm yükseltmelerinden sonra regresyon testi yapın. 'Aynı config' yeni sürümde farklı varsayılanlara bağlanmış olabilir. Release note'daki breaking change bölümünü okuyun.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Uygulama notu</span></span><br />
Bu rehberdeki komutları olduğu gibi kopyalamadan önce yolları, arayüz adlarını ve IP adreslerini kendi ortamınıza göre değiştirin. Dağıtım farkları (Debian/Ubuntu/RHEL/Windows sunucu) çıktı biçimini değiştirebilir; man sayfası ve resmi dokümantasyon birincil kaynaktır. Bir adım beklediğiniz sonucu vermezse önce yetki (sudo/Administrator), sonra sürüm, en son da yapılandırma dosyası sırasıyla bakın. Değişiklikleri geri almak için snapshot veya yapılandırma yönetimi (Ansible/Git) kullanın; 'elle bir dokundum' geçmişi denetimde kaybolur. Alarm ve log örneklerini ekip kanalında paylaşırken kişisel veri ve iç IP şemasını maskeleyin.<br />
<span style="font-style: italic;" class="mycode_i">Yasal uyarı: Bu içerik eğitim amaçlıdır. Anlatılanları yalnızca kendi sistemlerinizde veya yazılı izin aldığınız sistemlerde uygulayın. Yetkisiz erişim ve sistemlere müdahale 5237 sayılı TCK'nın 243, 244 ve 245. maddeleri kapsamında suçtur.</span><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=289" target="_blank" title="">100-n20-0dfa17.png</a> (Dosya Boyutu: 63.1 KB / İndirme Sayısı: 14)
<!-- end: postbit_attachments_attachment --><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=290" target="_blank" title="">n20-inner.png</a> (Dosya Boyutu: 20.26 KB / İndirme Sayısı: 17)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=289" loading="lazy"  alt="[Resim: attachment.php?aid=289]" class="mycode_img" /></div>
<br />
Merhaba,<br />
<br />
Burp Suite Intruder, labda parametre fuzzing için hâlâ en hızlı yollardan biri. Bu yazıda DVWA / Juice Shop labımda Intruder'ı nasıl kullandığımı, payload tiplerini ve rate limit nezaketini anlatıyorum. Yalnızca izinli hedefler.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Hazırlık</span></span><br />
<ol type="1" class="mycode_list"><li>Proxy açık, lab trafiği Burp'tan geçiyor<br />
</li>
<li>Hedef HTTP history'den Intruder'a Send<br />
</li>
<li>Attack type seçimi: Sniper, Battering ram, Pitchfork, Cluster bomb<br />
</li>
</ol>
Tek parametre için Sniper yeter. İki parametreyi birlikte denemek için Pitchfork (eşleşmeli) veya Cluster bomb (kartezyen; patlar, dikkat).<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">İşaretleme</span></span><br />
Payload Positions'ta fuzz edilecek değeri § ile işaretleyin. Örnek: id=§1§. JSON body'de de aynı mantık.<br />
<br />
<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=290" loading="lazy"  alt="[Resim: attachment.php?aid=290]" class="mycode_img" /></div>
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Payload tipleri</span></span><ul class="mycode_list"><li>Simple list: kendi wordlist'iniz<br />
</li>
<li>Numbers: 1..1000 (IDOR avı)<br />
</li>
<li>Runtime file: büyük listeler<br />
</li>
<li>Grep / regex extract ile zincirleme (ileri)<br />
</li>
</ul>
IDOR lab örneği:<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Payload: Numbers 1-200
# Grep match: "email" veya "Welcome"
# Length / status code farkına bak</code></div></div><br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Sonuçları okumak</span></span><br />
Status, Length, Words, Grep Match sütunları. Anormal uzunluk = farklı yetki seviyesi veya hata mesajı sızıntısı olabilir. Response'u elle doğrulamadan "bug" demeyin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Nezaket ve güvenlik</span></span><ul class="mycode_list"><li>Resource Pool / Delay ile saniyede istek sayısını düşürün<br />
</li>
<li>Production bug bounty'de program kurallarındaki rate limit'e uyun<br />
</li>
<li>Login formunda brute force Intruder = çoğu programda yasak<br />
</li>
<li>Oturum çerezini öldürmemek için attack sırasında cookie jar'ı bilinçli yönetin<br />
</li>
</ul>
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Intruder vs ffuf</span></span><br />
Intruder GUI ve tarayıcı akışıyla entegre; ffuf hız ve CLI otomasyonunda önde. Ben keşifte ffuf, oturumlu iş mantığında Intruder kullanıyorum.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kaynaklar</span></span><ul class="mycode_list"><li>PortSwigger Web Security Academy - Burp Intruder<br />
</li>
<li>OWASP Testing Guide<br />
</li>
<li>DVWA / OWASP Juice Shop (yasal lab)<br />
</li>
</ul>
<br />
Siz Cluster bomb'u gerçekten ne zaman kullanıyorsunuz? Ben çoğu senaryoda Pitchfork + manuel ile yetiniyorum.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Grep extract ile zincir</span></span><br />
Önceki yanıttan CSRF token çekip sonraki isteğe yerleştirmek Intruder/macros ile yapılır. Labda login + fuzz akışını kaydedin. Session handling rule ile cookie yenilemek, uzun fuzz sırasında 401 yağmurunu keser.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Payload set hijyeni</span></span><br />
Başkasının "100MB xss.txt" listesini körlemesine kullanmayın; labda önce 50 satırlık hedefli liste. Production bounty'de aynı kural: kalite &gt; megabayt.<br />
<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Doğrulama senaryosu</span></span><br />
Bu konuyla ilgili ek bir kontrol: değişikliği yaptıktan sonra en az bir negatif test ve bir pozitif test tanımlayın. Negatif test 'alarm boşyere düşmemeli', pozitif test 'bilinen kötü örneği yakalamalı' der. İkisini de kaydedin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Lab disiplini</span></span><br />
Ortamlar arasında (lab, staging, production) aynı yapılandırmayı kör kopyalamayın. Adresler, sertifikalar ve kimlikler farklıdır. Şablon kullanın, değerleri envanterden doldurun.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Runbook'a taşımak</span></span><br />
İlgili log ve kanıtları olaydan sonra en az kurum politikasının öngördüğü süre kadar saklayın. Disk dolunca en eski güvenlik logunu silmek klasik hatadır; ayrı retention politikası tanımlayın.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Ölçüm ve alarm sağlığı</span></span><br />
Yanlış pozitifleri susturmak ile körleşmek arasındaki çizgi incedir. Suppress kuralına gerekçe ve gözden geçirme tarihi yazın. Süresi dolunca yeniden değerlendirin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kapsam ve izin hatırlatması</span></span><br />
Bu adımları change ticket olmadan production'da uygulamayın. Küçük görünen bir audit ayarı bile uygulama uyumluluğunu bozabilir. Önce staging, sonra kontrollü yayılım.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Yedekleme ve geri dönüş</span></span><br />
Yılda en az iki kez masabaşı tatbikatı yapın: 'bu kontrol kırılırsa kim fark eder?' sorusunu sorunsuz cevaplayabilmelisiniz. Tatbikat notlarını wiki'ye ekleyin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Log saklama süresi</span></span><br />
Araç çıktısını ekran görüntüsü olarak bırakmak yerine makinece okunur formatta (JSON/CSV) arşivleyin. İki yıl sonraki denetimde arama kolaylaşır.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Yanlış pozitif yönetimi</span></span><br />
Yetki ayrımı: bu kontrolü yapılandıran kişi ile alarmı triaj eden kişi mümkünse farklı olsun. Küçük ekiplerde olmasa bile en azından farklı hesap kullanın.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Değişiklik yönetimi ile ilişki</span></span><br />
Sürüüm yükseltmelerinden sonra regresyon testi yapın. 'Aynı config' yeni sürümde farklı varsayılanlara bağlanmış olabilir. Release note'daki breaking change bölümünü okuyun.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Eğitim tatbikatı</span></span><br />
Dış bağımlılık (feed, imza seti, konteyner imajı) için bütünlük doğrulaması yapın. İmzasız feed ile gelen kural seti tedarik zinciri riskidir.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Doğrulama senaryosu</span></span><br />
Bu konuyla ilgili ek bir kontrol: değişikliği yaptıktan sonra en az bir negatif test ve bir pozitif test tanımlayın. Negatif test 'alarm boşyere düşmemeli', pozitif test 'bilinen kötü örneği yakalamalı' der. İkisini de kaydedin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Lab disiplini</span></span><br />
Ortamlar arasında (lab, staging, production) aynı yapılandırmayı kör kopyalamayın. Adresler, sertifikalar ve kimlikler farklıdır. Şablon kullanın, değerleri envanterden doldurun.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Runbook'a taşımak</span></span><br />
İlgili log ve kanıtları olaydan sonra en az kurum politikasının öngördüğü süre kadar saklayın. Disk dolunca en eski güvenlik logunu silmek klasik hatadır; ayrı retention politikası tanımlayın.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Ölçüm ve alarm sağlığı</span></span><br />
Yanlış pozitifleri susturmak ile körleşmek arasındaki çizgi incedir. Suppress kuralına gerekçe ve gözden geçirme tarihi yazın. Süresi dolunca yeniden değerlendirin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Kapsam ve izin hatırlatması</span></span><br />
Bu adımları change ticket olmadan production'da uygulamayın. Küçük görünen bir audit ayarı bile uygulama uyumluluğunu bozabilir. Önce staging, sonra kontrollü yayılım.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Yedekleme ve geri dönüş</span></span><br />
Yılda en az iki kez masabaşı tatbikatı yapın: 'bu kontrol kırılırsa kim fark eder?' sorusunu sorunsuz cevaplayabilmelisiniz. Tatbikat notlarını wiki'ye ekleyin.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Log saklama süresi</span></span><br />
Araç çıktısını ekran görüntüsü olarak bırakmak yerine makinece okunur formatta (JSON/CSV) arşivleyin. İki yıl sonraki denetimde arama kolaylaşır.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Yanlış pozitif yönetimi</span></span><br />
Yetki ayrımı: bu kontrolü yapılandıran kişi ile alarmı triaj eden kişi mümkünse farklı olsun. Küçük ekiplerde olmasa bile en azından farklı hesap kullanın.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Değişiklik yönetimi ile ilişki</span></span><br />
Sürüüm yükseltmelerinden sonra regresyon testi yapın. 'Aynı config' yeni sürümde farklı varsayılanlara bağlanmış olabilir. Release note'daki breaking change bölümünü okuyun.<br />
<br />
<span style="font-size: large;" class="mycode_size"><span style="font-weight: bold;" class="mycode_b">Uygulama notu</span></span><br />
Bu rehberdeki komutları olduğu gibi kopyalamadan önce yolları, arayüz adlarını ve IP adreslerini kendi ortamınıza göre değiştirin. Dağıtım farkları (Debian/Ubuntu/RHEL/Windows sunucu) çıktı biçimini değiştirebilir; man sayfası ve resmi dokümantasyon birincil kaynaktır. Bir adım beklediğiniz sonucu vermezse önce yetki (sudo/Administrator), sonra sürüm, en son da yapılandırma dosyası sırasıyla bakın. Değişiklikleri geri almak için snapshot veya yapılandırma yönetimi (Ansible/Git) kullanın; 'elle bir dokundum' geçmişi denetimde kaybolur. Alarm ve log örneklerini ekip kanalında paylaşırken kişisel veri ve iç IP şemasını maskeleyin.<br />
<span style="font-style: italic;" class="mycode_i">Yasal uyarı: Bu içerik eğitim amaçlıdır. Anlatılanları yalnızca kendi sistemlerinizde veya yazılı izin aldığınız sistemlerde uygulayın. Yetkisiz erişim ve sistemlere müdahale 5237 sayılı TCK'nın 243, 244 ve 245. maddeleri kapsamında suçtur.</span><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=289" target="_blank" title="">100-n20-0dfa17.png</a> (Dosya Boyutu: 63.1 KB / İndirme Sayısı: 14)
<!-- end: postbit_attachments_attachment --><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=290" target="_blank" title="">n20-inner.png</a> (Dosya Boyutu: 20.26 KB / İndirme Sayısı: 17)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Command Injection: OS Komut Enjeksiyonu ve Güvenli Kodlama Rehberi]]></title>
			<link>https://www.turkteam.org/konu-command-injection-os-komut-enjeksiyonu-ve-guvenli-kodlama-rehberi.html</link>
			<pubDate>Sun, 18 Oct 2026 21:31:33 +0300</pubDate>
			<dc:creator><![CDATA[<a href="https://www.turkteam.org/member.php?action=profile&uid=3">BilgeKagan</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.turkteam.org/konu-command-injection-os-komut-enjeksiyonu-ve-guvenli-kodlama-rehberi.html</guid>
			<description><![CDATA[[center]<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=246" loading="lazy"  alt="[Resim: attachment.php?aid=246]" class="mycode_img" /></div>[/center]<br />
<br />
Selam millet, BlueTornado burada.<br />
<br />
Command Injection (OS komut enjeksiyonu), uygulamanın kullanıcı girdisini işletim sistemi kabuğuna güvensiz biçimde iletmesiyle oluşur. SQL Injection veritabanını hedeflerken, command injection doğrudan sunucu sürecini hedefler; etki çoğu zaman kritiktir. Bu yazıda CWE-78 bağlamında teori, DVWA/lab gözlemi ve <span style="font-weight: bold;" class="mycode_b">güvenli kodlama</span> odaklı korunma anlatılır.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Konuda Anlatılacaklar</span></span><br />
<ol type="1" class="mycode_list"><li>Command injection nedir?<br />
</li>
<li>Kodlama hataları: shell=True, string birleştirme<br />
</li>
<li>Lab ortamı ve güvenli gözlem<br />
</li>
<li>Metacharacter'lar ve çıktı yorumlama<br />
</li>
<li>Korunma: API'ler, allowlist, least privilege<br />
</li>
<li>İleri seviye: argument injection, kör enjeksiyon<br />
</li>
<li>Kaynakça ve yasal uyarı<br />
</li>
</ol>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">1) Teori</span></span><br />
Birçok uygulama ping, traceroute, görüntü işleme, yedekleme gibi işler için dış komut çağırır. Girdi kabuğa birleşirse saldırgan ek komut zincirleyebilir.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Tehlikeli Python kalıbı
import os
ip = request.args["ip"]
os.system("ping -c 1 " + ip)
# ip = 127.0.0.1; id   -&gt; kabuk ; ile ikinci komutu çalıştırabilir</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Tehlikeli PHP kalıbı
system("ping -c 1 " . &#36;_GET["ip"]);</code></div></div><br />
OWASP Top 10 2021'de Injection (A03) ailesindedir. CWE: <span style="font-weight: bold;" class="mycode_b">CWE-78</span> (OS Command Injection). Argument injection (CWE-88) yakından ilişkilidir: kabuk olmasa bile program argümanları kötüye kullanılabilir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">2) Lab Kurulumu</span></span><br />
DVWA <span style="font-weight: bold;" class="mycode_b">Command Injection</span> sayfası klasik bir örnektir.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>cd DVWA &amp;&amp; docker compose up -d
# Security: Low</code></div></div><br />
Alternatif: kendi izole VM'inizde bilerek zayıf küçük bir Flask uygulaması (internete açmayın).<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">3) Kavram Referansı</span></span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Kabuk metacharacter örnekleri (bilgi amaçlı):</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Komut ayırıcı / zincir (Unix)
; &amp;&amp; || |
# Yerine koyma
`...`  &#36;(...)
# Yönlendirme
&gt; &gt;&gt;</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Güvenli çağrı:</span> Kabuğu devre dışı bırakıp argüman listesi geçmek.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>import subprocess
subprocess.run(["ping", "-c", "1", ip], check=False)
# shell=False (varsayılan) — ip artık yeni komut başlatamaz
# AMA ip'nin ping'e özel zararlı argüman olup olmadığı ayrı konudur</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Allowlist:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>import ipaddress
def validate_ip(s: str) -&gt; str:
    return str(ipaddress.ip_address(s))  # geçersizse exception</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">4) DVWA Low: Adım Adım Gözlem</span></span><br />
Yalnızca kendi DVWA'nızda:<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Adım 1 - Normal:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>127.0.0.1
# Beklenen: ping çıktısı</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Adım 2 - Zincir gözlemi (lab):</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>127.0.0.1; uname -a</code></div></div>Low seviyede çoğu kurulumda hem ping hem uname çıktısı görünür. Bu, girdinin kabuğa gittiğinin kanıtıdır.<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Adım 3 - Filtreli seviyeler:</span> Medium'da <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&amp;&amp;</code></div></div> / <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>;</code></div></div> gibi karakterler engellenmiş olabilir. Kara liste kırılgandır (<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>%0a</code></div></div> satır sonu vb. labda araştırılır). Impossible seviyede allowlist / güvenli API beklenir.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Not şablonu
Seviye: Medium
Payload: 127.0.0.1; id
Sonuç: ; silindi / komut çalışmadı / hata
Çıkarım: blacklist</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Adım 4 - Çıktıyı yorumlama:</span><ul class="mycode_list"><li>Ek komut çıktısı görünüyorsa RCE etkisi vardır<br />
</li>
<li>Çıktı görünmese bile time-based kör enjeksiyon mümkün olabilir<br />
</li>
<li>Uygulama hangi OS kullanıcısı ile çalışıyor? (www-data vb.) — least privilege kritik<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">5) Güvenli Kodlama</span></span><ul class="mycode_list"><li>Mümkünse hiç dış komut çağırmayın; dilin kendi kütüphanesini kullanın<br />
</li>
<li>Çağrı zorunluysa <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>subprocess</code></div></div> / <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>execve</code></div></div> argüman dizisi; <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>shell=True</code></div></div> yasak<br />
</li>
<li>Girdiyi allowlist ile doğrulayın (IP, enum, sabit seçenekler)<br />
</li>
<li>Kullanıcı girdisini asla komut şablonuna birleştirmeyin<br />
</li>
<li>Uygulamayı düşük yetkili kullanıcı ile çalıştırın; container'da root'tan kaçının<br />
</li>
<li>Gerekli binary'lere filesystem izni sınırlayın<br />
</li>
</ul>
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># İyi: IP doğrulama + argüman listesi
import ipaddress, subprocess
ip = str(ipaddress.ip_address(user_input))
subprocess.run(["ping", "-c", "1", ip], capture_output=True, text=True, timeout=5)</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Kötü
subprocess.run(f"ping -c 1 {user_input}", shell=True)</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Node.js kötü
const { exec } = require("child_process");
exec("ping -c 1 " + ip);

# Daha iyi yönde: execFile / spawn ile argüman dizisi + doğrulama
const { execFile } = require("child_process");
execFile("ping", ["-c", "1", ip]);</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">6) İleri Seviye</span></span><br />
<span style="font-weight: bold;" class="mycode_b">Argument injection:</span> <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>tar</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>ffmpeg</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>sendmail</code></div></div> gibi programlar <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>-o</code></div></div> / <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>--</code></div></div> ile başlayan girdilerde beklenmedik davranış sergileyebilir. Allowlist ve <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>--</code></div></div> ayırıcısı düşünün.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Kavramsal
subprocess.run(["some-tool", "--", user_path])</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Blind command injection:</span> Çıktı sayfaya basılmaz; <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>sleep</code></div></div> veya dışarıya DNS/HTTP callback (yalnızca kendi labınız) ile tespit edilir. Üretimde izinsiz outbound callback kullanmayın.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Şablon motorları / CI:</span> Build script'lerine kullanıcı kontrollü alan enjekte etmek de aynı sınıftır.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Rapor
Bulgu: OS Command Injection (CWE-78)
Konum: /vulnerabilities/exec/ ip parametresi
Kanıt: Labda ; uname -a çıktısı
Öneri: subprocess argüman listesi + IP allowlist + düşük yetki</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">7) Sonuç</span></span><br />
Command injection, kabuğa güvenilmeyen veri vermektir. Kara liste değil, güvenli API + allowlist + least privilege ile kapatılır. DVWA'da Low'da görün, Impossible'da doğru kodu okuyun.<br />
<br />
<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Ek: Tespit, Loglama ve Kod İnceleme İpuçları</span></span><br />
Mavi takım / kod inceleme perspektifinden şunlara bakın:<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Grep ile tehlike işaretleri (kendi repo'nuz)
rg -n "os&#92;&#92;.system|shell=True|exec&#92;&#92;(|popen&#92;&#92;(|child_process&#92;&#92;.exec" .</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Uygulama logunda (kavramsal)
{"event":"extcmd","bin":"ping","args":["-c","1","127.0.0.1"],"user":"www-data"}
# Argümanlar ayrık loglanmalı; kabuk satırı tek string olarak loglanıyorsa tasarım zayıf olabilir</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">WAF ve filtre yanılgısı:</span> <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>;</code></div></div> karakterini engellemek çözüm değildir. Base64 ile kodlanmış ikinci aşama, boşluk yerine <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&#36;IFS</code></div></div> gibi varyasyonlar lab ortamlarında anlatılır; üretimde kök nedeni (güvenli API) düzeltin.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Konteyner sertleştirme:</span><ul class="mycode_list"><li>Distroless veya minimal imaj; <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>bash</code></div></div>/<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>curl</code></div></div> yoksa etki azalır (yine de binary çalıştırma mümkün olabilir)<br />
</li>
<li>Read-only kök dosya sistemi + tmpfs<br />
</li>
<li>Capability drop, seccomp, non-root user<br />
</li>
</ul>
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Dockerfile parçası
USER nobody
# HEALTHCHECK ve minimal paket seti</code></div></div><br />
[center][/center]<br />
<br />
Kod incelemesinde "bu girdi allowlist'ten mi geçiyor?" sorusu, "filtre yeterli mi?" sorusundan daha değerlidir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Kaynakça</span></span><ul class="mycode_list"><li><a href="https://owasp.org/www-community/attacks/Command_Injection" target="_blank" rel="noopener" class="mycode_url">OWASP Command Injection</a><br />
</li>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/OS_Command_Injection_Defense_Cheat_Sheet.html" target="_blank" rel="noopener" class="mycode_url">OWASP OS Command Injection Defense</a><br />
</li>
<li><a href="https://cwe.mitre.org/data/definitions/78.html" target="_blank" rel="noopener" class="mycode_url">CWE-78</a><br />
</li>
<li><a href="https://docs.python.org/3/library/subprocess.html" target="_blank" rel="noopener" class="mycode_url">Python subprocess dokümantasyonu</a><br />
</li>
<li><a href="https://github.com/digininja/DVWA" target="_blank" rel="noopener" class="mycode_url">DVWA</a><br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Yasal Uyarı</span></span><br />
Komut enjeksiyonu testleri yalnızca kendi sistemleriniz veya yazılı izinli lab/pentest içindir. İzinsiz RCE denemesi TCK <span style="font-weight: bold;" class="mycode_b">243-245</span> kapsamında ağır suç olabilir. Sorumluluk uygulayana aittir.<br />
<br />
<span style="font-style: italic;" class="mycode_i">Yasal uyarı: Bu içerik eğitim amaçlıdır. Yalnızca kendi sistemlerinizde veya yazılı izin aldığınız hedeflerde uygulayın (TCK 243-245).</span><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=246" target="_blank" title="">000-team-new-bf04ec.png</a> (Dosya Boyutu: 67.75 KB / İndirme Sayısı: 9)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[[center]<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=246" loading="lazy"  alt="[Resim: attachment.php?aid=246]" class="mycode_img" /></div>[/center]<br />
<br />
Selam millet, BlueTornado burada.<br />
<br />
Command Injection (OS komut enjeksiyonu), uygulamanın kullanıcı girdisini işletim sistemi kabuğuna güvensiz biçimde iletmesiyle oluşur. SQL Injection veritabanını hedeflerken, command injection doğrudan sunucu sürecini hedefler; etki çoğu zaman kritiktir. Bu yazıda CWE-78 bağlamında teori, DVWA/lab gözlemi ve <span style="font-weight: bold;" class="mycode_b">güvenli kodlama</span> odaklı korunma anlatılır.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Konuda Anlatılacaklar</span></span><br />
<ol type="1" class="mycode_list"><li>Command injection nedir?<br />
</li>
<li>Kodlama hataları: shell=True, string birleştirme<br />
</li>
<li>Lab ortamı ve güvenli gözlem<br />
</li>
<li>Metacharacter'lar ve çıktı yorumlama<br />
</li>
<li>Korunma: API'ler, allowlist, least privilege<br />
</li>
<li>İleri seviye: argument injection, kör enjeksiyon<br />
</li>
<li>Kaynakça ve yasal uyarı<br />
</li>
</ol>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">1) Teori</span></span><br />
Birçok uygulama ping, traceroute, görüntü işleme, yedekleme gibi işler için dış komut çağırır. Girdi kabuğa birleşirse saldırgan ek komut zincirleyebilir.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Tehlikeli Python kalıbı
import os
ip = request.args["ip"]
os.system("ping -c 1 " + ip)
# ip = 127.0.0.1; id   -&gt; kabuk ; ile ikinci komutu çalıştırabilir</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Tehlikeli PHP kalıbı
system("ping -c 1 " . &#36;_GET["ip"]);</code></div></div><br />
OWASP Top 10 2021'de Injection (A03) ailesindedir. CWE: <span style="font-weight: bold;" class="mycode_b">CWE-78</span> (OS Command Injection). Argument injection (CWE-88) yakından ilişkilidir: kabuk olmasa bile program argümanları kötüye kullanılabilir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">2) Lab Kurulumu</span></span><br />
DVWA <span style="font-weight: bold;" class="mycode_b">Command Injection</span> sayfası klasik bir örnektir.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>cd DVWA &amp;&amp; docker compose up -d
# Security: Low</code></div></div><br />
Alternatif: kendi izole VM'inizde bilerek zayıf küçük bir Flask uygulaması (internete açmayın).<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">3) Kavram Referansı</span></span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Kabuk metacharacter örnekleri (bilgi amaçlı):</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Komut ayırıcı / zincir (Unix)
; &amp;&amp; || |
# Yerine koyma
`...`  &#36;(...)
# Yönlendirme
&gt; &gt;&gt;</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Güvenli çağrı:</span> Kabuğu devre dışı bırakıp argüman listesi geçmek.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>import subprocess
subprocess.run(["ping", "-c", "1", ip], check=False)
# shell=False (varsayılan) — ip artık yeni komut başlatamaz
# AMA ip'nin ping'e özel zararlı argüman olup olmadığı ayrı konudur</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Allowlist:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>import ipaddress
def validate_ip(s: str) -&gt; str:
    return str(ipaddress.ip_address(s))  # geçersizse exception</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">4) DVWA Low: Adım Adım Gözlem</span></span><br />
Yalnızca kendi DVWA'nızda:<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Adım 1 - Normal:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>127.0.0.1
# Beklenen: ping çıktısı</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Adım 2 - Zincir gözlemi (lab):</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>127.0.0.1; uname -a</code></div></div>Low seviyede çoğu kurulumda hem ping hem uname çıktısı görünür. Bu, girdinin kabuğa gittiğinin kanıtıdır.<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Adım 3 - Filtreli seviyeler:</span> Medium'da <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&amp;&amp;</code></div></div> / <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>;</code></div></div> gibi karakterler engellenmiş olabilir. Kara liste kırılgandır (<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>%0a</code></div></div> satır sonu vb. labda araştırılır). Impossible seviyede allowlist / güvenli API beklenir.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Not şablonu
Seviye: Medium
Payload: 127.0.0.1; id
Sonuç: ; silindi / komut çalışmadı / hata
Çıkarım: blacklist</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Adım 4 - Çıktıyı yorumlama:</span><ul class="mycode_list"><li>Ek komut çıktısı görünüyorsa RCE etkisi vardır<br />
</li>
<li>Çıktı görünmese bile time-based kör enjeksiyon mümkün olabilir<br />
</li>
<li>Uygulama hangi OS kullanıcısı ile çalışıyor? (www-data vb.) — least privilege kritik<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">5) Güvenli Kodlama</span></span><ul class="mycode_list"><li>Mümkünse hiç dış komut çağırmayın; dilin kendi kütüphanesini kullanın<br />
</li>
<li>Çağrı zorunluysa <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>subprocess</code></div></div> / <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>execve</code></div></div> argüman dizisi; <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>shell=True</code></div></div> yasak<br />
</li>
<li>Girdiyi allowlist ile doğrulayın (IP, enum, sabit seçenekler)<br />
</li>
<li>Kullanıcı girdisini asla komut şablonuna birleştirmeyin<br />
</li>
<li>Uygulamayı düşük yetkili kullanıcı ile çalıştırın; container'da root'tan kaçının<br />
</li>
<li>Gerekli binary'lere filesystem izni sınırlayın<br />
</li>
</ul>
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># İyi: IP doğrulama + argüman listesi
import ipaddress, subprocess
ip = str(ipaddress.ip_address(user_input))
subprocess.run(["ping", "-c", "1", ip], capture_output=True, text=True, timeout=5)</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Kötü
subprocess.run(f"ping -c 1 {user_input}", shell=True)</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Node.js kötü
const { exec } = require("child_process");
exec("ping -c 1 " + ip);

# Daha iyi yönde: execFile / spawn ile argüman dizisi + doğrulama
const { execFile } = require("child_process");
execFile("ping", ["-c", "1", ip]);</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">6) İleri Seviye</span></span><br />
<span style="font-weight: bold;" class="mycode_b">Argument injection:</span> <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>tar</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>ffmpeg</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>sendmail</code></div></div> gibi programlar <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>-o</code></div></div> / <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>--</code></div></div> ile başlayan girdilerde beklenmedik davranış sergileyebilir. Allowlist ve <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>--</code></div></div> ayırıcısı düşünün.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Kavramsal
subprocess.run(["some-tool", "--", user_path])</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Blind command injection:</span> Çıktı sayfaya basılmaz; <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>sleep</code></div></div> veya dışarıya DNS/HTTP callback (yalnızca kendi labınız) ile tespit edilir. Üretimde izinsiz outbound callback kullanmayın.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Şablon motorları / CI:</span> Build script'lerine kullanıcı kontrollü alan enjekte etmek de aynı sınıftır.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Rapor
Bulgu: OS Command Injection (CWE-78)
Konum: /vulnerabilities/exec/ ip parametresi
Kanıt: Labda ; uname -a çıktısı
Öneri: subprocess argüman listesi + IP allowlist + düşük yetki</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">7) Sonuç</span></span><br />
Command injection, kabuğa güvenilmeyen veri vermektir. Kara liste değil, güvenli API + allowlist + least privilege ile kapatılır. DVWA'da Low'da görün, Impossible'da doğru kodu okuyun.<br />
<br />
<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Ek: Tespit, Loglama ve Kod İnceleme İpuçları</span></span><br />
Mavi takım / kod inceleme perspektifinden şunlara bakın:<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Grep ile tehlike işaretleri (kendi repo'nuz)
rg -n "os&#92;&#92;.system|shell=True|exec&#92;&#92;(|popen&#92;&#92;(|child_process&#92;&#92;.exec" .</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Uygulama logunda (kavramsal)
{"event":"extcmd","bin":"ping","args":["-c","1","127.0.0.1"],"user":"www-data"}
# Argümanlar ayrık loglanmalı; kabuk satırı tek string olarak loglanıyorsa tasarım zayıf olabilir</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">WAF ve filtre yanılgısı:</span> <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>;</code></div></div> karakterini engellemek çözüm değildir. Base64 ile kodlanmış ikinci aşama, boşluk yerine <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&#36;IFS</code></div></div> gibi varyasyonlar lab ortamlarında anlatılır; üretimde kök nedeni (güvenli API) düzeltin.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Konteyner sertleştirme:</span><ul class="mycode_list"><li>Distroless veya minimal imaj; <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>bash</code></div></div>/<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>curl</code></div></div> yoksa etki azalır (yine de binary çalıştırma mümkün olabilir)<br />
</li>
<li>Read-only kök dosya sistemi + tmpfs<br />
</li>
<li>Capability drop, seccomp, non-root user<br />
</li>
</ul>
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Dockerfile parçası
USER nobody
# HEALTHCHECK ve minimal paket seti</code></div></div><br />
[center][/center]<br />
<br />
Kod incelemesinde "bu girdi allowlist'ten mi geçiyor?" sorusu, "filtre yeterli mi?" sorusundan daha değerlidir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Kaynakça</span></span><ul class="mycode_list"><li><a href="https://owasp.org/www-community/attacks/Command_Injection" target="_blank" rel="noopener" class="mycode_url">OWASP Command Injection</a><br />
</li>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/OS_Command_Injection_Defense_Cheat_Sheet.html" target="_blank" rel="noopener" class="mycode_url">OWASP OS Command Injection Defense</a><br />
</li>
<li><a href="https://cwe.mitre.org/data/definitions/78.html" target="_blank" rel="noopener" class="mycode_url">CWE-78</a><br />
</li>
<li><a href="https://docs.python.org/3/library/subprocess.html" target="_blank" rel="noopener" class="mycode_url">Python subprocess dokümantasyonu</a><br />
</li>
<li><a href="https://github.com/digininja/DVWA" target="_blank" rel="noopener" class="mycode_url">DVWA</a><br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Yasal Uyarı</span></span><br />
Komut enjeksiyonu testleri yalnızca kendi sistemleriniz veya yazılı izinli lab/pentest içindir. İzinsiz RCE denemesi TCK <span style="font-weight: bold;" class="mycode_b">243-245</span> kapsamında ağır suç olabilir. Sorumluluk uygulayana aittir.<br />
<br />
<span style="font-style: italic;" class="mycode_i">Yasal uyarı: Bu içerik eğitim amaçlıdır. Yalnızca kendi sistemlerinizde veya yazılı izin aldığınız hedeflerde uygulayın (TCK 243-245).</span><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=246" target="_blank" title="">000-team-new-bf04ec.png</a> (Dosya Boyutu: 67.75 KB / İndirme Sayısı: 9)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[HTTP Güvenlik Başlıkları: CSP, HSTS, X-Frame-Options ve Doğru Yapılandırma Rehberi]]></title>
			<link>https://www.turkteam.org/konu-http-guvenlik-basliklari-csp-hsts-x-frame-options-ve-dogru-yapilandirma-rehberi.html</link>
			<pubDate>Sun, 18 Oct 2026 19:13:18 +0300</pubDate>
			<dc:creator><![CDATA[<a href="https://www.turkteam.org/member.php?action=profile&uid=3">BilgeKagan</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.turkteam.org/konu-http-guvenlik-basliklari-csp-hsts-x-frame-options-ve-dogru-yapilandirma-rehberi.html</guid>
			<description><![CDATA[[center]<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=205" loading="lazy"  alt="[Resim: attachment.php?aid=205]" class="mycode_img" /></div>[/center]<br />
<br />
Selam TurkTeam, BlueTornado yazıyor.<br />
<br />
HTTP güvenlik başlıkları, sunucunun yanıtla birlikte tarayıcıya gönderdiği "bu sayfayı nasıl korumalısın" talimatlarıdır. Başlığı koymak işin yarısıdır; asıl mesele <span style="font-weight: bold;" class="mycode_b">tarayıcının o başlığı nasıl yorumladığını</span> bilmek ve politikayı uygulamanızı bozmadan, uygulama katmanında (kod, framework, middleware) doğru kurmaktır. Bu rehberde ağırlık Content Security Policy (CSP) üzerinde: direktifler, nonce/hash, report-only modu ve ihlal raporlama. Web sunucusu tarafındaki TLS ve rate limit ayarları için forumdaki Nginx sıkılaştırma konusuna bakabilirsiniz; burada o kısmı tekrar etmiyoruz.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Konuda Anlatılacaklar</span></span><br />
<ol type="1" class="mycode_list"><li>Güvenlik başlıkları nedir, tarayıcı bunları nasıl uygular?<br />
</li>
<li>Lab: kendi uygulamanızın başlıklarını okumak<br />
</li>
<li>CSP derinlemesine: direktifler ve kaynak ifadeleri<br />
</li>
<li>Nonce ve hash ile inline script'e güvenli izin<br />
</li>
<li>Report-Only modu ve ihlal raporlarının toplanması<br />
</li>
<li>HSTS, X-Frame-Options, nosniff, Referrer-Policy, Permissions-Policy<br />
</li>
<li>Uygulama katmanında kurulum: Express (helmet), Django, PHP<br />
</li>
<li>Sık yapılan hatalar, sonuç, kaynakça ve yasal uyarı<br />
</li>
</ol>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">1) Güvenlik Başlıkları Nedir?</span></span><br />
Tarayıcı, bir yanıtı işlerken başlıkları okur ve kendi davranışını kısıtlar. Örneğin CSP, "bu sayfada yalnızca kendi alan adımdan script çalıştır" der; XSS açığı olsa bile enjekte edilen script'in çalışması engellenebilir. Başlıklar <span style="font-weight: bold;" class="mycode_b">açığın kendisini kapatmaz</span>, sömürünün etkisini azaltan ikinci savunma hattıdır (defense in depth). Girdi doğrulama ve çıktı kodlama (output encoding) yine zorunludur.<br />
<br />
<blockquote class="mycode_quote"><cite>Alıntı:</cite>Kural: Başlıklar tarayıcıda uygulanır. curl veya bir bot bu kurallara uymaz; yani CSP sunucunuzu değil, kullanıcınızın tarayıcısını korur.</blockquote>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">2) Lab: Başlıkları Okumak</span></span><br />
Önce mevcut durumu görelim. Kendi geliştirme ortamınızda (ör. localhost:3000) çalışan uygulamanız üzerinde:<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Yalnızca yanıt başlıklarını göster
curl -sI http://localhost:3000/

# Belirli başlıkları süz
curl -sI http://localhost:3000/ | grep -iE 'content-security|strict-transport|x-frame|x-content-type|referrer|permissions'</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Çıktı yorumu:</span> Hiçbir satır dönmüyorsa uygulamanız hiçbir güvenlik başlığı göndermiyor demektir. Tarayıcıda DevTools &gt; Network &gt; ilgili istek &gt; Headers sekmesinden de aynı bilgiyi görebilirsiniz. CSP ihlalleri ise Console sekmesinde ayrıca uyarı olarak çıkar.<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">3) Content Security Policy Derinlemesine</span></span><br />
CSP, direktif ve kaynak listelerinden oluşan bir politikadır. Direktifler noktalı virgülle ayrılır:<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Content-Security-Policy: default-src 'self'; img-src 'self' data:; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Temel direktifler:</span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">default-src:</span> Ayrıca tanımlanmayan fetch direktifleri için varsayılan (script-src, style-src, img-src, connect-src, font-src vb.)<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">script-src:</span> JavaScript kaynakları; XSS'e karşı en kritik direktif<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">style-src:</span> CSS kaynakları<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">connect-src:</span> fetch, XHR, WebSocket hedefleri<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">object-src 'none':</span> Eski eklenti (object/embed) içeriğini kapatır; neredeyse her sitede önerilir<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">base-uri:</span> base etiketiyle göreli URL'lerin kaçırılmasını önler<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">form-action:</span> Formların hangi adreslere gönderilebileceği<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">frame-ancestors:</span> Sayfanızı kimin iframe içine alabileceği (clickjacking koruması)<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">upgrade-insecure-requests:</span> Sayfa içindeki http alt kaynak isteklerini https'e yükseltir<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">Kaynak ifadeleri:</span> <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>'self'</code></div></div> (aynı origin: şema + host + port), <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>'none'</code></div></div>, belirli host'lar (<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>https://cdn.ornek.com</code></div></div>), şemalar (<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>data:</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>https:</code></div></div>) ve anahtar kelimeler (<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>'unsafe-inline'</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>'unsafe-eval'</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>'strict-dynamic'</code></div></div>). 'unsafe-inline' ve 'unsafe-eval' script-src içinde CSP'nin XSS korumasını büyük ölçüde boşa çıkarır; kaçının.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Meta etiketiyle CSP:</span> Başlık ekleyemediğiniz statik barındırmada politika HTML içine konabilir:<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&lt;meta http-equiv="Content-Security-Policy" content="default-src 'self'; object-src 'none'; base-uri 'self'"&gt;</code></div></div><br />
Dikkat: meta etiketi ile <span style="font-weight: bold;" class="mycode_b">frame-ancestors, report-uri ve sandbox desteklenmez</span> ve politika yalnızca etiketten sonra yüklenen içeriğe uygulanır. Mümkünse HTTP başlığını tercih edin.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">4) Nonce ve Hash ile Inline Script</span></span><br />
Inline script'leri tamamen kaldırmak en temizidir. Kaldıramıyorsanız 'unsafe-inline' yerine nonce veya hash kullanın.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Nonce:</span> Her yanıtta yeniden üretilen, tahmin edilemez rastgele bir değer. Başlıkta ve script etiketinde aynısı olmalıdır:<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Content-Security-Policy: script-src 'nonce-R4nd0mDegerHerIstekteYeni' 'strict-dynamic'; object-src 'none'; base-uri 'self'

&lt;script nonce="R4nd0mDegerHerIstekteYeni"&gt;
  initApp();
&lt;/script&gt;</code></div></div><br />
Nonce sabit kodlanırsa veya önbelleğe alınmış sayfada tekrar kullanılırsa koruma anlamını yitirir. <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>'strict-dynamic'</code></div></div>, nonce'lu güvenilir script'in yüklediği script'lere de güvenilmesini sağlar; destekleyen tarayıcılarda host listelerini göz ardı eder. Bu yaklaşım OWASP ve web.dev tarafından önerilen "strict CSP" modelidir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Hash:</span> Değişmeyen inline script için içeriğin SHA-256 özeti:<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Script içeriğinin (etiketler hariç, birebir aynı boşluklarla) hash'i
printf '%s' "initApp();" | openssl dgst -sha256 -binary | openssl base64

# Politikaya ekleme
Content-Security-Policy: script-src 'sha256-&lt;yukaridaki_cikti&gt;'</code></div></div><br />
Script içeriğinde tek bir boşluk değişirse hash tutmaz ve tarayıcı script'i engeller; Console'daki hata mesajı genellikle beklenen hash'i de gösterir.<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">5) Report-Only ve İhlal Raporları</span></span><br />
Mevcut bir uygulamaya doğrudan sıkı CSP koymak genellikle bir şeyleri bozar. Doğru yol önce <span style="font-weight: bold;" class="mycode_b">Content-Security-Policy-Report-Only</span> ile gözlemlemektir: tarayıcı hiçbir şeyi engellemez, yalnızca ihlali raporlar.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Reporting-Endpoints: csp-endpoint="https://uygulamaniz.ornek/csp-report"
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self'; report-to csp-endpoint; report-uri /csp-report</code></div></div><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">report-uri:</span> Eski yöntem, spesifikasyonda kullanımdan kaldırılıyor ama hâlâ geniş destekli. Tarayıcı JSON gövdesini application/csp-report türüyle POST eder.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">report-to:</span> Reporting API ile yeni yöntem; uç nokta adı Reporting-Endpoints başlığında tanımlanır. Geçiş döneminde ikisini birlikte kullanmak yaygındır.<br />
</li>
</ul>
<br />
Basit bir Express toplayıcı (yalnızca kendi uygulamanız için):<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>app.post('/csp-report',
  express.json({ type: ['application/csp-report', 'application/reports+json'] }),
  (req, res) =&gt; {
    console.log(JSON.stringify(req.body));   // üretimde log sistemine yazın
    res.sendStatus(204);
  });</code></div></div><br />
Raporlarda violated-directive / effective-directive ve blocked-uri alanlarına bakarak hangi kaynağı politikaya eklemeniz veya koddan kaldırmanız gerektiğine karar verin. Birkaç gün temiz rapor aldıktan sonra aynı politikayı zorlayıcı başlığa taşıyın. Rapor uç noktası herkese açık olduğundan gövde boyutunu sınırlayın ve içeriğe güvenmeyin.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">6) Diğer Başlıklar ve Tarayıcı Yorumu</span></span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Strict-Transport-Security (HSTS):</span> Tarayıcı bu başlığı yalnızca HTTPS yanıtında dikkate alır; max-age süresince o alan adına http ile gitmeyi reddeder, sertifika hatasında kullanıcıya "yine de devam et" seçeneği sunmaz.<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Strict-Transport-Security: max-age=31536000; includeSubDomains</code></div></div>preload eklemeden önce hstspreload.org gereksinimlerini okuyun; preload listesinden çıkmak uzun sürer. Kısa max-age ile başlayıp artırmak güvenli yaklaşımdır.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">X-Frame-Options:</span> DENY veya SAMEORIGIN. ALLOW-FROM eskidir, modern tarayıcılar desteklemez. Modern karşılığı CSP frame-ancestors'tır; ikisi birlikte varsa destekleyen tarayıcılar frame-ancestors'ı esas alır. Eski tarayıcılar için ikisini birlikte göndermek zararsızdır.<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors 'none'</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">X-Content-Type-Options: nosniff:</span> Tarayıcının MIME türü tahmin etmesini (sniffing) kapatır; yanlış Content-Type ile gelen script/stil engellenir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Referrer-Policy:</span> Başka siteye geçerken URL'nin ne kadarının Referer'da gideceğini belirler. <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>strict-origin-when-cross-origin</code></div></div> dengeli bir seçimdir; URL'de token taşıyorsanız <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>no-referrer</code></div></div> düşünün.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Permissions-Policy:</span> Kamera, mikrofon, konum gibi tarayıcı özelliklerini kısıtlar:<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Permissions-Policy: camera=(), microphone=(), geolocation=()</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">X-XSS-Protection:</span> Eski tarayıcı filtresi içindir, modern tarayıcılarda kaldırılmıştır. OWASP, göndermemeyi veya "0" değerini önerir; XSS koruması için CSP kullanın.<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">7) Uygulama Katmanında Kurulum</span></span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Express (helmet):</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>npm install helmet</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>const crypto = require('crypto');
const helmet = require('helmet');

app.use((req, res, next) =&gt; {
  res.locals.cspNonce = crypto.randomBytes(16).toString('base64');
  next();
});

app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'", (req, res) =&gt; `'nonce-&#36;{res.locals.cspNonce}'`],
      objectSrc: ["'none'"],
      baseUri: ["'self'"],
      frameAncestors: ["'none'"],
    },
  },
}));
// Şablonda: &lt;script nonce="&lt;%= cspNonce %&gt;"&gt;...&lt;/script&gt;</code></div></div><br />
helmet varsayılan olarak bir dizi başlık ekler; hangi değerleri gönderdiğini kendi sürümünüzde curl -I ile mutlaka doğrulayın.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Django:</span> SecurityMiddleware ve XFrameOptionsMiddleware ayarları settings.py'dedir. Django 6.0 ile yerleşik CSP desteği geldi (eski sürümlerde django-csp paketi kullanılır):<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
    "django.middleware.csp.ContentSecurityPolicyMiddleware",  # Django 6.0+
    # ...
]

SECURE_HSTS_SECONDS = 31536000          # yalnızca HTTPS tamamen hazırsa
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_CONTENT_TYPE_NOSNIFF = True
SECURE_REFERRER_POLICY = "strict-origin-when-cross-origin"
X_FRAME_OPTIONS = "DENY"

from django.utils.csp import CSP
SECURE_CSP_REPORT_ONLY = {
    "default-src": [CSP.SELF],
    "script-src": [CSP.SELF, CSP.NONCE],
    "object-src": [CSP.NONE],
    "report-uri": "/csp-report/",
}</code></div></div><br />
Şablonda nonce için csp context processor'ı (django.template.context_processors.csp) etkinleştirip <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&lt;script nonce="{{ csp_nonce }}"&gt;</code></div></div> kullanın. Ayarları kontrol etmek için:<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>python manage.py check --deploy</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">PHP:</span> header() çağrıları herhangi bir çıktıdan önce yapılmalıdır:<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&lt;?php
&#36;nonce = base64_encode(random_bytes(16));
header("Content-Security-Policy: default-src 'self'; script-src 'nonce-&#36;nonce' 'strict-dynamic'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'");
header("X-Content-Type-Options: nosniff");
header("Referrer-Policy: strict-origin-when-cross-origin");
?&gt;
&lt;script nonce="&lt;?= htmlspecialchars(&#36;nonce) ?&gt;"&gt;initApp();&lt;/script&gt;</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">8) Sık Yapılan Hatalar</span></span><ul class="mycode_list"><li>script-src içinde 'unsafe-inline' bırakmak (nonce/hash varken destekleyen tarayıcılar onu yok sayar, ama tek başına korumayı boşa çıkarır)<br />
</li>
<li>Aynı başlığı hem uygulamada hem ters vekilde farklı değerlerle eklemek; birden fazla CSP başlığında tarayıcı hepsini birden uygular, sonuç beklenenden sıkı olur<br />
</li>
<li>Nonce'u sabit yazmak veya tam sayfa önbelleğinde kullanıcılar arasında paylaştırmak<br />
</li>
<li>Report-Only'de kalıp politikayı hiç zorlayıcı moda almamak<br />
</li>
<li>HTTPS hazır değilken uzun max-age ile HSTS ya da preload göndermek<br />
</li>
<li>CDN alan adının tamamına izin vermek (ör. tüm bir paylaşımlı CDN); saldırgan aynı CDN'e dosya koyabiliyorsa politika aşılabilir<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">9) Sonuç</span></span><br />
Güvenlik başlıkları ucuz ama güçlü bir katmandır. Sıralama önerim: önce nosniff, Referrer-Policy ve frame koruması; ardından CSP'yi Report-Only ile başlatıp raporlarla olgunlaştırmak; en son nonce tabanlı strict CSP'yi zorlamak. Politikanızı Google'ın CSP Evaluator aracıyla gözden geçirip her sürümde curl -I ile doğrulayın.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Kaynakça</span></span><ul class="mycode_list"><li><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP" target="_blank" rel="noopener" class="mycode_url">MDN - Content Security Policy (CSP)</a><br />
</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy" target="_blank" rel="noopener" class="mycode_url">MDN - Content-Security-Policy başlık referansı</a><br />
</li>
<li><a href="https://www.w3.org/TR/CSP3/" target="_blank" rel="noopener" class="mycode_url">W3C - Content Security Policy Level 3</a><br />
</li>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/Content_Security_Policy_Cheat_Sheet.html" target="_blank" rel="noopener" class="mycode_url">OWASP CSP Cheat Sheet</a><br />
</li>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html" target="_blank" rel="noopener" class="mycode_url">OWASP HTTP Security Response Headers Cheat Sheet</a><br />
</li>
<li><a href="https://owasp.org/www-project-secure-headers/" target="_blank" rel="noopener" class="mycode_url">OWASP Secure Headers Project</a><br />
</li>
<li><a href="https://datatracker.ietf.org/doc/html/rfc6797" target="_blank" rel="noopener" class="mycode_url">RFC 6797 - HTTP Strict Transport Security</a><br />
</li>
<li><a href="https://datatracker.ietf.org/doc/html/rfc7034" target="_blank" rel="noopener" class="mycode_url">RFC 7034 - X-Frame-Options</a><br />
</li>
<li><a href="https://helmetjs.github.io/" target="_blank" rel="noopener" class="mycode_url">Helmet.js dokümantasyonu</a><br />
</li>
<li><a href="https://docs.djangoproject.com/en/6.0/ref/csp/" target="_blank" rel="noopener" class="mycode_url">Django - Content Security Policy</a><br />
</li>
<li><a href="https://web.dev/articles/strict-csp" target="_blank" rel="noopener" class="mycode_url">web.dev - Strict CSP</a><br />
</li>
<li><a href="https://csp-evaluator.withgoogle.com/" target="_blank" rel="noopener" class="mycode_url">Google CSP Evaluator</a><br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Yasal Uyarı</span></span><br />
Bu rehber kendi uygulamalarınızı korumak içindir. Başlık ve politika testlerini yalnızca kendi sistemlerinizde veya yazılı yetkili pentest kapsamında yapın. Başkasına ait sistemlere izinsiz erişim veya müdahale TCK <span style="font-weight: bold;" class="mycode_b">243-245</span> ve ilgili maddeler kapsamında suç olabilir. Eğitim amaçlıdır.<br />
<br />
<span style="font-style: italic;" class="mycode_i">Yasal uyarı: Bu içerik eğitim amaçlıdır. Yalnızca kendi sistemlerinizde veya yazılı izin aldığınız hedeflerde uygulayın (TCK 243-245).</span><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=205" target="_blank" title="">000-team-new-3ddc97.png</a> (Dosya Boyutu: 71.82 KB / İndirme Sayısı: 7)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[[center]<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=205" loading="lazy"  alt="[Resim: attachment.php?aid=205]" class="mycode_img" /></div>[/center]<br />
<br />
Selam TurkTeam, BlueTornado yazıyor.<br />
<br />
HTTP güvenlik başlıkları, sunucunun yanıtla birlikte tarayıcıya gönderdiği "bu sayfayı nasıl korumalısın" talimatlarıdır. Başlığı koymak işin yarısıdır; asıl mesele <span style="font-weight: bold;" class="mycode_b">tarayıcının o başlığı nasıl yorumladığını</span> bilmek ve politikayı uygulamanızı bozmadan, uygulama katmanında (kod, framework, middleware) doğru kurmaktır. Bu rehberde ağırlık Content Security Policy (CSP) üzerinde: direktifler, nonce/hash, report-only modu ve ihlal raporlama. Web sunucusu tarafındaki TLS ve rate limit ayarları için forumdaki Nginx sıkılaştırma konusuna bakabilirsiniz; burada o kısmı tekrar etmiyoruz.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Konuda Anlatılacaklar</span></span><br />
<ol type="1" class="mycode_list"><li>Güvenlik başlıkları nedir, tarayıcı bunları nasıl uygular?<br />
</li>
<li>Lab: kendi uygulamanızın başlıklarını okumak<br />
</li>
<li>CSP derinlemesine: direktifler ve kaynak ifadeleri<br />
</li>
<li>Nonce ve hash ile inline script'e güvenli izin<br />
</li>
<li>Report-Only modu ve ihlal raporlarının toplanması<br />
</li>
<li>HSTS, X-Frame-Options, nosniff, Referrer-Policy, Permissions-Policy<br />
</li>
<li>Uygulama katmanında kurulum: Express (helmet), Django, PHP<br />
</li>
<li>Sık yapılan hatalar, sonuç, kaynakça ve yasal uyarı<br />
</li>
</ol>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">1) Güvenlik Başlıkları Nedir?</span></span><br />
Tarayıcı, bir yanıtı işlerken başlıkları okur ve kendi davranışını kısıtlar. Örneğin CSP, "bu sayfada yalnızca kendi alan adımdan script çalıştır" der; XSS açığı olsa bile enjekte edilen script'in çalışması engellenebilir. Başlıklar <span style="font-weight: bold;" class="mycode_b">açığın kendisini kapatmaz</span>, sömürünün etkisini azaltan ikinci savunma hattıdır (defense in depth). Girdi doğrulama ve çıktı kodlama (output encoding) yine zorunludur.<br />
<br />
<blockquote class="mycode_quote"><cite>Alıntı:</cite>Kural: Başlıklar tarayıcıda uygulanır. curl veya bir bot bu kurallara uymaz; yani CSP sunucunuzu değil, kullanıcınızın tarayıcısını korur.</blockquote>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">2) Lab: Başlıkları Okumak</span></span><br />
Önce mevcut durumu görelim. Kendi geliştirme ortamınızda (ör. localhost:3000) çalışan uygulamanız üzerinde:<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Yalnızca yanıt başlıklarını göster
curl -sI http://localhost:3000/

# Belirli başlıkları süz
curl -sI http://localhost:3000/ | grep -iE 'content-security|strict-transport|x-frame|x-content-type|referrer|permissions'</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Çıktı yorumu:</span> Hiçbir satır dönmüyorsa uygulamanız hiçbir güvenlik başlığı göndermiyor demektir. Tarayıcıda DevTools &gt; Network &gt; ilgili istek &gt; Headers sekmesinden de aynı bilgiyi görebilirsiniz. CSP ihlalleri ise Console sekmesinde ayrıca uyarı olarak çıkar.<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">3) Content Security Policy Derinlemesine</span></span><br />
CSP, direktif ve kaynak listelerinden oluşan bir politikadır. Direktifler noktalı virgülle ayrılır:<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Content-Security-Policy: default-src 'self'; img-src 'self' data:; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Temel direktifler:</span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">default-src:</span> Ayrıca tanımlanmayan fetch direktifleri için varsayılan (script-src, style-src, img-src, connect-src, font-src vb.)<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">script-src:</span> JavaScript kaynakları; XSS'e karşı en kritik direktif<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">style-src:</span> CSS kaynakları<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">connect-src:</span> fetch, XHR, WebSocket hedefleri<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">object-src 'none':</span> Eski eklenti (object/embed) içeriğini kapatır; neredeyse her sitede önerilir<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">base-uri:</span> base etiketiyle göreli URL'lerin kaçırılmasını önler<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">form-action:</span> Formların hangi adreslere gönderilebileceği<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">frame-ancestors:</span> Sayfanızı kimin iframe içine alabileceği (clickjacking koruması)<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">upgrade-insecure-requests:</span> Sayfa içindeki http alt kaynak isteklerini https'e yükseltir<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">Kaynak ifadeleri:</span> <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>'self'</code></div></div> (aynı origin: şema + host + port), <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>'none'</code></div></div>, belirli host'lar (<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>https://cdn.ornek.com</code></div></div>), şemalar (<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>data:</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>https:</code></div></div>) ve anahtar kelimeler (<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>'unsafe-inline'</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>'unsafe-eval'</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>'strict-dynamic'</code></div></div>). 'unsafe-inline' ve 'unsafe-eval' script-src içinde CSP'nin XSS korumasını büyük ölçüde boşa çıkarır; kaçının.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Meta etiketiyle CSP:</span> Başlık ekleyemediğiniz statik barındırmada politika HTML içine konabilir:<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&lt;meta http-equiv="Content-Security-Policy" content="default-src 'self'; object-src 'none'; base-uri 'self'"&gt;</code></div></div><br />
Dikkat: meta etiketi ile <span style="font-weight: bold;" class="mycode_b">frame-ancestors, report-uri ve sandbox desteklenmez</span> ve politika yalnızca etiketten sonra yüklenen içeriğe uygulanır. Mümkünse HTTP başlığını tercih edin.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">4) Nonce ve Hash ile Inline Script</span></span><br />
Inline script'leri tamamen kaldırmak en temizidir. Kaldıramıyorsanız 'unsafe-inline' yerine nonce veya hash kullanın.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Nonce:</span> Her yanıtta yeniden üretilen, tahmin edilemez rastgele bir değer. Başlıkta ve script etiketinde aynısı olmalıdır:<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Content-Security-Policy: script-src 'nonce-R4nd0mDegerHerIstekteYeni' 'strict-dynamic'; object-src 'none'; base-uri 'self'

&lt;script nonce="R4nd0mDegerHerIstekteYeni"&gt;
  initApp();
&lt;/script&gt;</code></div></div><br />
Nonce sabit kodlanırsa veya önbelleğe alınmış sayfada tekrar kullanılırsa koruma anlamını yitirir. <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>'strict-dynamic'</code></div></div>, nonce'lu güvenilir script'in yüklediği script'lere de güvenilmesini sağlar; destekleyen tarayıcılarda host listelerini göz ardı eder. Bu yaklaşım OWASP ve web.dev tarafından önerilen "strict CSP" modelidir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Hash:</span> Değişmeyen inline script için içeriğin SHA-256 özeti:<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Script içeriğinin (etiketler hariç, birebir aynı boşluklarla) hash'i
printf '%s' "initApp();" | openssl dgst -sha256 -binary | openssl base64

# Politikaya ekleme
Content-Security-Policy: script-src 'sha256-&lt;yukaridaki_cikti&gt;'</code></div></div><br />
Script içeriğinde tek bir boşluk değişirse hash tutmaz ve tarayıcı script'i engeller; Console'daki hata mesajı genellikle beklenen hash'i de gösterir.<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">5) Report-Only ve İhlal Raporları</span></span><br />
Mevcut bir uygulamaya doğrudan sıkı CSP koymak genellikle bir şeyleri bozar. Doğru yol önce <span style="font-weight: bold;" class="mycode_b">Content-Security-Policy-Report-Only</span> ile gözlemlemektir: tarayıcı hiçbir şeyi engellemez, yalnızca ihlali raporlar.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Reporting-Endpoints: csp-endpoint="https://uygulamaniz.ornek/csp-report"
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self'; report-to csp-endpoint; report-uri /csp-report</code></div></div><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">report-uri:</span> Eski yöntem, spesifikasyonda kullanımdan kaldırılıyor ama hâlâ geniş destekli. Tarayıcı JSON gövdesini application/csp-report türüyle POST eder.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">report-to:</span> Reporting API ile yeni yöntem; uç nokta adı Reporting-Endpoints başlığında tanımlanır. Geçiş döneminde ikisini birlikte kullanmak yaygındır.<br />
</li>
</ul>
<br />
Basit bir Express toplayıcı (yalnızca kendi uygulamanız için):<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>app.post('/csp-report',
  express.json({ type: ['application/csp-report', 'application/reports+json'] }),
  (req, res) =&gt; {
    console.log(JSON.stringify(req.body));   // üretimde log sistemine yazın
    res.sendStatus(204);
  });</code></div></div><br />
Raporlarda violated-directive / effective-directive ve blocked-uri alanlarına bakarak hangi kaynağı politikaya eklemeniz veya koddan kaldırmanız gerektiğine karar verin. Birkaç gün temiz rapor aldıktan sonra aynı politikayı zorlayıcı başlığa taşıyın. Rapor uç noktası herkese açık olduğundan gövde boyutunu sınırlayın ve içeriğe güvenmeyin.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">6) Diğer Başlıklar ve Tarayıcı Yorumu</span></span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Strict-Transport-Security (HSTS):</span> Tarayıcı bu başlığı yalnızca HTTPS yanıtında dikkate alır; max-age süresince o alan adına http ile gitmeyi reddeder, sertifika hatasında kullanıcıya "yine de devam et" seçeneği sunmaz.<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Strict-Transport-Security: max-age=31536000; includeSubDomains</code></div></div>preload eklemeden önce hstspreload.org gereksinimlerini okuyun; preload listesinden çıkmak uzun sürer. Kısa max-age ile başlayıp artırmak güvenli yaklaşımdır.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">X-Frame-Options:</span> DENY veya SAMEORIGIN. ALLOW-FROM eskidir, modern tarayıcılar desteklemez. Modern karşılığı CSP frame-ancestors'tır; ikisi birlikte varsa destekleyen tarayıcılar frame-ancestors'ı esas alır. Eski tarayıcılar için ikisini birlikte göndermek zararsızdır.<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors 'none'</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">X-Content-Type-Options: nosniff:</span> Tarayıcının MIME türü tahmin etmesini (sniffing) kapatır; yanlış Content-Type ile gelen script/stil engellenir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Referrer-Policy:</span> Başka siteye geçerken URL'nin ne kadarının Referer'da gideceğini belirler. <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>strict-origin-when-cross-origin</code></div></div> dengeli bir seçimdir; URL'de token taşıyorsanız <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>no-referrer</code></div></div> düşünün.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Permissions-Policy:</span> Kamera, mikrofon, konum gibi tarayıcı özelliklerini kısıtlar:<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Permissions-Policy: camera=(), microphone=(), geolocation=()</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">X-XSS-Protection:</span> Eski tarayıcı filtresi içindir, modern tarayıcılarda kaldırılmıştır. OWASP, göndermemeyi veya "0" değerini önerir; XSS koruması için CSP kullanın.<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">7) Uygulama Katmanında Kurulum</span></span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Express (helmet):</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>npm install helmet</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>const crypto = require('crypto');
const helmet = require('helmet');

app.use((req, res, next) =&gt; {
  res.locals.cspNonce = crypto.randomBytes(16).toString('base64');
  next();
});

app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'", (req, res) =&gt; `'nonce-&#36;{res.locals.cspNonce}'`],
      objectSrc: ["'none'"],
      baseUri: ["'self'"],
      frameAncestors: ["'none'"],
    },
  },
}));
// Şablonda: &lt;script nonce="&lt;%= cspNonce %&gt;"&gt;...&lt;/script&gt;</code></div></div><br />
helmet varsayılan olarak bir dizi başlık ekler; hangi değerleri gönderdiğini kendi sürümünüzde curl -I ile mutlaka doğrulayın.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Django:</span> SecurityMiddleware ve XFrameOptionsMiddleware ayarları settings.py'dedir. Django 6.0 ile yerleşik CSP desteği geldi (eski sürümlerde django-csp paketi kullanılır):<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
    "django.middleware.csp.ContentSecurityPolicyMiddleware",  # Django 6.0+
    # ...
]

SECURE_HSTS_SECONDS = 31536000          # yalnızca HTTPS tamamen hazırsa
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_CONTENT_TYPE_NOSNIFF = True
SECURE_REFERRER_POLICY = "strict-origin-when-cross-origin"
X_FRAME_OPTIONS = "DENY"

from django.utils.csp import CSP
SECURE_CSP_REPORT_ONLY = {
    "default-src": [CSP.SELF],
    "script-src": [CSP.SELF, CSP.NONCE],
    "object-src": [CSP.NONE],
    "report-uri": "/csp-report/",
}</code></div></div><br />
Şablonda nonce için csp context processor'ı (django.template.context_processors.csp) etkinleştirip <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&lt;script nonce="{{ csp_nonce }}"&gt;</code></div></div> kullanın. Ayarları kontrol etmek için:<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>python manage.py check --deploy</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">PHP:</span> header() çağrıları herhangi bir çıktıdan önce yapılmalıdır:<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&lt;?php
&#36;nonce = base64_encode(random_bytes(16));
header("Content-Security-Policy: default-src 'self'; script-src 'nonce-&#36;nonce' 'strict-dynamic'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'");
header("X-Content-Type-Options: nosniff");
header("Referrer-Policy: strict-origin-when-cross-origin");
?&gt;
&lt;script nonce="&lt;?= htmlspecialchars(&#36;nonce) ?&gt;"&gt;initApp();&lt;/script&gt;</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">8) Sık Yapılan Hatalar</span></span><ul class="mycode_list"><li>script-src içinde 'unsafe-inline' bırakmak (nonce/hash varken destekleyen tarayıcılar onu yok sayar, ama tek başına korumayı boşa çıkarır)<br />
</li>
<li>Aynı başlığı hem uygulamada hem ters vekilde farklı değerlerle eklemek; birden fazla CSP başlığında tarayıcı hepsini birden uygular, sonuç beklenenden sıkı olur<br />
</li>
<li>Nonce'u sabit yazmak veya tam sayfa önbelleğinde kullanıcılar arasında paylaştırmak<br />
</li>
<li>Report-Only'de kalıp politikayı hiç zorlayıcı moda almamak<br />
</li>
<li>HTTPS hazır değilken uzun max-age ile HSTS ya da preload göndermek<br />
</li>
<li>CDN alan adının tamamına izin vermek (ör. tüm bir paylaşımlı CDN); saldırgan aynı CDN'e dosya koyabiliyorsa politika aşılabilir<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">9) Sonuç</span></span><br />
Güvenlik başlıkları ucuz ama güçlü bir katmandır. Sıralama önerim: önce nosniff, Referrer-Policy ve frame koruması; ardından CSP'yi Report-Only ile başlatıp raporlarla olgunlaştırmak; en son nonce tabanlı strict CSP'yi zorlamak. Politikanızı Google'ın CSP Evaluator aracıyla gözden geçirip her sürümde curl -I ile doğrulayın.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Kaynakça</span></span><ul class="mycode_list"><li><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP" target="_blank" rel="noopener" class="mycode_url">MDN - Content Security Policy (CSP)</a><br />
</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy" target="_blank" rel="noopener" class="mycode_url">MDN - Content-Security-Policy başlık referansı</a><br />
</li>
<li><a href="https://www.w3.org/TR/CSP3/" target="_blank" rel="noopener" class="mycode_url">W3C - Content Security Policy Level 3</a><br />
</li>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/Content_Security_Policy_Cheat_Sheet.html" target="_blank" rel="noopener" class="mycode_url">OWASP CSP Cheat Sheet</a><br />
</li>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html" target="_blank" rel="noopener" class="mycode_url">OWASP HTTP Security Response Headers Cheat Sheet</a><br />
</li>
<li><a href="https://owasp.org/www-project-secure-headers/" target="_blank" rel="noopener" class="mycode_url">OWASP Secure Headers Project</a><br />
</li>
<li><a href="https://datatracker.ietf.org/doc/html/rfc6797" target="_blank" rel="noopener" class="mycode_url">RFC 6797 - HTTP Strict Transport Security</a><br />
</li>
<li><a href="https://datatracker.ietf.org/doc/html/rfc7034" target="_blank" rel="noopener" class="mycode_url">RFC 7034 - X-Frame-Options</a><br />
</li>
<li><a href="https://helmetjs.github.io/" target="_blank" rel="noopener" class="mycode_url">Helmet.js dokümantasyonu</a><br />
</li>
<li><a href="https://docs.djangoproject.com/en/6.0/ref/csp/" target="_blank" rel="noopener" class="mycode_url">Django - Content Security Policy</a><br />
</li>
<li><a href="https://web.dev/articles/strict-csp" target="_blank" rel="noopener" class="mycode_url">web.dev - Strict CSP</a><br />
</li>
<li><a href="https://csp-evaluator.withgoogle.com/" target="_blank" rel="noopener" class="mycode_url">Google CSP Evaluator</a><br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Yasal Uyarı</span></span><br />
Bu rehber kendi uygulamalarınızı korumak içindir. Başlık ve politika testlerini yalnızca kendi sistemlerinizde veya yazılı yetkili pentest kapsamında yapın. Başkasına ait sistemlere izinsiz erişim veya müdahale TCK <span style="font-weight: bold;" class="mycode_b">243-245</span> ve ilgili maddeler kapsamında suç olabilir. Eğitim amaçlıdır.<br />
<br />
<span style="font-style: italic;" class="mycode_i">Yasal uyarı: Bu içerik eğitim amaçlıdır. Yalnızca kendi sistemlerinizde veya yazılı izin aldığınız hedeflerde uygulayın (TCK 243-245).</span><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=205" target="_blank" title="">000-team-new-3ddc97.png</a> (Dosya Boyutu: 71.82 KB / İndirme Sayısı: 7)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Dosya Yükleme File Upload Açıkları ve Güvenli Doğrulama Rehberi]]></title>
			<link>https://www.turkteam.org/konu-dosya-yukleme-file-upload-aciklari-ve-guvenli-dogrulama-rehberi.html</link>
			<pubDate>Sun, 18 Oct 2026 11:45:10 +0300</pubDate>
			<dc:creator><![CDATA[<a href="https://www.turkteam.org/member.php?action=profile&uid=3">BilgeKagan</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.turkteam.org/konu-dosya-yukleme-file-upload-aciklari-ve-guvenli-dogrulama-rehberi.html</guid>
			<description><![CDATA[[center]<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=168" loading="lazy"  alt="[Resim: attachment.php?aid=168]" class="mycode_img" /></div>[/center]<br />
<br />
Selam TurkTeam, BlueTornado ile devam.<br />
<br />
Dosya yükleme özelliği; profil fotoğrafı, ek, CV, fatura gibi meşru ihtiyaçlar için vardır. Yanlış uygulanırsa webshell yükleme, XSS (SVG/HTML), path traversal, depolama tüketimi (DoS) ve sunucu tarafı parse açıklarına yol açar. Bu rehber <span style="font-weight: bold;" class="mycode_b">güvenli doğrulama</span> odaklıdır; örnekler DVWA ve kendi labınız içindir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Konuda Anlatılacaklar</span></span><br />
<ol type="1" class="mycode_list"><li>File upload riskleri nelerdir?<br />
</li>
<li>DVWA File Upload labı<br />
</li>
<li>Tehlikeli doğrulama hataları<br />
</li>
<li>Savunma katmanları: tip, içerik, depolama, sunum<br />
</li>
<li>Uygulamalı güvenli tasarım<br />
</li>
<li>İleri seviye: SVG, zip slip, malware tarama<br />
</li>
<li>Kaynakça ve yasal uyarı<br />
</li>
</ol>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">1) Riskler</span></span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Uzaktan kod çalıştırma:</span> <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>.php</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>.jsp</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>.aspx</code></div></div> webshell'in web köküne yazılması<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">XSS:</span> <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>.html</code></div></div> / <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>.svg</code></div></div> dosyasının aynı origin'den sunulması<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Path traversal:</span> <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>../../var/www/shell.php</code></div></div> dosya adı<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Overwrite:</span> mevcut kritik dosyanın üzerine yazma<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Zip Slip:</span> arşiv açarken dizin kaçışı<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">DoS:</span> çok büyük dosya, zip bomb<br />
</li>
</ul>
<br />
OWASP WSTG içinde "Testing for Uploaded File Attacks" bölümü bu aileyi kapsar. CWE örnekleri: CWE-434 (Unrestricted Upload of File with Dangerous Type).<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">2) Lab: DVWA File Upload</span></span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>docker compose -f DVWA/docker-compose.yml up -d
# Security Low -&gt; File Upload</code></div></div><br />
Low seviyede çoğu kurulum yalnızca istemci tarafı veya basit uzantı kontrolü yapar. Impossible seviyede içerik tipi ve depolama sertleştirmesi vardır.<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Gözlem adımları (lab):</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># 1) Küçük bir PNG yükleyin, yükleme yolunu not alın
# 2) Uzantı / Content-Type oyunlarını lab politikasına göre gözlemleyin
# 3) Impossible ile farkı karşılaştırın</code></div></div><br />
Webshell yüklemeyi üretimde veya izinsiz sistemlerde denemeyin. Labda bile yüklediğiniz dosyaları işiniz bitince silin.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">3) Yaygın Hatalı Kontroller</span></span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Sadece istemci tarafı:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&lt;!-- Kolayca bypass: DevTools ile accept kaldırma --&gt;
&lt;input type="file" accept="image/*"&gt;</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Sadece uzantı kara listesi:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># .php engelli ama .php5 .phtml .phar .jpg.php ?
# Sunucu yapılandırmasına bağlı</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Sadece Content-Type başlığı:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Content-Type: image/png
# İstemci istediğini yazar; güvenilmez</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">MIME sniffing/<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>file</code></div></div> komutu tek başına:</span> Polyglot dosyalar (hem geçerli görüntü hem script) tarih boyunca görülmüştür; yine de sunucu tarafı MIME tahmini + uzantı allowlist birlikte kullanılmalıdır.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">4) Güvenli Doğrulama Katmanları</span></span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">1 - Allowlist:</span> Yalnızca iş ihtiyacı olan uzantılar (<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>jpg jpeg png webp pdf</code></div></div>).<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2 - Rastgele dosya adı:</span> Kullanıcı adını kullanmayın.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>import uuid
from pathlib import PurePosixPath
ext = PurePosixPath(filename).suffix.lower()
if ext not in {".jpg", ".jpeg", ".png", ".webp"}:
    raise ValueError("uzantı yok")
stored = f"{uuid.uuid4().hex}{ext}"</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">3 - İçerik doğrulama:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>from PIL import Image
img = Image.open(upload_stream)
img.verify()  # bozuk/şüpheli dosyayı ele
# Yeniden encode ederek metadata/polyglot riskini azaltın
Image.open(upload_stream).save(out_path, format="JPEG")</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">4 - Depolama konumu:</span> Dosyaları web kökü dışına veya yalnızca statik object storage'a koyun. Uygulama sunucusunun yorumladığı dizine yazmayın.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5 - Sunum:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># İndirme için
Content-Disposition: attachment; filename="rapor.pdf"
X-Content-Type-Options: nosniff
Content-Type: application/pdf</code></div></div>SVG/HTML'i aynı origin'de inline açmayın; mümkünse ayrı domain (static.example) kullanın.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6 - Boyut ve hız sınırı:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Nginx örneği
client_max_body_size 5m;</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">5) Uygulamalı Güvenli İskelet</span></span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Flask kavramsal özet
ALLOWED = {"jpg", "jpeg", "png"}
MAX = 5 * 1024 * 1024

def save_avatar(file_storage):
    if file_storage.content_length and file_storage.content_length &gt; MAX:
        abort(400)
    name = file_storage.filename or ""
    ext = name.rsplit(".", 1)[-1].lower()
    if ext not in ALLOWED:
        abort(400)
    # PIL verify + re-encode
    # kaydet: /var/app/uploads/{uuid}.jpg  (web root dışı)
    # sun: imza/lı URL veya ayrı static host</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># PHP move_uploaded_file + finfo allowlist (kavramsal)
&#36;finfo = new finfo(FILEINFO_MIME_TYPE);
&#36;mime = &#36;finfo-&gt;file(&#36;_FILES['u']['tmp_name']);
&#36;allowed = ['image/jpeg' =&gt; 'jpg', 'image/png' =&gt; 'png'];
if (!isset(&#36;allowed[&#36;mime])) { http_response_code(400); exit; }</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">6) İleri Seviye</span></span><br />
<span style="font-weight: bold;" class="mycode_b">SVG:</span> İçinde JavaScript / external entity olabilir. Avatar için SVG kabul etmeyin veya sıkı sanitizer + ayrı domain kullanın.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Zip Slip:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Tehlikeli arşiv girdileri
../../../../tmp/evil
# Açarken final path'in hedef dizin altında kaldığını doğrulayın</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Malware tarama:</span> ClamAV vb. ile async tarama; temizlenmeden public yapmayın.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">ImageMagick / parse CVE'leri:</span> Görüntü işleme kütüphanelerini güncel tutun; policy.xml ile coder'ları kısıtlayın. İcat CVE numarası yazmayın; NVD'den doğrulayın.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Rapor dili
Bulgu: Unrestricted File Upload (CWE-434)
Kanıt: Labda tehlikeli tipin web köküne yazılması
Öneri: allowlist + re-encode + web root dışı + nosniff</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">7) Sonuç</span></span><br />
Dosya yükleme, "uzantıya bakmak"tan ibaret değildir. Allowlist, içerik doğrulama, güvenli depolama ve güvenli sunum birlikte gerekir. DVWA Low/Impossible farkını inceleyerek kendi uygulamanızın kontrol listesini çıkarın.<br />
<br />
<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Ek: Operasyonel Kontrol Listesi ve Yaygın Senaryolar</span></span><br />
<span style="font-weight: bold;" class="mycode_b">Profil fotoğrafı:</span> Yalnızca raster; yeniden encode; sabit max boyut (ör. 1024px); EXIF temizliği (konum sızıntısı).<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># ImageMagick (güncel sürüm + policy) ile yeniden örnekleme kavramı
# convert input.jpg -resize 1024x1024&gt; -strip out.jpg</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">PDF yükleme:</span> PDF içinde JavaScript / form aksiyonları olabilir. Inline göstermek yerine <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Content-Disposition: attachment</code></div></div> veya güvenilir bir önizleme servisi kullanın.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Çok parçalı / chunked upload:</span> Her parçayı ayrı doğrulayın; birleştirme sonrası tekrar MIME/uzantı kontrolü yapın; geçici dosyaları güvenli dizinde tutun.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># S3 / MinIO politikası kavramı
# public-read vermeyin; pre-signed URL ile süreli erişim
# bucket'ta website hosting açıkken html/svg yüklemeyin</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">CI kontrolü:</span> Yükleme ile ilgili birim testleri: path traversal dosya adı reddi, aşırı boyut reddi, yanlış MIME reddi, başarılı PNG yolu.<br />
<br />
[center][/center]<br />
<br />
Yükleme özelliği ürün için vazgeçilmezse, güvenlik bütçesini "sonra bakarız"a bırakmayın; tasarım aşamasında depolama ve sunum kararlarını kilitleyin.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Kaynakça</span></span><ul class="mycode_list"><li><a href="https://owasp.org/www-community/vulnerabilities/Unrestricted_File_Upload" target="_blank" rel="noopener" class="mycode_url">OWASP Unrestricted File Upload</a><br />
</li>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html" target="_blank" rel="noopener" class="mycode_url">OWASP File Upload Cheat Sheet</a><br />
</li>
<li><a href="https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/10-Business_Logic_Testing/09-Test_Upload_of_Malicious_Files" target="_blank" rel="noopener" class="mycode_url">WSTG - Malicious File Upload</a><br />
</li>
<li><a href="https://cwe.mitre.org/data/definitions/434.html" target="_blank" rel="noopener" class="mycode_url">CWE-434</a><br />
</li>
<li><a href="https://github.com/digininja/DVWA" target="_blank" rel="noopener" class="mycode_url">DVWA</a><br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Yasal Uyarı</span></span><br />
Zararlı dosya yükleme ve webshell denemeleri yalnızca kendi labınızda veya yazılı yetki ile yapılmalıdır. İzinsiz yükleme TCK <span style="font-weight: bold;" class="mycode_b">243-245</span> kapsamında suçtur. Eğitim amaçlıdır; sorumluluk uygulayana aittir.<br />
<br />
<span style="font-style: italic;" class="mycode_i">Yasal uyarı: Bu içerik eğitim amaçlıdır. Yalnızca kendi sistemlerinizde veya yazılı izin aldığınız hedeflerde uygulayın (TCK 243-245).</span><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=168" target="_blank" title="">000-team-new-1bf799.png</a> (Dosya Boyutu: 67.49 KB / İndirme Sayısı: 8)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[[center]<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=168" loading="lazy"  alt="[Resim: attachment.php?aid=168]" class="mycode_img" /></div>[/center]<br />
<br />
Selam TurkTeam, BlueTornado ile devam.<br />
<br />
Dosya yükleme özelliği; profil fotoğrafı, ek, CV, fatura gibi meşru ihtiyaçlar için vardır. Yanlış uygulanırsa webshell yükleme, XSS (SVG/HTML), path traversal, depolama tüketimi (DoS) ve sunucu tarafı parse açıklarına yol açar. Bu rehber <span style="font-weight: bold;" class="mycode_b">güvenli doğrulama</span> odaklıdır; örnekler DVWA ve kendi labınız içindir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Konuda Anlatılacaklar</span></span><br />
<ol type="1" class="mycode_list"><li>File upload riskleri nelerdir?<br />
</li>
<li>DVWA File Upload labı<br />
</li>
<li>Tehlikeli doğrulama hataları<br />
</li>
<li>Savunma katmanları: tip, içerik, depolama, sunum<br />
</li>
<li>Uygulamalı güvenli tasarım<br />
</li>
<li>İleri seviye: SVG, zip slip, malware tarama<br />
</li>
<li>Kaynakça ve yasal uyarı<br />
</li>
</ol>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">1) Riskler</span></span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Uzaktan kod çalıştırma:</span> <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>.php</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>.jsp</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>.aspx</code></div></div> webshell'in web köküne yazılması<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">XSS:</span> <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>.html</code></div></div> / <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>.svg</code></div></div> dosyasının aynı origin'den sunulması<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Path traversal:</span> <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>../../var/www/shell.php</code></div></div> dosya adı<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Overwrite:</span> mevcut kritik dosyanın üzerine yazma<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Zip Slip:</span> arşiv açarken dizin kaçışı<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">DoS:</span> çok büyük dosya, zip bomb<br />
</li>
</ul>
<br />
OWASP WSTG içinde "Testing for Uploaded File Attacks" bölümü bu aileyi kapsar. CWE örnekleri: CWE-434 (Unrestricted Upload of File with Dangerous Type).<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">2) Lab: DVWA File Upload</span></span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>docker compose -f DVWA/docker-compose.yml up -d
# Security Low -&gt; File Upload</code></div></div><br />
Low seviyede çoğu kurulum yalnızca istemci tarafı veya basit uzantı kontrolü yapar. Impossible seviyede içerik tipi ve depolama sertleştirmesi vardır.<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Gözlem adımları (lab):</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># 1) Küçük bir PNG yükleyin, yükleme yolunu not alın
# 2) Uzantı / Content-Type oyunlarını lab politikasına göre gözlemleyin
# 3) Impossible ile farkı karşılaştırın</code></div></div><br />
Webshell yüklemeyi üretimde veya izinsiz sistemlerde denemeyin. Labda bile yüklediğiniz dosyaları işiniz bitince silin.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">3) Yaygın Hatalı Kontroller</span></span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Sadece istemci tarafı:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&lt;!-- Kolayca bypass: DevTools ile accept kaldırma --&gt;
&lt;input type="file" accept="image/*"&gt;</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Sadece uzantı kara listesi:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># .php engelli ama .php5 .phtml .phar .jpg.php ?
# Sunucu yapılandırmasına bağlı</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Sadece Content-Type başlığı:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Content-Type: image/png
# İstemci istediğini yazar; güvenilmez</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">MIME sniffing/<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>file</code></div></div> komutu tek başına:</span> Polyglot dosyalar (hem geçerli görüntü hem script) tarih boyunca görülmüştür; yine de sunucu tarafı MIME tahmini + uzantı allowlist birlikte kullanılmalıdır.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">4) Güvenli Doğrulama Katmanları</span></span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">1 - Allowlist:</span> Yalnızca iş ihtiyacı olan uzantılar (<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>jpg jpeg png webp pdf</code></div></div>).<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2 - Rastgele dosya adı:</span> Kullanıcı adını kullanmayın.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>import uuid
from pathlib import PurePosixPath
ext = PurePosixPath(filename).suffix.lower()
if ext not in {".jpg", ".jpeg", ".png", ".webp"}:
    raise ValueError("uzantı yok")
stored = f"{uuid.uuid4().hex}{ext}"</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">3 - İçerik doğrulama:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>from PIL import Image
img = Image.open(upload_stream)
img.verify()  # bozuk/şüpheli dosyayı ele
# Yeniden encode ederek metadata/polyglot riskini azaltın
Image.open(upload_stream).save(out_path, format="JPEG")</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">4 - Depolama konumu:</span> Dosyaları web kökü dışına veya yalnızca statik object storage'a koyun. Uygulama sunucusunun yorumladığı dizine yazmayın.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5 - Sunum:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># İndirme için
Content-Disposition: attachment; filename="rapor.pdf"
X-Content-Type-Options: nosniff
Content-Type: application/pdf</code></div></div>SVG/HTML'i aynı origin'de inline açmayın; mümkünse ayrı domain (static.example) kullanın.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6 - Boyut ve hız sınırı:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Nginx örneği
client_max_body_size 5m;</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">5) Uygulamalı Güvenli İskelet</span></span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Flask kavramsal özet
ALLOWED = {"jpg", "jpeg", "png"}
MAX = 5 * 1024 * 1024

def save_avatar(file_storage):
    if file_storage.content_length and file_storage.content_length &gt; MAX:
        abort(400)
    name = file_storage.filename or ""
    ext = name.rsplit(".", 1)[-1].lower()
    if ext not in ALLOWED:
        abort(400)
    # PIL verify + re-encode
    # kaydet: /var/app/uploads/{uuid}.jpg  (web root dışı)
    # sun: imza/lı URL veya ayrı static host</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># PHP move_uploaded_file + finfo allowlist (kavramsal)
&#36;finfo = new finfo(FILEINFO_MIME_TYPE);
&#36;mime = &#36;finfo-&gt;file(&#36;_FILES['u']['tmp_name']);
&#36;allowed = ['image/jpeg' =&gt; 'jpg', 'image/png' =&gt; 'png'];
if (!isset(&#36;allowed[&#36;mime])) { http_response_code(400); exit; }</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">6) İleri Seviye</span></span><br />
<span style="font-weight: bold;" class="mycode_b">SVG:</span> İçinde JavaScript / external entity olabilir. Avatar için SVG kabul etmeyin veya sıkı sanitizer + ayrı domain kullanın.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Zip Slip:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Tehlikeli arşiv girdileri
../../../../tmp/evil
# Açarken final path'in hedef dizin altında kaldığını doğrulayın</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Malware tarama:</span> ClamAV vb. ile async tarama; temizlenmeden public yapmayın.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">ImageMagick / parse CVE'leri:</span> Görüntü işleme kütüphanelerini güncel tutun; policy.xml ile coder'ları kısıtlayın. İcat CVE numarası yazmayın; NVD'den doğrulayın.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Rapor dili
Bulgu: Unrestricted File Upload (CWE-434)
Kanıt: Labda tehlikeli tipin web köküne yazılması
Öneri: allowlist + re-encode + web root dışı + nosniff</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">7) Sonuç</span></span><br />
Dosya yükleme, "uzantıya bakmak"tan ibaret değildir. Allowlist, içerik doğrulama, güvenli depolama ve güvenli sunum birlikte gerekir. DVWA Low/Impossible farkını inceleyerek kendi uygulamanızın kontrol listesini çıkarın.<br />
<br />
<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Ek: Operasyonel Kontrol Listesi ve Yaygın Senaryolar</span></span><br />
<span style="font-weight: bold;" class="mycode_b">Profil fotoğrafı:</span> Yalnızca raster; yeniden encode; sabit max boyut (ör. 1024px); EXIF temizliği (konum sızıntısı).<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># ImageMagick (güncel sürüm + policy) ile yeniden örnekleme kavramı
# convert input.jpg -resize 1024x1024&gt; -strip out.jpg</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">PDF yükleme:</span> PDF içinde JavaScript / form aksiyonları olabilir. Inline göstermek yerine <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Content-Disposition: attachment</code></div></div> veya güvenilir bir önizleme servisi kullanın.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Çok parçalı / chunked upload:</span> Her parçayı ayrı doğrulayın; birleştirme sonrası tekrar MIME/uzantı kontrolü yapın; geçici dosyaları güvenli dizinde tutun.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># S3 / MinIO politikası kavramı
# public-read vermeyin; pre-signed URL ile süreli erişim
# bucket'ta website hosting açıkken html/svg yüklemeyin</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">CI kontrolü:</span> Yükleme ile ilgili birim testleri: path traversal dosya adı reddi, aşırı boyut reddi, yanlış MIME reddi, başarılı PNG yolu.<br />
<br />
[center][/center]<br />
<br />
Yükleme özelliği ürün için vazgeçilmezse, güvenlik bütçesini "sonra bakarız"a bırakmayın; tasarım aşamasında depolama ve sunum kararlarını kilitleyin.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Kaynakça</span></span><ul class="mycode_list"><li><a href="https://owasp.org/www-community/vulnerabilities/Unrestricted_File_Upload" target="_blank" rel="noopener" class="mycode_url">OWASP Unrestricted File Upload</a><br />
</li>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html" target="_blank" rel="noopener" class="mycode_url">OWASP File Upload Cheat Sheet</a><br />
</li>
<li><a href="https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/10-Business_Logic_Testing/09-Test_Upload_of_Malicious_Files" target="_blank" rel="noopener" class="mycode_url">WSTG - Malicious File Upload</a><br />
</li>
<li><a href="https://cwe.mitre.org/data/definitions/434.html" target="_blank" rel="noopener" class="mycode_url">CWE-434</a><br />
</li>
<li><a href="https://github.com/digininja/DVWA" target="_blank" rel="noopener" class="mycode_url">DVWA</a><br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Yasal Uyarı</span></span><br />
Zararlı dosya yükleme ve webshell denemeleri yalnızca kendi labınızda veya yazılı yetki ile yapılmalıdır. İzinsiz yükleme TCK <span style="font-weight: bold;" class="mycode_b">243-245</span> kapsamında suçtur. Eğitim amaçlıdır; sorumluluk uygulayana aittir.<br />
<br />
<span style="font-style: italic;" class="mycode_i">Yasal uyarı: Bu içerik eğitim amaçlıdır. Yalnızca kendi sistemlerinizde veya yazılı izin aldığınız hedeflerde uygulayın (TCK 243-245).</span><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=168" target="_blank" title="">000-team-new-1bf799.png</a> (Dosya Boyutu: 67.49 KB / İndirme Sayısı: 8)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[API Güvenliği ve OWASP API Top 10: BOLA BFLA ve Temel Kontroller]]></title>
			<link>https://www.turkteam.org/konu-api-guvenligi-ve-owasp-api-top-10-bola-bfla-ve-temel-kontroller.html</link>
			<pubDate>Sun, 18 Oct 2026 11:12:18 +0300</pubDate>
			<dc:creator><![CDATA[<a href="https://www.turkteam.org/member.php?action=profile&uid=3">BilgeKagan</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.turkteam.org/konu-api-guvenligi-ve-owasp-api-top-10-bola-bfla-ve-temel-kontroller.html</guid>
			<description><![CDATA[[center]<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=147" loading="lazy"  alt="[Resim: attachment.php?aid=147]" class="mycode_img" /></div>[/center]<br />
<br />
Selam millet, BlueTornado yazıyor.<br />
<br />
Modern uygulamaların yüzeyi çoğu zaman HTML formlarından çok JSON API'lerdir. OWASP API Security Top 10, bu yüzeyi hedefleyen riskleri listeler. Bu rehberde 2023 sürümüne odaklanarak özellikle <span style="font-weight: bold;" class="mycode_b">BOLA</span> ve <span style="font-weight: bold;" class="mycode_b">BFLA</span>'yı, labda test yaklaşımını ve savunma kontrollerini anlatıyoruz. İcat istatistik veya uydurma CVE yok; resmi OWASP dokümanına bağlı kalıyoruz.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Konuda Anlatılacaklar</span></span><br />
<ol type="1" class="mycode_list"><li>API güvenliği neden ayrı ele alınır?<br />
</li>
<li>OWASP API Top 10 2023 özeti<br />
</li>
<li>BOLA (object) ve BFLA (function) derinlemesine<br />
</li>
<li>Lab: basit API ile A/B hesap testi<br />
</li>
<li>Korunma: authn/authz, rate limit, şema<br />
</li>
<li>İleri seviye: GraphQL, mass assignment, envanter<br />
</li>
<li>Kaynakça ve yasal uyarı<br />
</li>
</ol>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">1) API Güvenliği Nedir?</span></span><br />
API'ler makine-okur, otomasyona açıktır, mobil/SPA/partner entegrasyonlarını besler. UI'da gizlenen bir düğme API'de hâlâ duruyor olabilir. Kimlik doğrulama (authentication) ile yetkilendirme (authorization) karıştırılmamalıdır: "Token var" yetki demek değildir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">2) OWASP API Top 10 2023 Özeti</span></span><br />
Resmi liste (kısa Türkçe karşılıklarıyla):<ul class="mycode_list"><li>API1:2023 Broken Object Level Authorization (BOLA)<br />
</li>
<li>API2:2023 Broken Authentication<br />
</li>
<li>API3:2023 Broken Object Property Level Authorization<br />
</li>
<li>API4:2023 Unrestricted Resource Consumption<br />
</li>
<li>API5:2023 Broken Function Level Authorization (BFLA)<br />
</li>
<li>API6:2023 Unrestricted Access to Sensitive Business Flows<br />
</li>
<li>API7:2023 Server Side Request Forgery<br />
</li>
<li>API8:2023 Security Misconfiguration<br />
</li>
<li>API9:2023 Improper Inventory Management<br />
</li>
<li>API10:2023 Unsafe Consumption of APIs<br />
</li>
</ul>
<br />
Detay için <a href="https://owasp.org/API-Security/" target="_blank" rel="noopener" class="mycode_url">OWASP API Security Project</a> sayfasına bakın. Sürüm yılını raporlarınızda belirtin.<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">3) BOLA Nedir?</span></span><br />
Broken Object Level Authorization, web'deki IDOR'un API dilindeki adıdır. Kullanıcı, erişmemesi gereken nesneye kimlik (id) ile ulaşır.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Tehlikeli
GET /api/v1/users/214/orders
# Authorization yalnızca "login oldu mu?" seviyesinde</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Doğru yön
order = repo.get(order_id)
if order.owner_id != current_user.id:
    raise Forbidden()</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">4) BFLA Nedir?</span></span><br />
Broken Function Level Authorization, işlev düzeyinde yetki eksikliğidir. Özellikle admin uçlarının gizlenerek "güvende" sanılması.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>DELETE /api/v1/admin/users/214
POST /api/v1/admin/settings/maintenance
# UI'da admin menüsü yok ama endpoint açık</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Rol kontrolü
if "admin" not in current_user.roles:
    raise Forbidden()</code></div></div><br />
BOLA nesne sahipliğine, BFLA ise role/işleve bakar; ikisi birlikte test edilmelidir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">5) Lab: Mini API Testi</span></span><br />
Kendi bilgisayarınızda iki kullanıcı oluşturabileceğiniz bir lab API'si kullanın (Juice Shop API, crAPI, veya kendi Flask iskeletiniz).<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># A kullanıcısı token
TOKEN_A=...
TOKEN_B=...

# A kendi kaynağını okur
curl -s -H "Authorization: Bearer &#36;TOKEN_A" http://127.0.0.1:8000/api/orders/1

# A, B'nin order id'sini dener
curl -s -o /tmp/out -w "%{http_code}" -H "Authorization: Bearer &#36;TOKEN_A" &#92;
  http://127.0.0.1:8000/api/orders/2
# 403/404 beklenir; 200 + B verisi = BOLA</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># BFLA denemesi
curl -s -o /tmp/out -w "%{http_code}" -H "Authorization: Bearer &#36;TOKEN_A" &#92;
  -X DELETE http://127.0.0.1:8000/api/admin/users/2
# 403 beklenir</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">6) Kavram Referansı ve Korunma</span></span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Object property level (API3):</span> Kullanıcı nesneyi görebilir ama <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>is_admin</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>salary</code></div></div> alanlarını okuyamamalı / yazamamalıdır (mass assignment ile bağlantılı).<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Allowlist serialize
return {"id": o.id, "item": o.item, "status": o.status}
# role, internal_notes yok</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Resource consumption (API4):</span> Rate limit, pagination tavanı, max page size, maliyetli aramalar için kota.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Örnek (nginx / API gateway)
limit_req_zone &#36;binary_remote_addr zone=api:10m rate=5r/s;</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Inventory (API9):</span> Eski <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>/v1</code></div></div> unutulmuş, shadow API, document edilmemiş debug uçları. OpenAPI envanteri tutun; gateway'de yalnızca bilinen route'ları açın.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># OpenAPI'de tanımlı olmayan yolu reddet (gateway politikası)</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Authn (API2):</span> Credential stuffing'e karşı rate limit + MFA; JWT için bir önceki konudaki kurallar.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">7) Uygulamalı Kontrol Listesi</span></span><ul class="mycode_list"><li>Her endpoint için: kim çağırabilir, hangi nesneler?<br />
</li>
<li>A/B hesap otomasyon testi CI'da<br />
</li>
<li>Admin prefix'leri ayrı authz middleware<br />
</li>
<li>Response'ta fazla alan sızıntısı var mı?<br />
</li>
<li>Rate limit ve payload size limit<br />
</li>
<li>WAF/gateway + uygulama içi kontrol (defense in depth)<br />
</li>
<li>Log: authz deny olayları<br />
</li>
</ul>
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Pseudo test
def test_bola_forbidden(client, user_a, order_of_b):
    r = client.get(f"/api/orders/{order_of_b.id}", headers=auth(user_a))
    assert r.status_code in (403, 404)</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">8) İleri Seviye</span></span><br />
<span style="font-weight: bold;" class="mycode_b">GraphQL:</span> Tek endpoint; field-level authz, query depth/cost limit, introspection'ı production'da kapatma.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">BFLA keşfi:</span> OpenAPI / JS bundle içinde <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>/admin</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>role</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>internal</code></div></div> string araması (kendi uygulamanız).<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Unsafe consumption (API10):</span> Üçüncü parti API yanıtına güvenerek komut/SQL birleştirmeyin; şema doğrulayın.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Rapor
Bulgu: BOLA (API1:2023) / CWE-639
Endpoint: GET /api/orders/{id}
Kanıt: Kullanıcı A, B siparişini 200 ile okudu
Öneri: object-level authz + otomatik test</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">9) Sonuç</span></span><br />
API güvenliği, UI güvenlik varsayımlarını taşımaz. BOLA ve BFLA en sık atlanan yetki hatalarıdır; rate limit, şema ve envanter ile tamamlayın. OWASP API Top 10'u ekip içinde ortak dil yapın.<br />
<br />
<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Ek: Partner API ve Versiyonlama Notları</span></span><br />
Dışarıya açılan partner API'lerinde ek olarak:<ul class="mycode_list"><li>İstemci kimliği başına ayrı kimlik bilgisi ve scope<br />
</li>
<li>IP allowlist (mümkünse) + mTLS (yüksek güvenlikli B2B)<br />
</li>
<li>Değişiklik yönetimi: breaking change için yeni versiyon<br />
</li>
<li>Eski versiyonun kapatılma tarihi (inventory ile bağlantılı)<br />
</li>
</ul>
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Scope örneği
Authorization: Bearer ...
# token içinde scope: "orders:read"
# orders:write gerektiren endpoint'te reddedin</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Sayfalama tavanı
GET /api/orders?limit=1000  -&gt; 400 Bad Request (max 50)</code></div></div><br />
[center][/center]<br />
<br />
API Top 10 maddelerini sprint Definition of Done listesine tek satırlık kontroller olarak eklemek, "sonra bakarız" riskini azaltır.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Kaynakça</span></span><ul class="mycode_list"><li><a href="https://owasp.org/API-Security/editions/2023/en/0x00-header/" target="_blank" rel="noopener" class="mycode_url">OWASP API Security Top 10 2023</a><br />
</li>
<li><a href="https://owasp.org/API-Security/editions/2023/en/0xa1-broken-object-level-authorization/" target="_blank" rel="noopener" class="mycode_url">API1 BOLA</a><br />
</li>
<li><a href="https://owasp.org/API-Security/editions/2023/en/0xa5-broken-function-level-authorization/" target="_blank" rel="noopener" class="mycode_url">API5 BFLA</a><br />
</li>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/REST_Security_Cheat_Sheet.html" target="_blank" rel="noopener" class="mycode_url">OWASP REST Security Cheat Sheet</a><br />
</li>
<li><a href="https://cwe.mitre.org/data/definitions/285.html" target="_blank" rel="noopener" class="mycode_url">CWE-285 Improper Authorization</a><br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Yasal Uyarı</span></span><br />
API testleri yalnızca kendi sistemleriniz veya yazılı pentest yetkisi kapsamında yapılmalıdır. İzinsiz API tarama ve veri erişimi TCK <span style="font-weight: bold;" class="mycode_b">243-245</span> kapsamında suç olabilir. Eğitim amaçlıdır.<br />
<br />
<span style="font-style: italic;" class="mycode_i">Yasal uyarı: Bu içerik eğitim amaçlıdır. Yalnızca kendi sistemlerinizde veya yazılı izin aldığınız hedeflerde uygulayın (TCK 243-245).</span><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=147" target="_blank" title="">000-team-new-de9d96.png</a> (Dosya Boyutu: 64.92 KB / İndirme Sayısı: 7)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[[center]<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=147" loading="lazy"  alt="[Resim: attachment.php?aid=147]" class="mycode_img" /></div>[/center]<br />
<br />
Selam millet, BlueTornado yazıyor.<br />
<br />
Modern uygulamaların yüzeyi çoğu zaman HTML formlarından çok JSON API'lerdir. OWASP API Security Top 10, bu yüzeyi hedefleyen riskleri listeler. Bu rehberde 2023 sürümüne odaklanarak özellikle <span style="font-weight: bold;" class="mycode_b">BOLA</span> ve <span style="font-weight: bold;" class="mycode_b">BFLA</span>'yı, labda test yaklaşımını ve savunma kontrollerini anlatıyoruz. İcat istatistik veya uydurma CVE yok; resmi OWASP dokümanına bağlı kalıyoruz.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Konuda Anlatılacaklar</span></span><br />
<ol type="1" class="mycode_list"><li>API güvenliği neden ayrı ele alınır?<br />
</li>
<li>OWASP API Top 10 2023 özeti<br />
</li>
<li>BOLA (object) ve BFLA (function) derinlemesine<br />
</li>
<li>Lab: basit API ile A/B hesap testi<br />
</li>
<li>Korunma: authn/authz, rate limit, şema<br />
</li>
<li>İleri seviye: GraphQL, mass assignment, envanter<br />
</li>
<li>Kaynakça ve yasal uyarı<br />
</li>
</ol>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">1) API Güvenliği Nedir?</span></span><br />
API'ler makine-okur, otomasyona açıktır, mobil/SPA/partner entegrasyonlarını besler. UI'da gizlenen bir düğme API'de hâlâ duruyor olabilir. Kimlik doğrulama (authentication) ile yetkilendirme (authorization) karıştırılmamalıdır: "Token var" yetki demek değildir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">2) OWASP API Top 10 2023 Özeti</span></span><br />
Resmi liste (kısa Türkçe karşılıklarıyla):<ul class="mycode_list"><li>API1:2023 Broken Object Level Authorization (BOLA)<br />
</li>
<li>API2:2023 Broken Authentication<br />
</li>
<li>API3:2023 Broken Object Property Level Authorization<br />
</li>
<li>API4:2023 Unrestricted Resource Consumption<br />
</li>
<li>API5:2023 Broken Function Level Authorization (BFLA)<br />
</li>
<li>API6:2023 Unrestricted Access to Sensitive Business Flows<br />
</li>
<li>API7:2023 Server Side Request Forgery<br />
</li>
<li>API8:2023 Security Misconfiguration<br />
</li>
<li>API9:2023 Improper Inventory Management<br />
</li>
<li>API10:2023 Unsafe Consumption of APIs<br />
</li>
</ul>
<br />
Detay için <a href="https://owasp.org/API-Security/" target="_blank" rel="noopener" class="mycode_url">OWASP API Security Project</a> sayfasına bakın. Sürüm yılını raporlarınızda belirtin.<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">3) BOLA Nedir?</span></span><br />
Broken Object Level Authorization, web'deki IDOR'un API dilindeki adıdır. Kullanıcı, erişmemesi gereken nesneye kimlik (id) ile ulaşır.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Tehlikeli
GET /api/v1/users/214/orders
# Authorization yalnızca "login oldu mu?" seviyesinde</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Doğru yön
order = repo.get(order_id)
if order.owner_id != current_user.id:
    raise Forbidden()</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">4) BFLA Nedir?</span></span><br />
Broken Function Level Authorization, işlev düzeyinde yetki eksikliğidir. Özellikle admin uçlarının gizlenerek "güvende" sanılması.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>DELETE /api/v1/admin/users/214
POST /api/v1/admin/settings/maintenance
# UI'da admin menüsü yok ama endpoint açık</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Rol kontrolü
if "admin" not in current_user.roles:
    raise Forbidden()</code></div></div><br />
BOLA nesne sahipliğine, BFLA ise role/işleve bakar; ikisi birlikte test edilmelidir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">5) Lab: Mini API Testi</span></span><br />
Kendi bilgisayarınızda iki kullanıcı oluşturabileceğiniz bir lab API'si kullanın (Juice Shop API, crAPI, veya kendi Flask iskeletiniz).<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># A kullanıcısı token
TOKEN_A=...
TOKEN_B=...

# A kendi kaynağını okur
curl -s -H "Authorization: Bearer &#36;TOKEN_A" http://127.0.0.1:8000/api/orders/1

# A, B'nin order id'sini dener
curl -s -o /tmp/out -w "%{http_code}" -H "Authorization: Bearer &#36;TOKEN_A" &#92;
  http://127.0.0.1:8000/api/orders/2
# 403/404 beklenir; 200 + B verisi = BOLA</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># BFLA denemesi
curl -s -o /tmp/out -w "%{http_code}" -H "Authorization: Bearer &#36;TOKEN_A" &#92;
  -X DELETE http://127.0.0.1:8000/api/admin/users/2
# 403 beklenir</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">6) Kavram Referansı ve Korunma</span></span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Object property level (API3):</span> Kullanıcı nesneyi görebilir ama <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>is_admin</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>salary</code></div></div> alanlarını okuyamamalı / yazamamalıdır (mass assignment ile bağlantılı).<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Allowlist serialize
return {"id": o.id, "item": o.item, "status": o.status}
# role, internal_notes yok</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Resource consumption (API4):</span> Rate limit, pagination tavanı, max page size, maliyetli aramalar için kota.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Örnek (nginx / API gateway)
limit_req_zone &#36;binary_remote_addr zone=api:10m rate=5r/s;</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Inventory (API9):</span> Eski <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>/v1</code></div></div> unutulmuş, shadow API, document edilmemiş debug uçları. OpenAPI envanteri tutun; gateway'de yalnızca bilinen route'ları açın.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># OpenAPI'de tanımlı olmayan yolu reddet (gateway politikası)</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Authn (API2):</span> Credential stuffing'e karşı rate limit + MFA; JWT için bir önceki konudaki kurallar.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">7) Uygulamalı Kontrol Listesi</span></span><ul class="mycode_list"><li>Her endpoint için: kim çağırabilir, hangi nesneler?<br />
</li>
<li>A/B hesap otomasyon testi CI'da<br />
</li>
<li>Admin prefix'leri ayrı authz middleware<br />
</li>
<li>Response'ta fazla alan sızıntısı var mı?<br />
</li>
<li>Rate limit ve payload size limit<br />
</li>
<li>WAF/gateway + uygulama içi kontrol (defense in depth)<br />
</li>
<li>Log: authz deny olayları<br />
</li>
</ul>
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Pseudo test
def test_bola_forbidden(client, user_a, order_of_b):
    r = client.get(f"/api/orders/{order_of_b.id}", headers=auth(user_a))
    assert r.status_code in (403, 404)</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">8) İleri Seviye</span></span><br />
<span style="font-weight: bold;" class="mycode_b">GraphQL:</span> Tek endpoint; field-level authz, query depth/cost limit, introspection'ı production'da kapatma.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">BFLA keşfi:</span> OpenAPI / JS bundle içinde <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>/admin</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>role</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>internal</code></div></div> string araması (kendi uygulamanız).<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Unsafe consumption (API10):</span> Üçüncü parti API yanıtına güvenerek komut/SQL birleştirmeyin; şema doğrulayın.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Rapor
Bulgu: BOLA (API1:2023) / CWE-639
Endpoint: GET /api/orders/{id}
Kanıt: Kullanıcı A, B siparişini 200 ile okudu
Öneri: object-level authz + otomatik test</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">9) Sonuç</span></span><br />
API güvenliği, UI güvenlik varsayımlarını taşımaz. BOLA ve BFLA en sık atlanan yetki hatalarıdır; rate limit, şema ve envanter ile tamamlayın. OWASP API Top 10'u ekip içinde ortak dil yapın.<br />
<br />
<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Ek: Partner API ve Versiyonlama Notları</span></span><br />
Dışarıya açılan partner API'lerinde ek olarak:<ul class="mycode_list"><li>İstemci kimliği başına ayrı kimlik bilgisi ve scope<br />
</li>
<li>IP allowlist (mümkünse) + mTLS (yüksek güvenlikli B2B)<br />
</li>
<li>Değişiklik yönetimi: breaking change için yeni versiyon<br />
</li>
<li>Eski versiyonun kapatılma tarihi (inventory ile bağlantılı)<br />
</li>
</ul>
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Scope örneği
Authorization: Bearer ...
# token içinde scope: "orders:read"
# orders:write gerektiren endpoint'te reddedin</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Sayfalama tavanı
GET /api/orders?limit=1000  -&gt; 400 Bad Request (max 50)</code></div></div><br />
[center][/center]<br />
<br />
API Top 10 maddelerini sprint Definition of Done listesine tek satırlık kontroller olarak eklemek, "sonra bakarız" riskini azaltır.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Kaynakça</span></span><ul class="mycode_list"><li><a href="https://owasp.org/API-Security/editions/2023/en/0x00-header/" target="_blank" rel="noopener" class="mycode_url">OWASP API Security Top 10 2023</a><br />
</li>
<li><a href="https://owasp.org/API-Security/editions/2023/en/0xa1-broken-object-level-authorization/" target="_blank" rel="noopener" class="mycode_url">API1 BOLA</a><br />
</li>
<li><a href="https://owasp.org/API-Security/editions/2023/en/0xa5-broken-function-level-authorization/" target="_blank" rel="noopener" class="mycode_url">API5 BFLA</a><br />
</li>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/REST_Security_Cheat_Sheet.html" target="_blank" rel="noopener" class="mycode_url">OWASP REST Security Cheat Sheet</a><br />
</li>
<li><a href="https://cwe.mitre.org/data/definitions/285.html" target="_blank" rel="noopener" class="mycode_url">CWE-285 Improper Authorization</a><br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Yasal Uyarı</span></span><br />
API testleri yalnızca kendi sistemleriniz veya yazılı pentest yetkisi kapsamında yapılmalıdır. İzinsiz API tarama ve veri erişimi TCK <span style="font-weight: bold;" class="mycode_b">243-245</span> kapsamında suç olabilir. Eğitim amaçlıdır.<br />
<br />
<span style="font-style: italic;" class="mycode_i">Yasal uyarı: Bu içerik eğitim amaçlıdır. Yalnızca kendi sistemlerinizde veya yazılı izin aldığınız hedeflerde uygulayın (TCK 243-245).</span><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=147" target="_blank" title="">000-team-new-de9d96.png</a> (Dosya Boyutu: 64.92 KB / İndirme Sayısı: 7)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[JWT ve Oturum Güvenliği: Yaygın Hatalar ve Doğru Kullanım Rehberi]]></title>
			<link>https://www.turkteam.org/konu-jwt-ve-oturum-guvenligi-yaygin-hatalar-ve-dogru-kullanim-rehberi.html</link>
			<pubDate>Sun, 18 Oct 2026 11:08:37 +0300</pubDate>
			<dc:creator><![CDATA[<a href="https://www.turkteam.org/member.php?action=profile&uid=3">BilgeKagan</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.turkteam.org/konu-jwt-ve-oturum-guvenligi-yaygin-hatalar-ve-dogru-kullanim-rehberi.html</guid>
			<description><![CDATA[[center]<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=144" loading="lazy"  alt="[Resim: attachment.php?aid=144]" class="mycode_img" /></div>[/center]<br />
<br />
Selam TurkTeam, BlueTornado burada.<br />
<br />
JWT (JSON Web Token), iddia (claim) taşımak için yaygın bir formattır; "otomatik olarak güvenli oturum çözümü" değildir. Yanlış kullanıldığında alg:none, zayıf imza, uzun ömürlü token, secret sızıntısı gibi hatalar ortaya çıkar. Bu rehberde JWT yapısı, klasik oturum çerezi ile farkı, yaygın hatalar ve savunmacı doğru kullanım anlatılır.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Konuda Anlatılacaklar</span></span><br />
<ol type="1" class="mycode_list"><li>JWT nedir, ne işe yarar?<br />
</li>
<li>Oturum çerezi ile karşılaştırma<br />
</li>
<li>Lab: token üretme ve inceleme<br />
</li>
<li>Yaygın hatalar (alg, secret, saklama)<br />
</li>
<li>Doğru kullanım: imza, süre, yenileme, iptal<br />
</li>
<li>İleri seviye: JWE, key rotation, browser saklama<br />
</li>
<li>Kaynakça ve yasal uyarı<br />
</li>
</ol>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">1) JWT Nedir?</span></span><br />
JWT genellikle üç Base64URL parçasından oluşur: header.payload.signature<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Örnek yapı (sahte / eğitim)
header = {"alg":"HS256","typ":"JWT"}
payload = {"sub":"123","role":"user","exp":1735689600}</code></div></div><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Header:</span> algoritma ve tip<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Payload:</span> claim'ler (sub, exp, iss, aud, özel alanlar)<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Signature:</span> bütünlük; gizli anahtar veya özel anahtar ile<br />
</li>
</ul>
<br />
Payload varsayılan olarak <span style="font-weight: bold;" class="mycode_b">şifreli değildir</span>; Base64 decode herkes yapar. Gizlilik için TLS şarttır; ek gizlilik gerekirse JWE düşünülür.<br />
<br />
<blockquote class="mycode_quote"><cite>Alıntı:</cite>JWT'yi "encrypt" sanmak yaygın hatadır. İmza bütünlük sağlar; içeriği gizlemez.</blockquote>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">2) Klasik Oturum ile Fark</span></span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Sunucu oturumu:</span> Çerezde rastgele session id; veri sunucuda. İptal kolay (store'dan sil).<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Stateless JWT:</span> Veri token içinde; ölçeklenmesi kolay, iptal zor (blacklist/ kısa ömür gerekir).<br />
</li>
</ul>
<br />
İkisi de doğru tasarlanırsa güvenli olabilir. Çoğu web uygulaması için HttpOnly Secure SameSite çerez + sunucu oturumu hâlâ sağlam bir seçimdir. JWT özellikle API'ler, mikroservisler ve mobil istemcilerde tercih edilir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">3) Lab: Token İnceleme</span></span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Python ile imzalı token (lab secret - üretime koymayın)
pip install pyjwt
python3 - &lt;&lt;'PY'
import jwt, datetime
key = "lab-only-change-me"
payload = {
  "sub": "42",
  "role": "user",
  "exp": datetime.datetime.utcnow() + datetime.timedelta(minutes=15),
  "iat": datetime.datetime.utcnow(),
  "iss": "turkteam-lab",
}
token = jwt.encode(payload, key, algorithm="HS256")
print(token)
print(jwt.decode(token, key, algorithms=["HS256"], issuer="turkteam-lab"))
PY</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Parçaları görmek (imza doğrulaması değil!)
python3 - &lt;&lt;'PY'
import base64, json
t = input().strip().split('.')
for part in t[:2]:
    pad = '=' * (-len(part) % 4)
    print(json.loads(base64.urlsafe_b64decode(part + pad)))
PY</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">4) Yaygın Hatalar</span></span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">alg:none veya algoritma karışıklığı:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Kütüphane "alg" header'ına körü körüne güvenmemeli
# Doğrulamada algoritmayı allowlist ile sabitleyin
jwt.decode(token, key, algorithms=["HS256"])  # algorithms zorunlu</code></div></div>Eski kütüphane hatalarında saldırgan <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>alg</code></div></div>'ı none veya HS256'ya çevirip RSA public key ile imza atlatmayı denemişti. Güncel kütüphane + sabit algorithms kullanın.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Zayıf / sızmış secret:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Kötü
secret = "secret"
# İyi: uzun, rastgele, ortam değişkeni / KMS
# openssl rand -base64 48</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">exp yok veya çok uzun:</span> Yıllarca geçerli access token çalınırsa uzun süre geçerlidir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Hassas veri payload'da:</span> TCKN, parola hash'i, kart numarası koymayın.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">localStorage'da access token:</span> XSS ile çalınır. Mümkünse Secure HttpOnly çerez; XSS'i de kapatın.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Imza doğrulamadan claim okumak:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># YANLIŞ
payload = jwt.decode(token, options={"verify_signature": False})</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">5) Doğru Kullanım Pratikleri</span></span><ul class="mycode_list"><li>Access token kısa ömürlü (dakikalar); refresh token uzun, sıkı saklı, rotate edilebilir<br />
</li>
<li><div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>iss</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>aud</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>exp</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>nbf</code></div></div> doğrulayın<br />
</li>
<li>HS256 için güçlü secret; asimetrik için RS256/ES256 ve JWKS<br />
</li>
<li>Rol/yetki değişince eski token'lara güvenmeyin (kısa TTL veya sürüm claim'i)<br />
</li>
<li>Logout: refresh iptali + çerez silme; saf stateless'ta kısa TTL şart<br />
</li>
<li>TLS zorunlu; token'ı URL query'de taşımayın (loglara düşer)<br />
</li>
</ul>
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Doğrulama örneği
jwt.decode(
  token,
  key,
  algorithms=["HS256"],
  issuer="turkteam-lab",
  audience="turkteam-api",
  options={"require": ["exp", "iss", "aud", "sub"]},
)</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Refresh rotate (kavramsal)
# Her kullanımda yeni refresh üret, eskisini revoke et
# Çalınan refresh replay edilirse aile (family) iptali</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">6) Oturum Çerezi Sertleştirme (JWT kullanmasanız bile)</span></span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Set-Cookie: session=...; Path=/; Secure; HttpOnly; SameSite=Lax; Priority=High</code></div></div><ul class="mycode_list"><li>Session fixation: login sonrası id yenile<br />
</li>
<li>Idle / absolute timeout<br />
</li>
<li>Concurrent session politikası (isteğe bağlı)<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">7) İleri Seviye</span></span><br />
<span style="font-weight: bold;" class="mycode_b">JWKS ve key rotation:</span> <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>kid</code></div></div> header ile anahtar seçimi; eski kid kısa süre doğrulanmaya devam edebilir.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>GET /.well-known/jwks.json</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">JWE:</span> Token içeriğini şifrelemek gerektiğinde. Karmaşıklık artar; çoğu API için TLS + minimal claim yeterlidir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Service-to-service:</span> Kullanıcı JWT'sini körü körüne iletmeyin; audience daraltın, impersonation claim'lerini dikkatli tasarlayın.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Rapor dili
Bulgu: JWT imza doğrulamasında algoritma sabitlenmemiş
Risk: Algorithm confusion / alg none sınıfı hatalara açıklık
Öneri: algorithms allowlist + güçlü anahtar + kısa exp</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">8) Sonuç</span></span><br />
JWT güçlü bir formattır; güvenlik tasarımında detaylarda gizlidir. İmza algoritmasını sabitleyin, süreyi kısa tutun, saklamayı XSS'e karşı düşünün, claim'leri doğrulayın. Gerekmiyorsa sunucu oturumu ile de ilerleyebilirsiniz.<br />
<br />
<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Ek: Tarayıcı Saklama Karar Ağacı</span></span><ul class="mycode_list"><li>Birinci taraf web uygulaması: mümkünse sunucu oturumu veya refresh'i HttpOnly çerezde tutun<br />
</li>
<li>Access token bellekte (memory) kısa ömürlü tutulabilir; sayfa yenilenince refresh ile yenilenir<br />
</li>
<li>localStorage/sessionStorage: XSS yüzeyi geniş; yalnızca risk kabulü ile<br />
</li>
<li>Mobil uygulama: OS güvenli depolama (Keychain / Keystore)<br />
</li>
</ul>
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Nginx ile çerez örneği (uygulama Set-Cookie üretiyorsa)
# proxy_cookie_flags ~ secure httponly samesite=lax;</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Test kontrol listesi:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>[ ] algorithms parametresi sabit mi?
[ ] exp / iss / aud doğrulanıyor mu?
[ ] Secret git'te yok mu?
[ ] Access TTL kısa mı?
[ ] Refresh rotate / revoke var mı?
[ ] Token URL'de taşınmıyor mu?
[ ] Logout sonrası refresh geçersiz mi?</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Kaynakça</span></span><ul class="mycode_list"><li><a href="https://datatracker.ietf.org/doc/html/rfc7519" target="_blank" rel="noopener" class="mycode_url">RFC 7519 - JWT</a><br />
</li>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html" target="_blank" rel="noopener" class="mycode_url">OWASP JWT Cheat Sheet</a><br />
</li>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html" target="_blank" rel="noopener" class="mycode_url">OWASP Session Management Cheat Sheet</a><br />
</li>
<li><a href="https://auth0.com/blog/a-look-at-the-latest-draft-for-jwt-bcp/" target="_blank" rel="noopener" class="mycode_url">JWT BCP tartışmaları / best practices (Auth0 özeti, RFC 8725 ile birlikte okuyun)</a><br />
</li>
<li><a href="https://datatracker.ietf.org/doc/html/rfc8725" target="_blank" rel="noopener" class="mycode_url">RFC 8725 - JWT Best Current Practices</a><br />
</li>
<li><a href="https://pyjwt.readthedocs.io/" target="_blank" rel="noopener" class="mycode_url">PyJWT Documentation</a><br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Yasal Uyarı</span></span><br />
Token üretme/kırma denemeleri yalnızca kendi labınızda veya yazılı yetki ile yapılmalıdır. Başkalarının oturum token'larını ele geçirmek veya kullanmak TCK <span style="font-weight: bold;" class="mycode_b">243-245</span> kapsamında suç olabilir. Eğitim amaçlıdır.<br />
<br />
<span style="font-style: italic;" class="mycode_i">Yasal uyarı: Bu içerik eğitim amaçlıdır. Yalnızca kendi sistemlerinizde veya yazılı izin aldığınız hedeflerde uygulayın (TCK 243-245).</span><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=144" target="_blank" title="">000-team-new-ceebc8.png</a> (Dosya Boyutu: 62.82 KB / İndirme Sayısı: 6)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[[center]<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=144" loading="lazy"  alt="[Resim: attachment.php?aid=144]" class="mycode_img" /></div>[/center]<br />
<br />
Selam TurkTeam, BlueTornado burada.<br />
<br />
JWT (JSON Web Token), iddia (claim) taşımak için yaygın bir formattır; "otomatik olarak güvenli oturum çözümü" değildir. Yanlış kullanıldığında alg:none, zayıf imza, uzun ömürlü token, secret sızıntısı gibi hatalar ortaya çıkar. Bu rehberde JWT yapısı, klasik oturum çerezi ile farkı, yaygın hatalar ve savunmacı doğru kullanım anlatılır.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Konuda Anlatılacaklar</span></span><br />
<ol type="1" class="mycode_list"><li>JWT nedir, ne işe yarar?<br />
</li>
<li>Oturum çerezi ile karşılaştırma<br />
</li>
<li>Lab: token üretme ve inceleme<br />
</li>
<li>Yaygın hatalar (alg, secret, saklama)<br />
</li>
<li>Doğru kullanım: imza, süre, yenileme, iptal<br />
</li>
<li>İleri seviye: JWE, key rotation, browser saklama<br />
</li>
<li>Kaynakça ve yasal uyarı<br />
</li>
</ol>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">1) JWT Nedir?</span></span><br />
JWT genellikle üç Base64URL parçasından oluşur: header.payload.signature<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Örnek yapı (sahte / eğitim)
header = {"alg":"HS256","typ":"JWT"}
payload = {"sub":"123","role":"user","exp":1735689600}</code></div></div><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Header:</span> algoritma ve tip<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Payload:</span> claim'ler (sub, exp, iss, aud, özel alanlar)<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Signature:</span> bütünlük; gizli anahtar veya özel anahtar ile<br />
</li>
</ul>
<br />
Payload varsayılan olarak <span style="font-weight: bold;" class="mycode_b">şifreli değildir</span>; Base64 decode herkes yapar. Gizlilik için TLS şarttır; ek gizlilik gerekirse JWE düşünülür.<br />
<br />
<blockquote class="mycode_quote"><cite>Alıntı:</cite>JWT'yi "encrypt" sanmak yaygın hatadır. İmza bütünlük sağlar; içeriği gizlemez.</blockquote>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">2) Klasik Oturum ile Fark</span></span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Sunucu oturumu:</span> Çerezde rastgele session id; veri sunucuda. İptal kolay (store'dan sil).<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Stateless JWT:</span> Veri token içinde; ölçeklenmesi kolay, iptal zor (blacklist/ kısa ömür gerekir).<br />
</li>
</ul>
<br />
İkisi de doğru tasarlanırsa güvenli olabilir. Çoğu web uygulaması için HttpOnly Secure SameSite çerez + sunucu oturumu hâlâ sağlam bir seçimdir. JWT özellikle API'ler, mikroservisler ve mobil istemcilerde tercih edilir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">3) Lab: Token İnceleme</span></span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Python ile imzalı token (lab secret - üretime koymayın)
pip install pyjwt
python3 - &lt;&lt;'PY'
import jwt, datetime
key = "lab-only-change-me"
payload = {
  "sub": "42",
  "role": "user",
  "exp": datetime.datetime.utcnow() + datetime.timedelta(minutes=15),
  "iat": datetime.datetime.utcnow(),
  "iss": "turkteam-lab",
}
token = jwt.encode(payload, key, algorithm="HS256")
print(token)
print(jwt.decode(token, key, algorithms=["HS256"], issuer="turkteam-lab"))
PY</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Parçaları görmek (imza doğrulaması değil!)
python3 - &lt;&lt;'PY'
import base64, json
t = input().strip().split('.')
for part in t[:2]:
    pad = '=' * (-len(part) % 4)
    print(json.loads(base64.urlsafe_b64decode(part + pad)))
PY</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">4) Yaygın Hatalar</span></span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">alg:none veya algoritma karışıklığı:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Kütüphane "alg" header'ına körü körüne güvenmemeli
# Doğrulamada algoritmayı allowlist ile sabitleyin
jwt.decode(token, key, algorithms=["HS256"])  # algorithms zorunlu</code></div></div>Eski kütüphane hatalarında saldırgan <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>alg</code></div></div>'ı none veya HS256'ya çevirip RSA public key ile imza atlatmayı denemişti. Güncel kütüphane + sabit algorithms kullanın.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Zayıf / sızmış secret:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Kötü
secret = "secret"
# İyi: uzun, rastgele, ortam değişkeni / KMS
# openssl rand -base64 48</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">exp yok veya çok uzun:</span> Yıllarca geçerli access token çalınırsa uzun süre geçerlidir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Hassas veri payload'da:</span> TCKN, parola hash'i, kart numarası koymayın.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">localStorage'da access token:</span> XSS ile çalınır. Mümkünse Secure HttpOnly çerez; XSS'i de kapatın.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Imza doğrulamadan claim okumak:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># YANLIŞ
payload = jwt.decode(token, options={"verify_signature": False})</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">5) Doğru Kullanım Pratikleri</span></span><ul class="mycode_list"><li>Access token kısa ömürlü (dakikalar); refresh token uzun, sıkı saklı, rotate edilebilir<br />
</li>
<li><div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>iss</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>aud</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>exp</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>nbf</code></div></div> doğrulayın<br />
</li>
<li>HS256 için güçlü secret; asimetrik için RS256/ES256 ve JWKS<br />
</li>
<li>Rol/yetki değişince eski token'lara güvenmeyin (kısa TTL veya sürüm claim'i)<br />
</li>
<li>Logout: refresh iptali + çerez silme; saf stateless'ta kısa TTL şart<br />
</li>
<li>TLS zorunlu; token'ı URL query'de taşımayın (loglara düşer)<br />
</li>
</ul>
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Doğrulama örneği
jwt.decode(
  token,
  key,
  algorithms=["HS256"],
  issuer="turkteam-lab",
  audience="turkteam-api",
  options={"require": ["exp", "iss", "aud", "sub"]},
)</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Refresh rotate (kavramsal)
# Her kullanımda yeni refresh üret, eskisini revoke et
# Çalınan refresh replay edilirse aile (family) iptali</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">6) Oturum Çerezi Sertleştirme (JWT kullanmasanız bile)</span></span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Set-Cookie: session=...; Path=/; Secure; HttpOnly; SameSite=Lax; Priority=High</code></div></div><ul class="mycode_list"><li>Session fixation: login sonrası id yenile<br />
</li>
<li>Idle / absolute timeout<br />
</li>
<li>Concurrent session politikası (isteğe bağlı)<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">7) İleri Seviye</span></span><br />
<span style="font-weight: bold;" class="mycode_b">JWKS ve key rotation:</span> <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>kid</code></div></div> header ile anahtar seçimi; eski kid kısa süre doğrulanmaya devam edebilir.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>GET /.well-known/jwks.json</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">JWE:</span> Token içeriğini şifrelemek gerektiğinde. Karmaşıklık artar; çoğu API için TLS + minimal claim yeterlidir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Service-to-service:</span> Kullanıcı JWT'sini körü körüne iletmeyin; audience daraltın, impersonation claim'lerini dikkatli tasarlayın.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Rapor dili
Bulgu: JWT imza doğrulamasında algoritma sabitlenmemiş
Risk: Algorithm confusion / alg none sınıfı hatalara açıklık
Öneri: algorithms allowlist + güçlü anahtar + kısa exp</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">8) Sonuç</span></span><br />
JWT güçlü bir formattır; güvenlik tasarımında detaylarda gizlidir. İmza algoritmasını sabitleyin, süreyi kısa tutun, saklamayı XSS'e karşı düşünün, claim'leri doğrulayın. Gerekmiyorsa sunucu oturumu ile de ilerleyebilirsiniz.<br />
<br />
<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Ek: Tarayıcı Saklama Karar Ağacı</span></span><ul class="mycode_list"><li>Birinci taraf web uygulaması: mümkünse sunucu oturumu veya refresh'i HttpOnly çerezde tutun<br />
</li>
<li>Access token bellekte (memory) kısa ömürlü tutulabilir; sayfa yenilenince refresh ile yenilenir<br />
</li>
<li>localStorage/sessionStorage: XSS yüzeyi geniş; yalnızca risk kabulü ile<br />
</li>
<li>Mobil uygulama: OS güvenli depolama (Keychain / Keystore)<br />
</li>
</ul>
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Nginx ile çerez örneği (uygulama Set-Cookie üretiyorsa)
# proxy_cookie_flags ~ secure httponly samesite=lax;</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Test kontrol listesi:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>[ ] algorithms parametresi sabit mi?
[ ] exp / iss / aud doğrulanıyor mu?
[ ] Secret git'te yok mu?
[ ] Access TTL kısa mı?
[ ] Refresh rotate / revoke var mı?
[ ] Token URL'de taşınmıyor mu?
[ ] Logout sonrası refresh geçersiz mi?</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Kaynakça</span></span><ul class="mycode_list"><li><a href="https://datatracker.ietf.org/doc/html/rfc7519" target="_blank" rel="noopener" class="mycode_url">RFC 7519 - JWT</a><br />
</li>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html" target="_blank" rel="noopener" class="mycode_url">OWASP JWT Cheat Sheet</a><br />
</li>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html" target="_blank" rel="noopener" class="mycode_url">OWASP Session Management Cheat Sheet</a><br />
</li>
<li><a href="https://auth0.com/blog/a-look-at-the-latest-draft-for-jwt-bcp/" target="_blank" rel="noopener" class="mycode_url">JWT BCP tartışmaları / best practices (Auth0 özeti, RFC 8725 ile birlikte okuyun)</a><br />
</li>
<li><a href="https://datatracker.ietf.org/doc/html/rfc8725" target="_blank" rel="noopener" class="mycode_url">RFC 8725 - JWT Best Current Practices</a><br />
</li>
<li><a href="https://pyjwt.readthedocs.io/" target="_blank" rel="noopener" class="mycode_url">PyJWT Documentation</a><br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Yasal Uyarı</span></span><br />
Token üretme/kırma denemeleri yalnızca kendi labınızda veya yazılı yetki ile yapılmalıdır. Başkalarının oturum token'larını ele geçirmek veya kullanmak TCK <span style="font-weight: bold;" class="mycode_b">243-245</span> kapsamında suç olabilir. Eğitim amaçlıdır.<br />
<br />
<span style="font-style: italic;" class="mycode_i">Yasal uyarı: Bu içerik eğitim amaçlıdır. Yalnızca kendi sistemlerinizde veya yazılı izin aldığınız hedeflerde uygulayın (TCK 243-245).</span><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=144" target="_blank" title="">000-team-new-ceebc8.png</a> (Dosya Boyutu: 62.82 KB / İndirme Sayısı: 6)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[CSRF Cross-Site Request Forgery Nedir? Tespit ve Korunma Rehberi]]></title>
			<link>https://www.turkteam.org/konu-csrf-cross-site-request-forgery-nedir-tespit-ve-korunma-rehberi.html</link>
			<pubDate>Sun, 18 Oct 2026 11:05:08 +0300</pubDate>
			<dc:creator><![CDATA[<a href="https://www.turkteam.org/member.php?action=profile&uid=3">BilgeKagan</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.turkteam.org/konu-csrf-cross-site-request-forgery-nedir-tespit-ve-korunma-rehberi.html</guid>
			<description><![CDATA[[center]<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=140" loading="lazy"  alt="[Resim: attachment.php?aid=140]" class="mycode_img" /></div>[/center]<br />
<br />
Selam TurkTeam, BlueTornado yazıyor.<br />
<br />
CSRF (Cross-Site Request Forgery), kimliği doğrulanmış bir kullanıcının tarayıcısını kandırarak, kullanıcının haberi olmadan siteye istek attırmaktır. XSS "saldırganın script'ini kurbanın tarayıcısında çalıştırır"; CSRF ise kurbanın <span style="font-weight: bold;" class="mycode_b">mevcut oturumunu</span> kullanarak istenmeyen bir eylemi tetikler. Bu rehberde teori, lab gözlemi, token/SameSite korunmaları ve modern API'lerdeki durumu inceliyoruz.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Konuda Anlatılacaklar</span></span><br />
<ol type="1" class="mycode_list"><li>CSRF nedir, hangi koşullarda çalışır?<br />
</li>
<li>XSS ile farkı<br />
</li>
<li>Lab: DVWA CSRF sayfası<br />
</li>
<li>Klasik PoC formu ve cookie davranışı<br />
</li>
<li>Korunma: Anti-CSRF token, SameSite, pratikler<br />
</li>
<li>İleri seviye: JSON API, SameSite=None, login CSRF<br />
</li>
<li>Kaynakça ve yasal uyarı<br />
</li>
</ol>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">1) CSRF Nedir?</span></span><br />
Tarayıcılar, bir siteye istek atarken o siteye ait çerezleri (oturum çerezi dahil) varsayılan kurallara göre ekler. Saldırgan, kötü amaçlı bir sayfada şu tür bir istek tetiklerse:<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&lt;!-- Kavramsal kötü sayfa (lab dışında kullanmayın) --&gt;
&lt;form action="https://bank.example/transfer" method="POST"&gt;
  &lt;input type="hidden" name="to" value="attacker"&gt;
  &lt;input type="hidden" name="amount" value="1000"&gt;
&lt;/form&gt;
&lt;script&gt;document.forms[0].submit()&lt;/script&gt;</code></div></div><br />
Kurban o anda bank.example oturumu açıksa, tarayıcı çerezi ekleyebilir ve transfer isteği "kurbandan gelmiş" gibi görünür. Sunucu, isteğin <span style="font-weight: bold;" class="mycode_b">kullanıcının isteyerek mi</span> yoksa <span style="font-weight: bold;" class="mycode_b">başka siteden mi</span> geldiğini ayırt edemiyorsa CSRF oluşur.<br />
<br />
Gerekli koşullar (özet):<ul class="mycode_list"><li>İlgili sitede geçerli oturum (çerez tabanlı)<br />
</li>
<li>Tarayıcının çerezi o isteğe eklemesi<br />
</li>
<li>Sunucuda istek sahteciliğini engelleyen ek doğrulama olmaması<br />
</li>
<li>Değiştirici (state-changing) bir eylem (POST ile para transferi, e-posta değiştirme vb.)<br />
</li>
</ul>
<br />
<blockquote class="mycode_quote"><cite>Alıntı:</cite>CSRF, "çerezi çalmak" zorunda değildir. Çerez tarayıcıda kalır; saldırgan sadece isteği tetikler.</blockquote>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">2) XSS ile Fark</span></span><ul class="mycode_list"><li>XSS: Güvenilmeyen verinin sayfada script olarak çalışması<br />
</li>
<li>CSRF: Güvenilen sitenin state-changing endpoint'ine çapraz siteden istek<br />
</li>
<li>XSS varsa çoğu CSRF koruması da aşılabilir (token okunur); ikisi ayrı ayrı kapatılmalıdır<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">3) Lab: DVWA CSRF</span></span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>git clone https://github.com/digininja/DVWA.git
cd DVWA
docker compose up -d</code></div></div><br />
DVWA menüsünden <span style="font-weight: bold;" class="mycode_b">CSRF</span> sayfasına gidin. Low seviyede parola değiştirme formu genelde anti-CSRF tokensızdır.<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Adım 1:</span> Normal şekilde parolayı değiştirip isteği DevTools/Burp ile inceleyin.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>POST /vulnerabilities/csrf/
password_new=...&amp;password_conf=...&amp;Change=Change
Cookie: PHPSESSID=...; security=low</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Adım 2:</span> Aynı parametrelerle, labınızda yerel bir HTML dosyasından formu işaret ederek davranışı gözlemleyin (yalnızca 127.0.0.1 DVWA). Impossible seviyede token eklenmiş olduğunu göreceksiniz.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&lt;!-- Yerel lab HTML iskeleti --&gt;
&lt;form method="POST" action="http://127.0.0.1/vulnerabilities/csrf/"&gt;
&lt;input type="hidden" name="password_new" value="hacked"&gt;
&lt;input type="hidden" name="password_conf" value="hacked"&gt;
&lt;input type="hidden" name="Change" value="Change"&gt;
&lt;/form&gt;</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Çıktı yorumu:</span> Low'da oturum açıkken bu sayfa yüklendiğinde parola değişiyorsa CSRF vardır. Impossible'da token eksik/yanlışsa işlem reddedilir.<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">4) Kavram Referansı</span></span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Anti-CSRF synchronizer token:</span> Sunucu, forma rastgele token koyar; POST'ta token oturumdaki ile eşleşmelidir. Saldırganın sitesi bu token'ı okuyamaz (same-origin policy), XSS yoksa.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&lt;!-- Kavramsal --&gt;
&lt;input type="hidden" name="csrf_token" value="a3f9..."&gt;</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Sunucu tarafı (kavramsal)
if not hmac.compare_digest(session["csrf"], request.form["csrf_token"]):
    abort(403)</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">SameSite çerez özelliği:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Set-Cookie: session=...; Secure; HttpOnly; SameSite=Lax</code></div></div><ul class="mycode_list"><li><div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Strict</code></div></div>: Çapraz site isteklerinde çerez gönderilmez (en sıkı; bazı akışları bozabilir)<br />
</li>
<li><div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Lax</code></div></div>: Top-level GET navigasyonunda gönderilir; çoğu CSRF POST senaryosunu keser<br />
</li>
<li><div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>None</code></div></div>: Secure zorunlu; çapraz site çerez (dikkatli kullanın)<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">Origin / Referer kontrolü:</span> Ek katman; Referer eksik olabilir, Origin daha güvenilirdir ama her istemci/senaryoda yetmeyebilir. Token ile birlikte düşünün.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Örnek kontrol (kavramsal)
origin = request.headers.get("Origin")
if origin and origin not in ALLOWED_ORIGINS:
    abort(403)</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">5) Korunma Kontrol Listesi</span></span><ul class="mycode_list"><li>State-changing işlemleri POST/PUT/DELETE ile yapın; önemli işleri GET'e bağlamayın<br />
</li>
<li>Anti-CSRF token (framework'ün built-in'i: Django, Rails, ASP.NET, Spring)<br />
</li>
<li>SameSite=Lax veya Strict + Secure + HttpOnly<br />
</li>
<li>Mümkünse oturumu çerez dışında authorization header (Bearer) ile taşıyan SPA'larda CSRF yüzeyi küçülür; XSS'e dikkat<br />
</li>
<li>Kritik işlemlerde re-auth (şifre yeniden sor)<br />
</li>
<li>CORS'u sıkı tutun; credentials ile * kullanmayın<br />
</li>
</ul>
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Django'da middleware varsayılan olarak CSRF korur
# Şablon:
{% csrf_token %}</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Flask-WTF örneği
form = FlaskForm()  # csrf_token alanı otomatik</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">6) İleri Seviye</span></span><br />
<span style="font-weight: bold;" class="mycode_b">Login CSRF:</span> Kurbanı saldırganın hesabına zorla giriş yaptırma; sonra kurban o oturuma veri kaydeder. Login formuna da token koyun.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">JSON API + simple request:</span> <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Content-Type: application/json</code></div></div> olan istekler tarayıcıda CORS preflight tetikleyebilir; yine de cookie tabanlı oturumda doğru CORS/CSRF tasarımı şarttır.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">SameSite=None</span> gereken üçüncü parti gömülü senaryolarda CSRF riski geri gelir; ek token zorunlu düşünün.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Double-submit cookie:</span> Token'ı hem çerezde hem formda göndermek. Basit ama subdomain XSS/cookie injection varsa zayıflayabilir; synchronizer pattern genelde tercih edilir.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Rapor dili
Bulgu: CSRF (CWE-352)
Endpoint: POST /vulnerabilities/csrf/
Kanıt: Labda tokensız POST ile parola değişimi
Öneri: synchronizer token + SameSite=Lax</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">7) Sonuç</span></span><br />
CSRF, tarayıcının çerez ekleme davranışından beslenir. Token + SameSite + güvenli metod kullanımı temel üçlüdür. DVWA Low/Impossible karşılaştırması korumayı somut gösterir.<br />
<br />
<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Ek: Framework Notları ve Test Kontrol Listesi</span></span><br />
Modern çerçeveler CSRF için hazır çözüm sunar; asıl risk "korumayı kapatmak"tır.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Django: CSRF_TRUSTED_ORIGINS doğru ayarlanmalı (HTTPS arkasında)
# @csrf_exempt yalnızca çok bilinçli istisnalarda; API için token veya auth tasarımını gözden geçirin</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># ASP.NET Core: Antiforgery middleware
# ValidateAntiForgeryToken attribute</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># SPA + cookie oturumu:
# 1) Frontend, login yanıtından veya cookie-olmayan bir endpoint'ten CSRF token alsın
# 2) Her state-changing istekte header olarak göndersin (ör. X-CSRF-Token)
# 3) SameSite=Lax + Secure</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Manuel test listesi (izinli lab):</span><ul class="mycode_list"><li>Oturum açıkken çapraz origin HTML formu ile POST deneyin<br />
</li>
<li>Token'ı silerek/değiştirerek 403 bekleyin<br />
</li>
<li>Content-Type ve metod kombinasyonlarını not edin<br />
</li>
<li>Logout sonrası token'ın geçersiz olduğunu doğrulayın<br />
</li>
</ul>
<br />
[center][/center]<br />
<br />
Unutmayın: CSRF koruması XSS varken zayıflar çünkü script token'ı okuyabilir. İkisini birlikte ele alın.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Kaynakça</span></span><ul class="mycode_list"><li><a href="https://owasp.org/www-community/attacks/csrf" target="_blank" rel="noopener" class="mycode_url">OWASP CSRF</a><br />
</li>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html" target="_blank" rel="noopener" class="mycode_url">OWASP CSRF Prevention Cheat Sheet</a><br />
</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite" target="_blank" rel="noopener" class="mycode_url">MDN SameSite</a><br />
</li>
<li><a href="https://cwe.mitre.org/data/definitions/352.html" target="_blank" rel="noopener" class="mycode_url">CWE-352</a><br />
</li>
<li><a href="https://github.com/digininja/DVWA" target="_blank" rel="noopener" class="mycode_url">DVWA</a><br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Yasal Uyarı</span></span><br />
CSRF testleri yalnızca kendi labınızda veya yazılı yetkili pentest kapsamında yapılmalıdır. Başkalarının oturumunu kötüye kullanmak TCK <span style="font-weight: bold;" class="mycode_b">243-245</span> ve ilgili maddeler kapsamında suç olabilir. Eğitim amaçlıdır.<br />
<br />
<span style="font-style: italic;" class="mycode_i">Yasal uyarı: Bu içerik eğitim amaçlıdır. Yalnızca kendi sistemlerinizde veya yazılı izin aldığınız hedeflerde uygulayın (TCK 243-245).</span><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=140" target="_blank" title="">000-team-new-293496.png</a> (Dosya Boyutu: 67.17 KB / İndirme Sayısı: 9)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[[center]<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=140" loading="lazy"  alt="[Resim: attachment.php?aid=140]" class="mycode_img" /></div>[/center]<br />
<br />
Selam TurkTeam, BlueTornado yazıyor.<br />
<br />
CSRF (Cross-Site Request Forgery), kimliği doğrulanmış bir kullanıcının tarayıcısını kandırarak, kullanıcının haberi olmadan siteye istek attırmaktır. XSS "saldırganın script'ini kurbanın tarayıcısında çalıştırır"; CSRF ise kurbanın <span style="font-weight: bold;" class="mycode_b">mevcut oturumunu</span> kullanarak istenmeyen bir eylemi tetikler. Bu rehberde teori, lab gözlemi, token/SameSite korunmaları ve modern API'lerdeki durumu inceliyoruz.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Konuda Anlatılacaklar</span></span><br />
<ol type="1" class="mycode_list"><li>CSRF nedir, hangi koşullarda çalışır?<br />
</li>
<li>XSS ile farkı<br />
</li>
<li>Lab: DVWA CSRF sayfası<br />
</li>
<li>Klasik PoC formu ve cookie davranışı<br />
</li>
<li>Korunma: Anti-CSRF token, SameSite, pratikler<br />
</li>
<li>İleri seviye: JSON API, SameSite=None, login CSRF<br />
</li>
<li>Kaynakça ve yasal uyarı<br />
</li>
</ol>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">1) CSRF Nedir?</span></span><br />
Tarayıcılar, bir siteye istek atarken o siteye ait çerezleri (oturum çerezi dahil) varsayılan kurallara göre ekler. Saldırgan, kötü amaçlı bir sayfada şu tür bir istek tetiklerse:<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&lt;!-- Kavramsal kötü sayfa (lab dışında kullanmayın) --&gt;
&lt;form action="https://bank.example/transfer" method="POST"&gt;
  &lt;input type="hidden" name="to" value="attacker"&gt;
  &lt;input type="hidden" name="amount" value="1000"&gt;
&lt;/form&gt;
&lt;script&gt;document.forms[0].submit()&lt;/script&gt;</code></div></div><br />
Kurban o anda bank.example oturumu açıksa, tarayıcı çerezi ekleyebilir ve transfer isteği "kurbandan gelmiş" gibi görünür. Sunucu, isteğin <span style="font-weight: bold;" class="mycode_b">kullanıcının isteyerek mi</span> yoksa <span style="font-weight: bold;" class="mycode_b">başka siteden mi</span> geldiğini ayırt edemiyorsa CSRF oluşur.<br />
<br />
Gerekli koşullar (özet):<ul class="mycode_list"><li>İlgili sitede geçerli oturum (çerez tabanlı)<br />
</li>
<li>Tarayıcının çerezi o isteğe eklemesi<br />
</li>
<li>Sunucuda istek sahteciliğini engelleyen ek doğrulama olmaması<br />
</li>
<li>Değiştirici (state-changing) bir eylem (POST ile para transferi, e-posta değiştirme vb.)<br />
</li>
</ul>
<br />
<blockquote class="mycode_quote"><cite>Alıntı:</cite>CSRF, "çerezi çalmak" zorunda değildir. Çerez tarayıcıda kalır; saldırgan sadece isteği tetikler.</blockquote>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">2) XSS ile Fark</span></span><ul class="mycode_list"><li>XSS: Güvenilmeyen verinin sayfada script olarak çalışması<br />
</li>
<li>CSRF: Güvenilen sitenin state-changing endpoint'ine çapraz siteden istek<br />
</li>
<li>XSS varsa çoğu CSRF koruması da aşılabilir (token okunur); ikisi ayrı ayrı kapatılmalıdır<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">3) Lab: DVWA CSRF</span></span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>git clone https://github.com/digininja/DVWA.git
cd DVWA
docker compose up -d</code></div></div><br />
DVWA menüsünden <span style="font-weight: bold;" class="mycode_b">CSRF</span> sayfasına gidin. Low seviyede parola değiştirme formu genelde anti-CSRF tokensızdır.<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Adım 1:</span> Normal şekilde parolayı değiştirip isteği DevTools/Burp ile inceleyin.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>POST /vulnerabilities/csrf/
password_new=...&amp;password_conf=...&amp;Change=Change
Cookie: PHPSESSID=...; security=low</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Adım 2:</span> Aynı parametrelerle, labınızda yerel bir HTML dosyasından formu işaret ederek davranışı gözlemleyin (yalnızca 127.0.0.1 DVWA). Impossible seviyede token eklenmiş olduğunu göreceksiniz.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&lt;!-- Yerel lab HTML iskeleti --&gt;
&lt;form method="POST" action="http://127.0.0.1/vulnerabilities/csrf/"&gt;
&lt;input type="hidden" name="password_new" value="hacked"&gt;
&lt;input type="hidden" name="password_conf" value="hacked"&gt;
&lt;input type="hidden" name="Change" value="Change"&gt;
&lt;/form&gt;</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Çıktı yorumu:</span> Low'da oturum açıkken bu sayfa yüklendiğinde parola değişiyorsa CSRF vardır. Impossible'da token eksik/yanlışsa işlem reddedilir.<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">4) Kavram Referansı</span></span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Anti-CSRF synchronizer token:</span> Sunucu, forma rastgele token koyar; POST'ta token oturumdaki ile eşleşmelidir. Saldırganın sitesi bu token'ı okuyamaz (same-origin policy), XSS yoksa.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&lt;!-- Kavramsal --&gt;
&lt;input type="hidden" name="csrf_token" value="a3f9..."&gt;</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Sunucu tarafı (kavramsal)
if not hmac.compare_digest(session["csrf"], request.form["csrf_token"]):
    abort(403)</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">SameSite çerez özelliği:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Set-Cookie: session=...; Secure; HttpOnly; SameSite=Lax</code></div></div><ul class="mycode_list"><li><div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Strict</code></div></div>: Çapraz site isteklerinde çerez gönderilmez (en sıkı; bazı akışları bozabilir)<br />
</li>
<li><div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Lax</code></div></div>: Top-level GET navigasyonunda gönderilir; çoğu CSRF POST senaryosunu keser<br />
</li>
<li><div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>None</code></div></div>: Secure zorunlu; çapraz site çerez (dikkatli kullanın)<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">Origin / Referer kontrolü:</span> Ek katman; Referer eksik olabilir, Origin daha güvenilirdir ama her istemci/senaryoda yetmeyebilir. Token ile birlikte düşünün.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Örnek kontrol (kavramsal)
origin = request.headers.get("Origin")
if origin and origin not in ALLOWED_ORIGINS:
    abort(403)</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">5) Korunma Kontrol Listesi</span></span><ul class="mycode_list"><li>State-changing işlemleri POST/PUT/DELETE ile yapın; önemli işleri GET'e bağlamayın<br />
</li>
<li>Anti-CSRF token (framework'ün built-in'i: Django, Rails, ASP.NET, Spring)<br />
</li>
<li>SameSite=Lax veya Strict + Secure + HttpOnly<br />
</li>
<li>Mümkünse oturumu çerez dışında authorization header (Bearer) ile taşıyan SPA'larda CSRF yüzeyi küçülür; XSS'e dikkat<br />
</li>
<li>Kritik işlemlerde re-auth (şifre yeniden sor)<br />
</li>
<li>CORS'u sıkı tutun; credentials ile * kullanmayın<br />
</li>
</ul>
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Django'da middleware varsayılan olarak CSRF korur
# Şablon:
{% csrf_token %}</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Flask-WTF örneği
form = FlaskForm()  # csrf_token alanı otomatik</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">6) İleri Seviye</span></span><br />
<span style="font-weight: bold;" class="mycode_b">Login CSRF:</span> Kurbanı saldırganın hesabına zorla giriş yaptırma; sonra kurban o oturuma veri kaydeder. Login formuna da token koyun.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">JSON API + simple request:</span> <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Content-Type: application/json</code></div></div> olan istekler tarayıcıda CORS preflight tetikleyebilir; yine de cookie tabanlı oturumda doğru CORS/CSRF tasarımı şarttır.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">SameSite=None</span> gereken üçüncü parti gömülü senaryolarda CSRF riski geri gelir; ek token zorunlu düşünün.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Double-submit cookie:</span> Token'ı hem çerezde hem formda göndermek. Basit ama subdomain XSS/cookie injection varsa zayıflayabilir; synchronizer pattern genelde tercih edilir.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Rapor dili
Bulgu: CSRF (CWE-352)
Endpoint: POST /vulnerabilities/csrf/
Kanıt: Labda tokensız POST ile parola değişimi
Öneri: synchronizer token + SameSite=Lax</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">7) Sonuç</span></span><br />
CSRF, tarayıcının çerez ekleme davranışından beslenir. Token + SameSite + güvenli metod kullanımı temel üçlüdür. DVWA Low/Impossible karşılaştırması korumayı somut gösterir.<br />
<br />
<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Ek: Framework Notları ve Test Kontrol Listesi</span></span><br />
Modern çerçeveler CSRF için hazır çözüm sunar; asıl risk "korumayı kapatmak"tır.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Django: CSRF_TRUSTED_ORIGINS doğru ayarlanmalı (HTTPS arkasında)
# @csrf_exempt yalnızca çok bilinçli istisnalarda; API için token veya auth tasarımını gözden geçirin</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># ASP.NET Core: Antiforgery middleware
# ValidateAntiForgeryToken attribute</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># SPA + cookie oturumu:
# 1) Frontend, login yanıtından veya cookie-olmayan bir endpoint'ten CSRF token alsın
# 2) Her state-changing istekte header olarak göndersin (ör. X-CSRF-Token)
# 3) SameSite=Lax + Secure</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Manuel test listesi (izinli lab):</span><ul class="mycode_list"><li>Oturum açıkken çapraz origin HTML formu ile POST deneyin<br />
</li>
<li>Token'ı silerek/değiştirerek 403 bekleyin<br />
</li>
<li>Content-Type ve metod kombinasyonlarını not edin<br />
</li>
<li>Logout sonrası token'ın geçersiz olduğunu doğrulayın<br />
</li>
</ul>
<br />
[center][/center]<br />
<br />
Unutmayın: CSRF koruması XSS varken zayıflar çünkü script token'ı okuyabilir. İkisini birlikte ele alın.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Kaynakça</span></span><ul class="mycode_list"><li><a href="https://owasp.org/www-community/attacks/csrf" target="_blank" rel="noopener" class="mycode_url">OWASP CSRF</a><br />
</li>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html" target="_blank" rel="noopener" class="mycode_url">OWASP CSRF Prevention Cheat Sheet</a><br />
</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite" target="_blank" rel="noopener" class="mycode_url">MDN SameSite</a><br />
</li>
<li><a href="https://cwe.mitre.org/data/definitions/352.html" target="_blank" rel="noopener" class="mycode_url">CWE-352</a><br />
</li>
<li><a href="https://github.com/digininja/DVWA" target="_blank" rel="noopener" class="mycode_url">DVWA</a><br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Yasal Uyarı</span></span><br />
CSRF testleri yalnızca kendi labınızda veya yazılı yetkili pentest kapsamında yapılmalıdır. Başkalarının oturumunu kötüye kullanmak TCK <span style="font-weight: bold;" class="mycode_b">243-245</span> ve ilgili maddeler kapsamında suç olabilir. Eğitim amaçlıdır.<br />
<br />
<span style="font-style: italic;" class="mycode_i">Yasal uyarı: Bu içerik eğitim amaçlıdır. Yalnızca kendi sistemlerinizde veya yazılı izin aldığınız hedeflerde uygulayın (TCK 243-245).</span><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=140" target="_blank" title="">000-team-new-293496.png</a> (Dosya Boyutu: 67.17 KB / İndirme Sayısı: 9)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[SQL Injection Sıfırdan: DVWA ile Uygulamalı Rehber (Yasal Lab)]]></title>
			<link>https://www.turkteam.org/konu-sql-injection-sifirdan-dvwa-ile-uygulamali-rehber-yasal-lab.html</link>
			<pubDate>Sat, 17 Oct 2026 18:03:12 +0300</pubDate>
			<dc:creator><![CDATA[<a href="https://www.turkteam.org/member.php?action=profile&uid=3">BilgeKagan</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.turkteam.org/konu-sql-injection-sifirdan-dvwa-ile-uygulamali-rehber-yasal-lab.html</guid>
			<description><![CDATA[[center]<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=134" loading="lazy"  alt="[Resim: attachment.php?aid=134]" class="mycode_img" /></div>[/center]<br />
<br />
Selam TurkTeam, BlueTornado ile devam.<br />
<br />
SQL Injection (SQLi), uygulamanın SQL sorgusunu kullanıcı girdisiyle güvensiz biçimde birleştirmesi sonucu ortaya çıkan klasik bir enjeksiyon zafiyetidir. Bu rehberde sıfırdan teori, DVWA üzerinde Low/Medium/Impossible karşılaştırması, parametreli sorgular ve modern ORM hatalarını ele alıyoruz. Tüm örnekler <span style="font-weight: bold;" class="mycode_b">yalnızca yerel lab</span> içindir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Konuda Anlatılacaklar</span></span><br />
<ol type="1" class="mycode_list"><li>SQL Injection nedir, hangi riskleri taşır?<br />
</li>
<li>DVWA lab kurulumu<br />
</li>
<li>Kavramlar: union, boolean, error-based, blind<br />
</li>
<li>Low seviyede adım adım gözlem<br />
</li>
<li>Medium filtre ve prepared statement'a geçiş<br />
</li>
<li>Korunma: parametreli sorgu, ORM, least privilege<br />
</li>
<li>İleri seviye: second-order, WAF yanılsaması<br />
</li>
<li>Kaynakça ve yasal uyarı<br />
</li>
</ol>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">1) SQL Injection Nedir?</span></span><br />
Veritabanı, uygulamanın gönderdiği SQL metnini yorumlar. Saldırgan, girdi alanına SQL sözdizimi parçaları ekleyerek sorgunun mantığını değiştirebiliyorsa injection vardır.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Tehlikeli kalıp (kavramsal)
id = request.GET["id"]
sql = "SELECT first_name, last_name FROM users WHERE user_id = '" + id + "'"
# id = 1' OR '1'='1  olduğunda mantık bozulur</code></div></div><br />
Olası etkiler: kimlik doğrulamayı atlama, veri okuma/değiştirme, bazı DB/konfigürasyonlarda OS komutuna giden yollar (ör. xp_cmdshell gibi özellikler açıksa). Etki, DB kullanıcısının yetkisine ve uygulama mimarisine bağlıdır.<br />
<br />
OWASP Top 10 2021'de Injection <span style="font-weight: bold;" class="mycode_b">A03:2021</span> altındadır. CWE karşılığı başlıca <span style="font-weight: bold;" class="mycode_b">CWE-89</span>'dur.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">2) Lab Kurulumu</span></span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>git clone https://github.com/digininja/DVWA.git
cd DVWA
docker compose up -d</code></div></div><br />
Kurulum sonrası DVWA Security'yi <span style="font-weight: bold;" class="mycode_b">Low</span> yapın. SQL Injection ve SQL Injection (Blind) sayfalarını kullanacağız.<br />
<br />
[center][/center]<br />
<br />
İsteğe bağlı olarak kendi MySQL/MariaDB labınızda da aynı mantığı kurabilirsiniz; önemli olan üretim verisine dokunmamaktır.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">3) Kavram Referansı</span></span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">In-band (Union / Error):</span> Sonuç veya hata mesajı aynı kanalda döner.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Union temelli keşif (yalnızca lab, sözdizimi DB'ye göre değişir)
1' UNION SELECT null, null--
1' UNION SELECT user(), database()--</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Boolean-based blind:</span> Sayfa içeriği doğru/yanlış cevaba göre değişir; veri bit bit çıkarılır.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>1' AND 1=1--
1' AND 1=2--</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Time-based blind:</span> <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>SLEEP()</code></div></div> / <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>WAITFOR DELAY</code></div></div> ile zaman farkından çıkarım (labda dikkat: kendini DoS etme).<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># MySQL lab örneği (kendi DVWA'nız)
1' AND SLEEP(3)--</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Prepared statement / parametreli sorgu:</span> SQL yapısı ile verinin ayrılması. Asıl savunma budur.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Python psycopg / MySQL connector tarzı
cur.execute("SELECT * FROM users WHERE id = %s", (user_id,))</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">4) DVWA Low: Adım Adım</span></span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Adım 1 - Normal davranış:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>User ID: 1
# Beklenen: o kullanıcıya ait ad/soyad</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Adım 2 - Mantığı bozma:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>1' OR '1'='1
# Low seviyede genellikle birden fazla satır döner</code></div></div><br />
Çıktıyı yorumlayın: Uygulama girdi etrafına tırnak koyup birleştiriyorsa bu payload tüm satırları getirir. Bu, zafiyetin varlığını gösterir.<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Adım 3 - Sütun sayısını anlama (Union):</span><br />
DVWA Low'da klasik union yolu kullanılır. Önce sütun sayısını bulun:<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>1' ORDER BY 1--
1' ORDER BY 2--
1' ORDER BY 3--
# Hata aldığınız nokta sütun sayısını aştığınız yerdir</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>1' UNION SELECT user, password FROM users--
# Labda hash'lerin görünmesi, üretimde felaket senaryosudur</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Adım 4 - Hata mesajlarını okuma:</span><br />
Verbose SQL hataları hem enjeksiyonu kolaylaştırır hem bilgi sızdırır. Production'da genel hata sayfası kullanın; detayı loglayın.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Kötü: ham SQL exception'ı kullanıcıya göstermek
# İyi: "Bir hata oluştu" + sunucu tarafı log</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">5) Blind SQLi Sayfası</span></span><br />
DVWA SQL Injection (Blind) sayfasında sonuç satırları doğrudan basılmayabilir; "User ID exists" benzeri mesajlar görürsünüz.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>1' AND '1'='1
1' AND '1'='2</code></div></div><br />
Birinde "exists", diğerinde farklı mesaj varsa boolean blind mümkündür. Otomatik araçlar (sqlmap) bu farkları ölçer; <span style="font-weight: bold;" class="mycode_b">yalnızca kendi labınızda</span> ve yasal kapsamda kullanın.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># sqlmap lab örneği (DVWA localhost, kendi ortamınız)
sqlmap -u "http://127.0.0.1/vulnerabilities/sqli_blind/?id=1&amp;Submit=Submit" &#92;
  --cookie="security=low; PHPSESSID=..." &#92;
  --batch --technique=B</code></div></div><br />
sqlmap çıktısını yorumlarken: DBMS tipi, baner, tablolar. Üretimde izinsiz sqlmap çalıştırmak hem etik dışıdır hem yasadışıdır.<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">6) Medium ve Impossible: Ne Değişiyor?</span></span><br />
Medium'da DVWA genelde POST + mysql_real_escape_string benzeri kaçış veya seçim kutusu kullanır. Escape, yanlış bağlamda (ör. sayısal alan, farklı karakter seti) yeterli olmayabilir; asıl çözüm prepared statement'tır.<br />
<br />
Impossible seviyede parametreli sorgu görürsünüz. Kaynak kodu (DVWA PHP) inceleyerek farkı not edin:<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Kavramsal güvenli PHP
&#36;stmt = &#36;mysqli-&gt;prepare("SELECT first_name, last_name FROM users WHERE user_id = ?");
&#36;stmt-&gt;bind_param("s", &#36;id);
&#36;stmt-&gt;execute();</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># ORM örneği (Django)
User.objects.filter(id=user_id)
# Dikkat: raw() / extra() ile tekrar injection açabilirsiniz</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">7) Korunma Katmanları</span></span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Birincil:</span> Parametreli sorgu / ORM güvenli API<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Girdi doğrulama:</span> Beklenen tip (int), uzunluk, allowlist<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Least privilege:</span> Uygulama DB kullanıcısına DROP/FILE vermeyin<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Hata yönetimi:</span> Detaylı SQL hatalarını gizleyin<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">WAF:</span> Savunma derinliği; tek başına çözüm değil<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Test:</span> SAST, DAST, kod incelemesi, unit test ile raw SQL denetimi<br />
</li>
</ul>
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Beklenen tip kontrolü
if not user_id.isdigit():
    abort(400)</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># PostgreSQL rol örneği (kavramsal)
GRANT SELECT, INSERT, UPDATE ON app_schema.* TO app_user;
-- FILE, SUPERUSER yok</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">8) İleri Seviye</span></span><br />
<span style="font-weight: bold;" class="mycode_b">Second-order SQLi:</span> Girdi önce güvenli saklanır, sonra başka bir sorguda güvensiz birleştirilir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">ORM / query builder tuzakları:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Tehlikeli: kullanıcı girdisini SQL parçası sanmak
User.objects.raw("SELECT * FROM users WHERE name = '%s'" % name)</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">NoSQL injection:</span> MongoDB'de operatör enjeksiyonu (<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&#36;gt</code></div></div> vb.) ayrı bir ailedir; "SQL yoksa injection yok" yanılgısına düşmeyin.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Rapor şablonu:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Bulgu: SQL Injection (CWE-89)
Endpoint: GET /vulnerabilities/sqli?id=
Kanıt: Labda OR '1'='1 ile çoklu satır
Etki: users tablosu okuma (lab)
Öneri: prepared statement + least privilege</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">9) Sonuç</span></span><br />
SQLi, girdinin sorgu yapısına karışmasıdır. DVWA Low'da görün, Impossible'da doğru kodu okuyun, kendi projelerinizde raw string birleştirmeyi yasaklayın. Araçlar yardımcı olur; kök neden kod ve tasarımda kalır.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Kaynakça</span></span><ul class="mycode_list"><li><a href="https://owasp.org/www-community/attacks/SQL_Injection" target="_blank" rel="noopener" class="mycode_url">OWASP SQL Injection</a><br />
</li>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html" target="_blank" rel="noopener" class="mycode_url">OWASP SQLi Prevention Cheat Sheet</a><br />
</li>
<li><a href="https://github.com/digininja/DVWA" target="_blank" rel="noopener" class="mycode_url">DVWA</a><br />
</li>
<li><a href="https://sqlmap.org/" target="_blank" rel="noopener" class="mycode_url">sqlmap resmi site</a><br />
</li>
<li><a href="https://cwe.mitre.org/data/definitions/89.html" target="_blank" rel="noopener" class="mycode_url">CWE-89</a><br />
</li>
<li><a href="https://owasp.org/Top10/A03_2021-Injection/" target="_blank" rel="noopener" class="mycode_url">OWASP Top 10 2021 A03 Injection</a><br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Yasal Uyarı</span></span><br />
SQL Injection testleri yalnızca kendi sistemlerinizde veya yazılı izinli lab/pentest kapsamında yapılmalıdır. İzinsiz veritabanı sorgulama ve araç kullanımı TCK <span style="font-weight: bold;" class="mycode_b">243, 244, 245</span> maddeleri kapsamında suç olabilir. Bu yazı eğitim amaçlıdır; sorumluluk uygulayana aittir.<br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=134" target="_blank" title="">000-team-07-team-b4a3e5.png</a> (Dosya Boyutu: 64.34 KB / İndirme Sayısı: 7)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[[center]<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=134" loading="lazy"  alt="[Resim: attachment.php?aid=134]" class="mycode_img" /></div>[/center]<br />
<br />
Selam TurkTeam, BlueTornado ile devam.<br />
<br />
SQL Injection (SQLi), uygulamanın SQL sorgusunu kullanıcı girdisiyle güvensiz biçimde birleştirmesi sonucu ortaya çıkan klasik bir enjeksiyon zafiyetidir. Bu rehberde sıfırdan teori, DVWA üzerinde Low/Medium/Impossible karşılaştırması, parametreli sorgular ve modern ORM hatalarını ele alıyoruz. Tüm örnekler <span style="font-weight: bold;" class="mycode_b">yalnızca yerel lab</span> içindir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Konuda Anlatılacaklar</span></span><br />
<ol type="1" class="mycode_list"><li>SQL Injection nedir, hangi riskleri taşır?<br />
</li>
<li>DVWA lab kurulumu<br />
</li>
<li>Kavramlar: union, boolean, error-based, blind<br />
</li>
<li>Low seviyede adım adım gözlem<br />
</li>
<li>Medium filtre ve prepared statement'a geçiş<br />
</li>
<li>Korunma: parametreli sorgu, ORM, least privilege<br />
</li>
<li>İleri seviye: second-order, WAF yanılsaması<br />
</li>
<li>Kaynakça ve yasal uyarı<br />
</li>
</ol>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">1) SQL Injection Nedir?</span></span><br />
Veritabanı, uygulamanın gönderdiği SQL metnini yorumlar. Saldırgan, girdi alanına SQL sözdizimi parçaları ekleyerek sorgunun mantığını değiştirebiliyorsa injection vardır.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Tehlikeli kalıp (kavramsal)
id = request.GET["id"]
sql = "SELECT first_name, last_name FROM users WHERE user_id = '" + id + "'"
# id = 1' OR '1'='1  olduğunda mantık bozulur</code></div></div><br />
Olası etkiler: kimlik doğrulamayı atlama, veri okuma/değiştirme, bazı DB/konfigürasyonlarda OS komutuna giden yollar (ör. xp_cmdshell gibi özellikler açıksa). Etki, DB kullanıcısının yetkisine ve uygulama mimarisine bağlıdır.<br />
<br />
OWASP Top 10 2021'de Injection <span style="font-weight: bold;" class="mycode_b">A03:2021</span> altındadır. CWE karşılığı başlıca <span style="font-weight: bold;" class="mycode_b">CWE-89</span>'dur.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">2) Lab Kurulumu</span></span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>git clone https://github.com/digininja/DVWA.git
cd DVWA
docker compose up -d</code></div></div><br />
Kurulum sonrası DVWA Security'yi <span style="font-weight: bold;" class="mycode_b">Low</span> yapın. SQL Injection ve SQL Injection (Blind) sayfalarını kullanacağız.<br />
<br />
[center][/center]<br />
<br />
İsteğe bağlı olarak kendi MySQL/MariaDB labınızda da aynı mantığı kurabilirsiniz; önemli olan üretim verisine dokunmamaktır.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">3) Kavram Referansı</span></span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">In-band (Union / Error):</span> Sonuç veya hata mesajı aynı kanalda döner.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Union temelli keşif (yalnızca lab, sözdizimi DB'ye göre değişir)
1' UNION SELECT null, null--
1' UNION SELECT user(), database()--</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Boolean-based blind:</span> Sayfa içeriği doğru/yanlış cevaba göre değişir; veri bit bit çıkarılır.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>1' AND 1=1--
1' AND 1=2--</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Time-based blind:</span> <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>SLEEP()</code></div></div> / <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>WAITFOR DELAY</code></div></div> ile zaman farkından çıkarım (labda dikkat: kendini DoS etme).<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># MySQL lab örneği (kendi DVWA'nız)
1' AND SLEEP(3)--</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Prepared statement / parametreli sorgu:</span> SQL yapısı ile verinin ayrılması. Asıl savunma budur.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Python psycopg / MySQL connector tarzı
cur.execute("SELECT * FROM users WHERE id = %s", (user_id,))</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">4) DVWA Low: Adım Adım</span></span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Adım 1 - Normal davranış:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>User ID: 1
# Beklenen: o kullanıcıya ait ad/soyad</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Adım 2 - Mantığı bozma:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>1' OR '1'='1
# Low seviyede genellikle birden fazla satır döner</code></div></div><br />
Çıktıyı yorumlayın: Uygulama girdi etrafına tırnak koyup birleştiriyorsa bu payload tüm satırları getirir. Bu, zafiyetin varlığını gösterir.<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Adım 3 - Sütun sayısını anlama (Union):</span><br />
DVWA Low'da klasik union yolu kullanılır. Önce sütun sayısını bulun:<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>1' ORDER BY 1--
1' ORDER BY 2--
1' ORDER BY 3--
# Hata aldığınız nokta sütun sayısını aştığınız yerdir</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>1' UNION SELECT user, password FROM users--
# Labda hash'lerin görünmesi, üretimde felaket senaryosudur</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Adım 4 - Hata mesajlarını okuma:</span><br />
Verbose SQL hataları hem enjeksiyonu kolaylaştırır hem bilgi sızdırır. Production'da genel hata sayfası kullanın; detayı loglayın.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Kötü: ham SQL exception'ı kullanıcıya göstermek
# İyi: "Bir hata oluştu" + sunucu tarafı log</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">5) Blind SQLi Sayfası</span></span><br />
DVWA SQL Injection (Blind) sayfasında sonuç satırları doğrudan basılmayabilir; "User ID exists" benzeri mesajlar görürsünüz.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>1' AND '1'='1
1' AND '1'='2</code></div></div><br />
Birinde "exists", diğerinde farklı mesaj varsa boolean blind mümkündür. Otomatik araçlar (sqlmap) bu farkları ölçer; <span style="font-weight: bold;" class="mycode_b">yalnızca kendi labınızda</span> ve yasal kapsamda kullanın.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># sqlmap lab örneği (DVWA localhost, kendi ortamınız)
sqlmap -u "http://127.0.0.1/vulnerabilities/sqli_blind/?id=1&amp;Submit=Submit" &#92;
  --cookie="security=low; PHPSESSID=..." &#92;
  --batch --technique=B</code></div></div><br />
sqlmap çıktısını yorumlarken: DBMS tipi, baner, tablolar. Üretimde izinsiz sqlmap çalıştırmak hem etik dışıdır hem yasadışıdır.<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">6) Medium ve Impossible: Ne Değişiyor?</span></span><br />
Medium'da DVWA genelde POST + mysql_real_escape_string benzeri kaçış veya seçim kutusu kullanır. Escape, yanlış bağlamda (ör. sayısal alan, farklı karakter seti) yeterli olmayabilir; asıl çözüm prepared statement'tır.<br />
<br />
Impossible seviyede parametreli sorgu görürsünüz. Kaynak kodu (DVWA PHP) inceleyerek farkı not edin:<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Kavramsal güvenli PHP
&#36;stmt = &#36;mysqli-&gt;prepare("SELECT first_name, last_name FROM users WHERE user_id = ?");
&#36;stmt-&gt;bind_param("s", &#36;id);
&#36;stmt-&gt;execute();</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># ORM örneği (Django)
User.objects.filter(id=user_id)
# Dikkat: raw() / extra() ile tekrar injection açabilirsiniz</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">7) Korunma Katmanları</span></span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Birincil:</span> Parametreli sorgu / ORM güvenli API<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Girdi doğrulama:</span> Beklenen tip (int), uzunluk, allowlist<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Least privilege:</span> Uygulama DB kullanıcısına DROP/FILE vermeyin<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Hata yönetimi:</span> Detaylı SQL hatalarını gizleyin<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">WAF:</span> Savunma derinliği; tek başına çözüm değil<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Test:</span> SAST, DAST, kod incelemesi, unit test ile raw SQL denetimi<br />
</li>
</ul>
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Beklenen tip kontrolü
if not user_id.isdigit():
    abort(400)</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># PostgreSQL rol örneği (kavramsal)
GRANT SELECT, INSERT, UPDATE ON app_schema.* TO app_user;
-- FILE, SUPERUSER yok</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">8) İleri Seviye</span></span><br />
<span style="font-weight: bold;" class="mycode_b">Second-order SQLi:</span> Girdi önce güvenli saklanır, sonra başka bir sorguda güvensiz birleştirilir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">ORM / query builder tuzakları:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Tehlikeli: kullanıcı girdisini SQL parçası sanmak
User.objects.raw("SELECT * FROM users WHERE name = '%s'" % name)</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">NoSQL injection:</span> MongoDB'de operatör enjeksiyonu (<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&#36;gt</code></div></div> vb.) ayrı bir ailedir; "SQL yoksa injection yok" yanılgısına düşmeyin.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Rapor şablonu:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Bulgu: SQL Injection (CWE-89)
Endpoint: GET /vulnerabilities/sqli?id=
Kanıt: Labda OR '1'='1 ile çoklu satır
Etki: users tablosu okuma (lab)
Öneri: prepared statement + least privilege</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">9) Sonuç</span></span><br />
SQLi, girdinin sorgu yapısına karışmasıdır. DVWA Low'da görün, Impossible'da doğru kodu okuyun, kendi projelerinizde raw string birleştirmeyi yasaklayın. Araçlar yardımcı olur; kök neden kod ve tasarımda kalır.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Kaynakça</span></span><ul class="mycode_list"><li><a href="https://owasp.org/www-community/attacks/SQL_Injection" target="_blank" rel="noopener" class="mycode_url">OWASP SQL Injection</a><br />
</li>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html" target="_blank" rel="noopener" class="mycode_url">OWASP SQLi Prevention Cheat Sheet</a><br />
</li>
<li><a href="https://github.com/digininja/DVWA" target="_blank" rel="noopener" class="mycode_url">DVWA</a><br />
</li>
<li><a href="https://sqlmap.org/" target="_blank" rel="noopener" class="mycode_url">sqlmap resmi site</a><br />
</li>
<li><a href="https://cwe.mitre.org/data/definitions/89.html" target="_blank" rel="noopener" class="mycode_url">CWE-89</a><br />
</li>
<li><a href="https://owasp.org/Top10/A03_2021-Injection/" target="_blank" rel="noopener" class="mycode_url">OWASP Top 10 2021 A03 Injection</a><br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Yasal Uyarı</span></span><br />
SQL Injection testleri yalnızca kendi sistemlerinizde veya yazılı izinli lab/pentest kapsamında yapılmalıdır. İzinsiz veritabanı sorgulama ve araç kullanımı TCK <span style="font-weight: bold;" class="mycode_b">243, 244, 245</span> maddeleri kapsamında suç olabilir. Bu yazı eğitim amaçlıdır; sorumluluk uygulayana aittir.<br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=134" target="_blank" title="">000-team-07-team-b4a3e5.png</a> (Dosya Boyutu: 64.34 KB / İndirme Sayısı: 7)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[IDOR ve Broken Access Control: Tespit ve Korunma Rehberi]]></title>
			<link>https://www.turkteam.org/konu-idor-ve-broken-access-control-tespit-ve-korunma-rehberi.html</link>
			<pubDate>Sat, 17 Oct 2026 16:40:26 +0300</pubDate>
			<dc:creator><![CDATA[<a href="https://www.turkteam.org/member.php?action=profile&uid=3">BilgeKagan</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.turkteam.org/konu-idor-ve-broken-access-control-tespit-ve-korunma-rehberi.html</guid>
			<description><![CDATA[[center]<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=128" loading="lazy"  alt="[Resim: attachment.php?aid=128]" class="mycode_img" /></div>[/center]<br />
<br />
Selam TurkTeam, BlueTornado yazıyor.<br />
<br />
Broken Access Control, OWASP Top 10 2021 listesinde <span style="font-weight: bold;" class="mycode_b">A01</span> olarak birinci sıradaydı. Altındaki en sık pratik bulgulardan biri de IDOR (Insecure Direct Object Reference). Bu konuda IDOR'un ne olduğunu, Broken Access Control ile ilişkisini, labda nasıl güvenli test edileceğini ve sunucu tarafı korunmayı anlatıyorum.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Konuda Anlatılacaklar</span></span><br />
<ol type="1" class="mycode_list"><li>Broken Access Control ve IDOR nedir?<br />
</li>
<li>Yatay / dikey yetki karışıklığı<br />
</li>
<li>Lab ortamı: Juice Shop ve basit demo API<br />
</li>
<li>Tespit adımları: parametre manipülasyonu<br />
</li>
<li>Korunma: yetki kontrolleri, dolaylı referanslar<br />
</li>
<li>İleri seviye: mass assignment, GraphQL, BOLA<br />
</li>
<li>Kaynakça ve yasal uyarı<br />
</li>
</ol>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">1) Teori: Erişim Kontrolü Bozulunca Ne Olur?</span></span><br />
Erişim kontrolü iki soruya cevap verir: "Bu kullanıcı kim?" (kimlik doğrulama) ve "Bu işlem / nesne için yetkisi var mı?" (yetkilendirme). Broken Access Control, ikinci sorunun atlanması veya yanlış cevaplanmasıdır.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">IDOR:</span> Uygulamanın iç nesneye (sipariş, dosya, mesaj) kullanıcı kontrollü bir kimlikle (id, uuid, dosya adı) doğrudan referans vermesi ve <span style="font-weight: bold;" class="mycode_b">sahiplik/yetki kontrolü yapmaması</span>.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Tehlikeli kalıp
@app.get("/api/orders/{order_id}")
def get_order(order_id: int):
    # Sadece login kontrolü var, sahiplik yok
    return db.orders.get(order_id)</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Doğru yönde
@app.get("/api/orders/{order_id}")
def get_order(order_id: int, user=Depends(current_user)):
    order = db.orders.get(order_id)
    if order is None or order.owner_id != user.id:
        raise HTTPException(404)  # veya 403
    return order</code></div></div><br />
IDOR yalnızca sayısal id'lerde olmaz. Tahmin edilebilir dosya yolları, e-posta adresleri, hesap numaraları da nesne referansı olabilir.<br />
<br />
<blockquote class="mycode_quote"><cite>Alıntı:</cite>UUID kullanmak IDOR'u "çözmez". Keşfi zorlaştırabilir; yetki kontrolü olmadan bilinmeyen UUID hâlâ başkasının verisine açılan kapıdır (ör. sızıntı, referrer, bildirim linki).</blockquote>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">2) Yatay ve Dikey Erişim</span></span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Yatay (horizontal):</span> Aynı roldeki A kullanıcısı, B kullanıcısının kaynağına erişir (klasik IDOR).<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Dikey (vertical):</span> Normal kullanıcı admin işlevine erişir (<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>/admin/deleteUser</code></div></div>).<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Bağlam / işlev:</span> Kullanıcı kendi siparişini görebilir ama "iade onayla" gibi ayrıcalıklı işlemi yapamamalıdır.<br />
</li>
</ul>
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Dikey örnek (kavramsal)
POST /api/admin/users/42/role  {"role":"admin"}
# Rol kontrolü yoksa Broken Access Control</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">3) Lab Ortamı</span></span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>docker pull bkimminich/juice-shop
docker run --rm -p 3000:3000 bkimminich/juice-shop</code></div></div><br />
Juice Shop'ta sepet, geri bildirim ve kullanıcı challenge'larında erişim kontrolü zafiyetleri bilinçli olarak vardır. Spoiler vermeden: kendi hesabınızla oluşturduğunuz nesnelerin kimliklerini not alıp, başka hesapla aynı kimliğe istek atmayı deneyin (yalnızca localhost).<br />
<br />
Basit bir yerel demo için:<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Flask iskeleti (kasıtlı zayıf - sadece lab)
orders = {1: {"owner": "ali", "item": "kitap"}, 2: {"owner": "ayse", "item": "kalem"}}

@app.get("/orders")
def get(id: int):
    return orders[id]  # sahiplik yok!</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">4) Kavram Referansı</span></span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Direct object reference:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>GET /invoices/18442.pdf
GET /api/v1/messages/9921</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Indirect reference map:</span> Kullanıcıya geçici, oturuma bağlı rastgele anahtar vermek. Yine de sunucuda yetki doğrulanmalıdır.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Kavramsal eşleme
session_refs["a8f0..."] = {"type":"invoice", "id":18442, "owner": user.id}</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Forced browsing:</span> Auth gerektiren URL'lerin tahmin edilerek gezilmesi.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>/admin/dashboard
/api/internal/metrics</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">CORS yanlış yapılandırması:</span> Access-Control-Allow-Origin: * ve credentials birlikte veya aşırı geniş origin listesi, tarayıcıdan yetkisiz okumayı kolaylaştırabilir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">5) Tespit: Adım Adım (Yasal Lab)</span></span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Adım 1 - İki hesap oluşturun.</span> A ve B. A ile kaynak yaratın (sipariş, not, dosya).<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Adım 2 - İstekleri kaydedin.</span> Burp / DevTools ile <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>order_id</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>userId</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>doc</code></div></div> parametrelerini bulun.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Örnek istek
GET /api/orders/105 HTTP/1.1
Cookie: session=A_SESSION</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Adım 3 - Kimliği değiştirin.</span> 105 yerine B'nin veya A'nın diğer kaydını koyun; oturum A'da kalsın.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>GET /api/orders/106 HTTP/1.1
Cookie: session=A_SESSION</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Adım 4 - Yanıtı yorumlayın.</span><ul class="mycode_list"><li>200 + B'nin verisi -&gt; yatay IDOR güçlü aday<br />
</li>
<li>403/404 -&gt; kontrol var (yine de başka uçları deneyin)<br />
</li>
<li>301 ile başka yere gitmek -&gt; mantığı anlayın<br />
</li>
</ul>
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Adım 5 - Metotları deneyin.</span> GET güvenli görünürken PUT/DELETE/PATCH açık kalmış olabilir.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>PUT /api/orders/106
{"status":"refunded"}</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Adım 6 - Encoding / tip oyunları.</span> <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>106</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>106.0</code></div></div>, dizi <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>[106]</code></div></div>, JSON <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>{"id":106}</code></div></div> gibi alternatif temsiller bazı framework'lerde farklı kod yollarına düşebilir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">6) Korunma</span></span><ul class="mycode_list"><li>Her istekte sunucu tarafı yetki kontrolü (deny by default)<br />
</li>
<li>"Bu nesne bu kullanıcıya mı ait?" sorusunu merkezi bir policy katmanında sorun<br />
</li>
<li>Sadece UI'da butonu gizlemek yetmez<br />
</li>
<li>Admin işlevlerini ayrı rol ve mümkünse ayrı ağ/segment ile koruyun<br />
</li>
<li>Loglayın: access.denied olayları<br />
</li>
<li>Otomatik test: A kullanıcısı B kaynağına 403 bekleyen entegrasyon testleri<br />
</li>
</ul>
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Pseudo-policy
def authorize(user, action, resource):
    if user.role == "admin" and action in ADMIN_ACTIONS:
        return True
    if resource.owner_id == user.id and action in OWNER_ACTIONS:
        return True
    return False</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Django örneği
class OrderDetail(LoginRequiredMixin, UserPassesTestMixin, DetailView):
    def test_func(self):
        return self.get_object().owner_id == self.request.user.id</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">7) İleri Seviye</span></span><br />
<span style="font-weight: bold;" class="mycode_b">BOLA (Broken Object Level Authorization):</span> OWASP API Top 10'da API'ler için IDOR'un karşılığıdır. API güvenliği konusunda ayrıca ele alınacak.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Mass assignment / bağlama:</span> Kullanıcının <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>{"role":"admin"}</code></div></div> alanını body'de gönderip profilini yükseltmesi.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Tehlikeli
user.update(request.json)
# Güvenli: allowlist
user.update({k: request.json[k] for k in ("name", "bio")})</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">GraphQL:</span> Nesne id'leri ile başka kullanıcı kayıtlarını çekmek; field-level authorization gerekir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Batch / IDOR otomasyonu:</span> Intruder ile id bruteforce yalnızca yetkili labda; üretimde rate limit ve izleme şarttır.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Rapor dili
Bulgu: IDOR / Broken Access Control (CWE-639)
Endpoint: GET /api/orders/{id}
Kanıt: Kullanıcı A, kullanıcı B siparişini 200 ile okudu
Öneri: sahiplik kontrolü + test otomasyonu</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">8) Sonuç</span></span><br />
IDOR, Broken Access Control ailesinin görünür yüzüdür. UUID, "gizli URL" veya sadece frontend kontrolü yetmez. Sunucuda her nesne erişiminde yetki sorun; A/B hesap testlerini CI'ya ekleyin.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Kaynakça</span></span><ul class="mycode_list"><li><a href="https://owasp.org/Top10/A01_2021-Broken_Access_Control/" target="_blank" rel="noopener" class="mycode_url">OWASP Top 10 2021 A01</a><br />
</li>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/Insecure_Direct_Object_Reference_Prevention_Cheat_Sheet.html" target="_blank" rel="noopener" class="mycode_url">OWASP IDOR Prevention Cheat Sheet</a><br />
</li>
<li><a href="https://owasp.org/API-Security/editions/2023/en/0xa1-broken-object-level-authorization/" target="_blank" rel="noopener" class="mycode_url">OWASP API Top 10 - BOLA</a><br />
</li>
<li><a href="https://cwe.mitre.org/data/definitions/639.html" target="_blank" rel="noopener" class="mycode_url">CWE-639</a><br />
</li>
<li><a href="https://owasp.org/www-project-juice-shop/" target="_blank" rel="noopener" class="mycode_url">OWASP Juice Shop</a><br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Yasal Uyarı</span></span><br />
Erişim kontrolü testleri yalnızca kendi uygulamalarınızda veya yazılı yetki kapsamındaki pentestlerde yapılmalıdır. Başkasının hesabına veya sistemine izinsiz erişim denemesi TCK <span style="font-weight: bold;" class="mycode_b">243-245</span> kapsamında suç oluşturabilir. Eğitim amaçlıdır; sorumluluk uygulayana aittir.<br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=128" target="_blank" title="">000-team-08-team-daccdd.png</a> (Dosya Boyutu: 63.82 KB / İndirme Sayısı: 7)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[[center]<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=128" loading="lazy"  alt="[Resim: attachment.php?aid=128]" class="mycode_img" /></div>[/center]<br />
<br />
Selam TurkTeam, BlueTornado yazıyor.<br />
<br />
Broken Access Control, OWASP Top 10 2021 listesinde <span style="font-weight: bold;" class="mycode_b">A01</span> olarak birinci sıradaydı. Altındaki en sık pratik bulgulardan biri de IDOR (Insecure Direct Object Reference). Bu konuda IDOR'un ne olduğunu, Broken Access Control ile ilişkisini, labda nasıl güvenli test edileceğini ve sunucu tarafı korunmayı anlatıyorum.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Konuda Anlatılacaklar</span></span><br />
<ol type="1" class="mycode_list"><li>Broken Access Control ve IDOR nedir?<br />
</li>
<li>Yatay / dikey yetki karışıklığı<br />
</li>
<li>Lab ortamı: Juice Shop ve basit demo API<br />
</li>
<li>Tespit adımları: parametre manipülasyonu<br />
</li>
<li>Korunma: yetki kontrolleri, dolaylı referanslar<br />
</li>
<li>İleri seviye: mass assignment, GraphQL, BOLA<br />
</li>
<li>Kaynakça ve yasal uyarı<br />
</li>
</ol>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">1) Teori: Erişim Kontrolü Bozulunca Ne Olur?</span></span><br />
Erişim kontrolü iki soruya cevap verir: "Bu kullanıcı kim?" (kimlik doğrulama) ve "Bu işlem / nesne için yetkisi var mı?" (yetkilendirme). Broken Access Control, ikinci sorunun atlanması veya yanlış cevaplanmasıdır.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">IDOR:</span> Uygulamanın iç nesneye (sipariş, dosya, mesaj) kullanıcı kontrollü bir kimlikle (id, uuid, dosya adı) doğrudan referans vermesi ve <span style="font-weight: bold;" class="mycode_b">sahiplik/yetki kontrolü yapmaması</span>.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Tehlikeli kalıp
@app.get("/api/orders/{order_id}")
def get_order(order_id: int):
    # Sadece login kontrolü var, sahiplik yok
    return db.orders.get(order_id)</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Doğru yönde
@app.get("/api/orders/{order_id}")
def get_order(order_id: int, user=Depends(current_user)):
    order = db.orders.get(order_id)
    if order is None or order.owner_id != user.id:
        raise HTTPException(404)  # veya 403
    return order</code></div></div><br />
IDOR yalnızca sayısal id'lerde olmaz. Tahmin edilebilir dosya yolları, e-posta adresleri, hesap numaraları da nesne referansı olabilir.<br />
<br />
<blockquote class="mycode_quote"><cite>Alıntı:</cite>UUID kullanmak IDOR'u "çözmez". Keşfi zorlaştırabilir; yetki kontrolü olmadan bilinmeyen UUID hâlâ başkasının verisine açılan kapıdır (ör. sızıntı, referrer, bildirim linki).</blockquote>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">2) Yatay ve Dikey Erişim</span></span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Yatay (horizontal):</span> Aynı roldeki A kullanıcısı, B kullanıcısının kaynağına erişir (klasik IDOR).<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Dikey (vertical):</span> Normal kullanıcı admin işlevine erişir (<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>/admin/deleteUser</code></div></div>).<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Bağlam / işlev:</span> Kullanıcı kendi siparişini görebilir ama "iade onayla" gibi ayrıcalıklı işlemi yapamamalıdır.<br />
</li>
</ul>
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Dikey örnek (kavramsal)
POST /api/admin/users/42/role  {"role":"admin"}
# Rol kontrolü yoksa Broken Access Control</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">3) Lab Ortamı</span></span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>docker pull bkimminich/juice-shop
docker run --rm -p 3000:3000 bkimminich/juice-shop</code></div></div><br />
Juice Shop'ta sepet, geri bildirim ve kullanıcı challenge'larında erişim kontrolü zafiyetleri bilinçli olarak vardır. Spoiler vermeden: kendi hesabınızla oluşturduğunuz nesnelerin kimliklerini not alıp, başka hesapla aynı kimliğe istek atmayı deneyin (yalnızca localhost).<br />
<br />
Basit bir yerel demo için:<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Flask iskeleti (kasıtlı zayıf - sadece lab)
orders = {1: {"owner": "ali", "item": "kitap"}, 2: {"owner": "ayse", "item": "kalem"}}

@app.get("/orders")
def get(id: int):
    return orders[id]  # sahiplik yok!</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">4) Kavram Referansı</span></span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Direct object reference:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>GET /invoices/18442.pdf
GET /api/v1/messages/9921</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Indirect reference map:</span> Kullanıcıya geçici, oturuma bağlı rastgele anahtar vermek. Yine de sunucuda yetki doğrulanmalıdır.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Kavramsal eşleme
session_refs["a8f0..."] = {"type":"invoice", "id":18442, "owner": user.id}</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Forced browsing:</span> Auth gerektiren URL'lerin tahmin edilerek gezilmesi.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>/admin/dashboard
/api/internal/metrics</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">CORS yanlış yapılandırması:</span> Access-Control-Allow-Origin: * ve credentials birlikte veya aşırı geniş origin listesi, tarayıcıdan yetkisiz okumayı kolaylaştırabilir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">5) Tespit: Adım Adım (Yasal Lab)</span></span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Adım 1 - İki hesap oluşturun.</span> A ve B. A ile kaynak yaratın (sipariş, not, dosya).<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Adım 2 - İstekleri kaydedin.</span> Burp / DevTools ile <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>order_id</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>userId</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>doc</code></div></div> parametrelerini bulun.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Örnek istek
GET /api/orders/105 HTTP/1.1
Cookie: session=A_SESSION</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Adım 3 - Kimliği değiştirin.</span> 105 yerine B'nin veya A'nın diğer kaydını koyun; oturum A'da kalsın.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>GET /api/orders/106 HTTP/1.1
Cookie: session=A_SESSION</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Adım 4 - Yanıtı yorumlayın.</span><ul class="mycode_list"><li>200 + B'nin verisi -&gt; yatay IDOR güçlü aday<br />
</li>
<li>403/404 -&gt; kontrol var (yine de başka uçları deneyin)<br />
</li>
<li>301 ile başka yere gitmek -&gt; mantığı anlayın<br />
</li>
</ul>
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Adım 5 - Metotları deneyin.</span> GET güvenli görünürken PUT/DELETE/PATCH açık kalmış olabilir.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>PUT /api/orders/106
{"status":"refunded"}</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Adım 6 - Encoding / tip oyunları.</span> <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>106</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>106.0</code></div></div>, dizi <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>[106]</code></div></div>, JSON <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>{"id":106}</code></div></div> gibi alternatif temsiller bazı framework'lerde farklı kod yollarına düşebilir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">6) Korunma</span></span><ul class="mycode_list"><li>Her istekte sunucu tarafı yetki kontrolü (deny by default)<br />
</li>
<li>"Bu nesne bu kullanıcıya mı ait?" sorusunu merkezi bir policy katmanında sorun<br />
</li>
<li>Sadece UI'da butonu gizlemek yetmez<br />
</li>
<li>Admin işlevlerini ayrı rol ve mümkünse ayrı ağ/segment ile koruyun<br />
</li>
<li>Loglayın: access.denied olayları<br />
</li>
<li>Otomatik test: A kullanıcısı B kaynağına 403 bekleyen entegrasyon testleri<br />
</li>
</ul>
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Pseudo-policy
def authorize(user, action, resource):
    if user.role == "admin" and action in ADMIN_ACTIONS:
        return True
    if resource.owner_id == user.id and action in OWNER_ACTIONS:
        return True
    return False</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Django örneği
class OrderDetail(LoginRequiredMixin, UserPassesTestMixin, DetailView):
    def test_func(self):
        return self.get_object().owner_id == self.request.user.id</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">7) İleri Seviye</span></span><br />
<span style="font-weight: bold;" class="mycode_b">BOLA (Broken Object Level Authorization):</span> OWASP API Top 10'da API'ler için IDOR'un karşılığıdır. API güvenliği konusunda ayrıca ele alınacak.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Mass assignment / bağlama:</span> Kullanıcının <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>{"role":"admin"}</code></div></div> alanını body'de gönderip profilini yükseltmesi.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Tehlikeli
user.update(request.json)
# Güvenli: allowlist
user.update({k: request.json[k] for k in ("name", "bio")})</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">GraphQL:</span> Nesne id'leri ile başka kullanıcı kayıtlarını çekmek; field-level authorization gerekir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Batch / IDOR otomasyonu:</span> Intruder ile id bruteforce yalnızca yetkili labda; üretimde rate limit ve izleme şarttır.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Rapor dili
Bulgu: IDOR / Broken Access Control (CWE-639)
Endpoint: GET /api/orders/{id}
Kanıt: Kullanıcı A, kullanıcı B siparişini 200 ile okudu
Öneri: sahiplik kontrolü + test otomasyonu</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">8) Sonuç</span></span><br />
IDOR, Broken Access Control ailesinin görünür yüzüdür. UUID, "gizli URL" veya sadece frontend kontrolü yetmez. Sunucuda her nesne erişiminde yetki sorun; A/B hesap testlerini CI'ya ekleyin.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Kaynakça</span></span><ul class="mycode_list"><li><a href="https://owasp.org/Top10/A01_2021-Broken_Access_Control/" target="_blank" rel="noopener" class="mycode_url">OWASP Top 10 2021 A01</a><br />
</li>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/Insecure_Direct_Object_Reference_Prevention_Cheat_Sheet.html" target="_blank" rel="noopener" class="mycode_url">OWASP IDOR Prevention Cheat Sheet</a><br />
</li>
<li><a href="https://owasp.org/API-Security/editions/2023/en/0xa1-broken-object-level-authorization/" target="_blank" rel="noopener" class="mycode_url">OWASP API Top 10 - BOLA</a><br />
</li>
<li><a href="https://cwe.mitre.org/data/definitions/639.html" target="_blank" rel="noopener" class="mycode_url">CWE-639</a><br />
</li>
<li><a href="https://owasp.org/www-project-juice-shop/" target="_blank" rel="noopener" class="mycode_url">OWASP Juice Shop</a><br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Yasal Uyarı</span></span><br />
Erişim kontrolü testleri yalnızca kendi uygulamalarınızda veya yazılı yetki kapsamındaki pentestlerde yapılmalıdır. Başkasının hesabına veya sistemine izinsiz erişim denemesi TCK <span style="font-weight: bold;" class="mycode_b">243-245</span> kapsamında suç oluşturabilir. Eğitim amaçlıdır; sorumluluk uygulayana aittir.<br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=128" target="_blank" title="">000-team-08-team-daccdd.png</a> (Dosya Boyutu: 63.82 KB / İndirme Sayısı: 7)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[XSS Nedir? Reflected, Stored ve DOM Tabanlı XSS (DVWA Lab ile Uygulamalı)]]></title>
			<link>https://www.turkteam.org/konu-xss-nedir-reflected-stored-ve-dom-tabanli-xss-dvwa-lab-ile-uygulamali.html</link>
			<pubDate>Sat, 17 Oct 2026 16:37:29 +0300</pubDate>
			<dc:creator><![CDATA[<a href="https://www.turkteam.org/member.php?action=profile&uid=3">BilgeKagan</a>]]></dc:creator>
			<guid isPermaLink="false">https://www.turkteam.org/konu-xss-nedir-reflected-stored-ve-dom-tabanli-xss-dvwa-lab-ile-uygulamali.html</guid>
			<description><![CDATA[[center]<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=126" loading="lazy"  alt="[Resim: attachment.php?aid=126]" class="mycode_img" /></div>[/center]<br />
<br />
Selam millet, BlueTornado burada.<br />
<br />
Cross-Site Scripting (XSS), web uygulamalarında en sık karşılaşılan enjeksiyon zafiyetlerinden biridir. Bu konuda XSS'in ne olduğunu, üç ana tipini (Reflected, Stored, DOM), DVWA labında nasıl güvenli şekilde gözlemleyeceğinizi ve korunma yöntemlerini adım adım anlatacağım. Amaç saldırı senaryosu ezberletmek değil; <span style="font-weight: bold;" class="mycode_b">neden oluştuğunu</span> ve <span style="font-weight: bold;" class="mycode_b">nasıl engellendiğini</span> anlamanız.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Konuda Anlatılacaklar</span></span><br />
<ol type="1" class="mycode_list"><li>XSS nedir, ne değildir?<br />
</li>
<li>DVWA lab kurulumu ve güvenlik seviyeleri<br />
</li>
<li>Reflected XSS: istekte yansıyan girdi<br />
</li>
<li>Stored XSS: kalıcı depolanan girdi<br />
</li>
<li>DOM-based XSS: tarayıcı tarafı<br />
</li>
<li>Çıktı encoding, CSP ve framework korumaları<br />
</li>
<li>İleri seviye: mutasyon XSS, cookie bayrakları, raporlama<br />
</li>
<li>Kaynakça ve yasal uyarı<br />
</li>
</ol>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">1) XSS Nedir?</span></span><br />
XSS, uygulamanın kullanıcıdan gelen veriyi, tarayıcının JavaScript olarak yorumlayabileceği biçimde <span style="font-weight: bold;" class="mycode_b">doğrulamadan veya encode etmeden</span> HTML/JS bağlamına yazmasıdır. Sonuçta saldırgan, kurbanın tarayıcısında kendi script'ini çalıştırabilir.<br />
<br />
XSS ile yapılabilecekler (eğitim bağlamında riskleri anlamak için):<ul class="mycode_list"><li>Oturum çerezinin (HttpOnly değilse) okunması<br />
</li>
<li>Sayfa içeriğinin değiştirilmesi (defacement / phishing formu)<br />
</li>
<li>Kurban adına istek atılması (aynı origin içinde)<br />
</li>
<li>Keylogger benzeri script enjekte edilmesi<br />
</li>
</ul>
<br />
XSS bir "sunucuyu ele geçirme" zafiyeti değildir; <span style="font-weight: bold;" class="mycode_b">kullanıcının tarayıcısını</span> hedefler. Yine de admin paneline Stored XSS düşerse etki çok yüksek olabilir.<br />
<br />
<blockquote class="mycode_quote"><cite>Alıntı:</cite>OWASP Top 10 2021'de XSS, A03 Injection kategorisi altında değerlendirilir. Ayrı bir Top 10 maddesi olarak listelenmese de pratikte en sık bulgulardan biridir.</blockquote>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">2) Lab: DVWA Kurulumu</span></span><br />
Yalnızca kendi bilgisayarınızda, izole ortamda çalıştırın.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>git clone https://github.com/digininja/DVWA.git
cd DVWA
docker compose up -d</code></div></div><br />
Tarayıcı: <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>http://127.0.0.1</code></div></div> (compose port eşlemenize göre değişebilir). Varsayılan giriş bilgileri DVWA dokümantasyonunda yer alır; ilk girişte Setup sayfasından veritabanını oluşturun.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Güvenlik seviyesini ayarlamak için DVWA menüsü:
# DVWA Security -&gt; Low / Medium / High / Impossible</code></div></div><br />
Bu konuda önce <span style="font-weight: bold;" class="mycode_b">Low</span>, sonra <span style="font-weight: bold;" class="mycode_b">Impossible</span> seviyesini karşılaştıracağız. Impossible, korunmuş referans implementasyondur.<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">3) Kavram Referansı</span></span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Context (bağlam):</span> Girdinin HTML gövdesine mi, attribute içine mi, JavaScript string'ine mi, URL'ye mi yazıldığı kritiktir. Encoding stratejisi bağlama göre değişir.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># HTML gövde bağlamı (kavramsal tehlikeli)
echo "&lt;p&gt;Merhaba &#36;name&lt;/p&gt;"

# Attribute bağlamı
echo "&lt;input value='&#36;name'&gt;"</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Output encoding:</span> Gösterilecek verinin HTML entity'ye çevrilmesi (<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&lt;</code></div></div> -&gt; <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&amp;lt;</code></div></div> gibi).<br />
<br />
<span style="font-weight: bold;" class="mycode_b">CSP (Content Security Policy):</span> Tarayıcıya hangi script kaynaklarının çalışabileceğini söyleyen HTTP başlığı. XSS'i tamamen bitirmez ama etkisini ciddi azaltır.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Örnek CSP (sıkılaştırılmış, kavramsal)
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">HttpOnly / Secure / SameSite çerez bayrakları:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Set-Cookie: session=...; HttpOnly; Secure; SameSite=Lax</code></div></div>HttpOnly, document.cookie ile çerezin JS'ten okunmasını engeller (XSS'in oturum çalma etkisini azaltır; XSS'i yok etmez).<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">4) Reflected XSS (DVWA Low)</span></span><br />
Reflected XSS'te zararlı girdi genellikle URL parametresi veya form alanı olarak gelir, sunucu cevabında hemen yansır ve depolanmaz. Kurbanın özel hazırlanmış bir linke tıklaması gerekir.<br />
<br />
DVWA'da <span style="font-weight: bold;" class="mycode_b">XSS (Reflected)</span> sayfasına gidin, güvenlik seviyesini Low yapın.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Labda denenebilecek basit payload (yalnızca DVWA)
&lt;script&gt;alert(1)&lt;/script&gt;</code></div></div><br />
Forma yazıp gönderdiğinizde alert çıkıyorsa, girdi encode edilmeden HTML'e basılıyor demektir. Bu, "XSS var" kanıtı için klasik bir smoke test'tir; gerçek bir pentest raporunda daha anlamlı bir PoC (ör. çerez bayrağı kontrolü, DOM değişikliği) tercih edilir.<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Çıktıyı yorumlama:</span><ul class="mycode_list"><li>Alert çıktı -&gt; girdi script olarak yorumlandı<br />
</li>
<li>Sayfada <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&amp;lt;script&amp;gt;</code></div></div> görünüyorsa encoding çalışıyor olabilir<br />
</li>
<li>WAF/filtre sadece <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&lt;script&gt;</code></div></div> kelimesini kesiyorsa başka etiketlerle bypass denenir; labda High seviyeye geçmeden önce filtre mantığını anlayın<br />
</li>
</ul>
<br />
Medium seviyede çoğu DVWA kurulumunda <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&lt;script&gt;</code></div></div> kelimesi strip edilir. Bu, güvenli encoding değildir; kara liste (blacklist) yaklaşımıdır ve kırılgandır.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Kara listenin zayıflığı (kavramsal örnekler, lab)
&lt;img src=x onerror=alert(1)&gt;
&lt;svg onload=alert(1)&gt;</code></div></div><br />
Impossible seviyesinde htmlspecialchars benzeri doğru encoding kullanılır; payload metin olarak görünür, çalışmaz.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">5) Stored XSS (DVWA)</span></span><br />
Stored (persistent) XSS'te girdi veritabanına veya başka kalıcı depoya yazılır ve her ziyaretçinin sayfasında tekrar gösterilir. Guestbook, yorum, profil bio alanları tipik hedeflerdir.<br />
<br />
DVWA <span style="font-weight: bold;" class="mycode_b">XSS (Stored)</span> sayfasında Low seviyede name/message alanlarına payload bırakın:<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&lt;script&gt;alert('stored')&lt;/script&gt;</code></div></div><br />
Sayfayı yenilediğinizde veya başka bir tarayıcı profiliyle girdiğinizde alert tekrarlanıyorsa Stored XSS söz konusudur. Etki yüzeyi Reflected'dan genelde daha yüksektir çünkü tek bir kurban linki gerekmez.<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Savunma gözlemi:</span> Impossible seviyeye alıp aynı payload'ı deneyin. Veri saklansa bile gösterilirken encode edilmelidir. "Saklarken temizle, gösterirken encode et" ikilisinden özellikle <span style="font-weight: bold;" class="mycode_b">gösterirken encode</span> vazgeçilmezdir; çünkü veri birden fazla bağlamda kullanılabilir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">6) DOM-Based XSS</span></span><br />
DOM XSS'te sunucu cevabı "temiz" görünebilir; zafiyet tarayıcıdaki JavaScript'in <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>location</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>hash</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>document.referrer</code></div></div> gibi kaynaklardan okuduğu veriyi <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>innerHTML</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>document.write</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>eval</code></div></div> gibi güvenli olmayan sink'lere yazmasından doğar.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>// Tehlikeli kalıp (kavramsal)
var q = location.hash.substring(1);
document.getElementById('out').innerHTML = q;

// Daha güvenli: textContent kullanmak
document.getElementById('out').textContent = q;</code></div></div><br />
DVWA'da DOM XSS için ayrı sayfa/versiyon farklılıkları olabilir; Juice Shop challenge'larında da DOM XSS örnekleri bulunur. Kaynak (source) ve sink listeleri için OWASP DOM based XSS Prevention Cheat Sheet'e bakın.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Kaynak örnekleri: location, document.URL, postMessage
# Sink örnekleri: innerHTML, outerHTML, eval, setTimeout(string)</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">7) Uygulamalı: Filtreyi Anlamak (Adım Adım)</span></span><br />
Low -&gt; Medium -&gt; High ilerleyin; her seviyede şu notları alın:<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Not şablonu
Seviye: Medium
Denenen: &lt;script&gt;alert(1)&lt;/script&gt;
Sonuç: script kelimesi silindi / sayfa boş / encode edildi
Çıkarım: blacklist mi, encoding mi?</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># High seviyede sık görülen: gelişmiş filtre veya kısmi encoding
# Impossible: doğru kütüphane encoding + katı kurallar</code></div></div><br />
Burp Suite kullanıyorsanız Proxy ile isteği yakalayıp parametreyi Repeater'da değiştirerek sunucu cevabında girdinin nereye yazıldığını izleyin (yalnızca lab).<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">8) Korunma: Geliştirici Kontrol Listesi</span></span><ul class="mycode_list"><li>Şablon motorunun otomatik escaping özelliğini kapatmayın (Django, Jinja2 autoescape, React JSX varsayılanı)<br />
</li>
<li><div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>dangerouslySetInnerHTML</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>|safe</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>v-html</code></div></div> gibi kaçış kapılarını kod incelemesinde işaretleyin<br />
</li>
<li>Bağlama uygun encoding kullanın (HTML, attribute, JS, URL, CSS ayrıdır)<br />
</li>
<li>Zengin metin (WYSIWYG) gerekiyorsa sıkı HTML sanitizer (ör. DOMPurify) kullanın<br />
</li>
<li>CSP ekleyin; inline script'i azaltın<br />
</li>
<li>Çerezlerde HttpOnly; Secure; SameSite ayarlayın<br />
</li>
<li>WAF kara listesine güvenerek "XSS bitti" demeyin<br />
</li>
</ul>
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Python / Jinja2 (otomatik escape açıkken)
{{ user_comment }}

# Bilerek ham HTML (kaçının veya sanitize edin)
{{ user_comment | safe }}</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># PHP örneği (bağlama göre)
echo htmlspecialchars(&#36;name, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">9) İleri Seviye Notlar</span></span><br />
<span style="font-weight: bold;" class="mycode_b">Mutation XSS (mXSS):</span> Tarayıcının HTML parser'ının beklenmedik şekilde DOM'u "düzeltmesi" sonucu sanitizer'ların bypass edilmesi. Kendi sanitizer'ınızı yazmak yerine bakımı yapılan kütüphaneleri kullanın.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Blind XSS:</span> Payload'un admin panelinde, log görüntüleyicide veya destek aracında sonradan tetiklenmesi. BeAlert / XSS Hunter benzeri geri çağırma (callback) servisleri pentestlerde kullanılır; izinsiz sistemlerde asla.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Raporlama dili:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Bulgu: Stored XSS (CWE-79)
Konum: /guestbook message alanı
Etki: Oturum çerezi HttpOnly değilse hesap ele geçirme riski
Kanıt: Lab ortamında alert PoC + HTML kaynak çıktısı
Öneri: Çıktı encoding + CSP + HttpOnly</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">10) Sonuç</span></span><br />
XSS; Reflected, Stored ve DOM olarak üç ana ailede incelenir. Ortak kök neden, güvensiz bağlama yazımdır. DVWA Low'da zafiyeti görün, Impossible'da doğru kodu inceleyin, kendi uygulamanızda escaping + CSP + çerez bayraklarını kontrol edin.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Kaynakça</span></span><ul class="mycode_list"><li><a href="https://owasp.org/www-community/attacks/xss/" target="_blank" rel="noopener" class="mycode_url">OWASP XSS</a><br />
</li>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html" target="_blank" rel="noopener" class="mycode_url">OWASP XSS Prevention Cheat Sheet</a><br />
</li>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/DOM_based_XSS_Prevention_Cheat_Sheet.html" target="_blank" rel="noopener" class="mycode_url">OWASP DOM based XSS Prevention</a><br />
</li>
<li><a href="https://github.com/digininja/DVWA" target="_blank" rel="noopener" class="mycode_url">DVWA (GitHub)</a><br />
</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP" target="_blank" rel="noopener" class="mycode_url">MDN Content Security Policy</a><br />
</li>
<li><a href="https://cwe.mitre.org/data/definitions/79.html" target="_blank" rel="noopener" class="mycode_url">CWE-79</a><br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Yasal Uyarı</span></span><br />
Bu içerik eğitim ve savunma amaçlıdır. XSS testleri yalnızca <span style="font-weight: bold;" class="mycode_b">kendi labınızda</span> veya <span style="font-weight: bold;" class="mycode_b">yazılı yetki</span> verilen sistemlerde yapılmalıdır. İzinsiz testler TCK <span style="font-weight: bold;" class="mycode_b">243-245</span> kapsamında suç oluşturabilir. Sorumluluk uygulayana aittir.<br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=126" target="_blank" title="">000-team-06-team-1e62fe.png</a> (Dosya Boyutu: 69.38 KB / İndirme Sayısı: 5)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[[center]<div style="text-align: center;" class="mycode_align"><img src="https://www.turkteam.org/attachment.php?aid=126" loading="lazy"  alt="[Resim: attachment.php?aid=126]" class="mycode_img" /></div>[/center]<br />
<br />
Selam millet, BlueTornado burada.<br />
<br />
Cross-Site Scripting (XSS), web uygulamalarında en sık karşılaşılan enjeksiyon zafiyetlerinden biridir. Bu konuda XSS'in ne olduğunu, üç ana tipini (Reflected, Stored, DOM), DVWA labında nasıl güvenli şekilde gözlemleyeceğinizi ve korunma yöntemlerini adım adım anlatacağım. Amaç saldırı senaryosu ezberletmek değil; <span style="font-weight: bold;" class="mycode_b">neden oluştuğunu</span> ve <span style="font-weight: bold;" class="mycode_b">nasıl engellendiğini</span> anlamanız.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Konuda Anlatılacaklar</span></span><br />
<ol type="1" class="mycode_list"><li>XSS nedir, ne değildir?<br />
</li>
<li>DVWA lab kurulumu ve güvenlik seviyeleri<br />
</li>
<li>Reflected XSS: istekte yansıyan girdi<br />
</li>
<li>Stored XSS: kalıcı depolanan girdi<br />
</li>
<li>DOM-based XSS: tarayıcı tarafı<br />
</li>
<li>Çıktı encoding, CSP ve framework korumaları<br />
</li>
<li>İleri seviye: mutasyon XSS, cookie bayrakları, raporlama<br />
</li>
<li>Kaynakça ve yasal uyarı<br />
</li>
</ol>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">1) XSS Nedir?</span></span><br />
XSS, uygulamanın kullanıcıdan gelen veriyi, tarayıcının JavaScript olarak yorumlayabileceği biçimde <span style="font-weight: bold;" class="mycode_b">doğrulamadan veya encode etmeden</span> HTML/JS bağlamına yazmasıdır. Sonuçta saldırgan, kurbanın tarayıcısında kendi script'ini çalıştırabilir.<br />
<br />
XSS ile yapılabilecekler (eğitim bağlamında riskleri anlamak için):<ul class="mycode_list"><li>Oturum çerezinin (HttpOnly değilse) okunması<br />
</li>
<li>Sayfa içeriğinin değiştirilmesi (defacement / phishing formu)<br />
</li>
<li>Kurban adına istek atılması (aynı origin içinde)<br />
</li>
<li>Keylogger benzeri script enjekte edilmesi<br />
</li>
</ul>
<br />
XSS bir "sunucuyu ele geçirme" zafiyeti değildir; <span style="font-weight: bold;" class="mycode_b">kullanıcının tarayıcısını</span> hedefler. Yine de admin paneline Stored XSS düşerse etki çok yüksek olabilir.<br />
<br />
<blockquote class="mycode_quote"><cite>Alıntı:</cite>OWASP Top 10 2021'de XSS, A03 Injection kategorisi altında değerlendirilir. Ayrı bir Top 10 maddesi olarak listelenmese de pratikte en sık bulgulardan biridir.</blockquote>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">2) Lab: DVWA Kurulumu</span></span><br />
Yalnızca kendi bilgisayarınızda, izole ortamda çalıştırın.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>git clone https://github.com/digininja/DVWA.git
cd DVWA
docker compose up -d</code></div></div><br />
Tarayıcı: <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>http://127.0.0.1</code></div></div> (compose port eşlemenize göre değişebilir). Varsayılan giriş bilgileri DVWA dokümantasyonunda yer alır; ilk girişte Setup sayfasından veritabanını oluşturun.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Güvenlik seviyesini ayarlamak için DVWA menüsü:
# DVWA Security -&gt; Low / Medium / High / Impossible</code></div></div><br />
Bu konuda önce <span style="font-weight: bold;" class="mycode_b">Low</span>, sonra <span style="font-weight: bold;" class="mycode_b">Impossible</span> seviyesini karşılaştıracağız. Impossible, korunmuş referans implementasyondur.<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">3) Kavram Referansı</span></span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Context (bağlam):</span> Girdinin HTML gövdesine mi, attribute içine mi, JavaScript string'ine mi, URL'ye mi yazıldığı kritiktir. Encoding stratejisi bağlama göre değişir.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># HTML gövde bağlamı (kavramsal tehlikeli)
echo "&lt;p&gt;Merhaba &#36;name&lt;/p&gt;"

# Attribute bağlamı
echo "&lt;input value='&#36;name'&gt;"</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">Output encoding:</span> Gösterilecek verinin HTML entity'ye çevrilmesi (<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&lt;</code></div></div> -&gt; <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&amp;lt;</code></div></div> gibi).<br />
<br />
<span style="font-weight: bold;" class="mycode_b">CSP (Content Security Policy):</span> Tarayıcıya hangi script kaynaklarının çalışabileceğini söyleyen HTTP başlığı. XSS'i tamamen bitirmez ama etkisini ciddi azaltır.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Örnek CSP (sıkılaştırılmış, kavramsal)
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b">HttpOnly / Secure / SameSite çerez bayrakları:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Set-Cookie: session=...; HttpOnly; Secure; SameSite=Lax</code></div></div>HttpOnly, document.cookie ile çerezin JS'ten okunmasını engeller (XSS'in oturum çalma etkisini azaltır; XSS'i yok etmez).<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">4) Reflected XSS (DVWA Low)</span></span><br />
Reflected XSS'te zararlı girdi genellikle URL parametresi veya form alanı olarak gelir, sunucu cevabında hemen yansır ve depolanmaz. Kurbanın özel hazırlanmış bir linke tıklaması gerekir.<br />
<br />
DVWA'da <span style="font-weight: bold;" class="mycode_b">XSS (Reflected)</span> sayfasına gidin, güvenlik seviyesini Low yapın.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Labda denenebilecek basit payload (yalnızca DVWA)
&lt;script&gt;alert(1)&lt;/script&gt;</code></div></div><br />
Forma yazıp gönderdiğinizde alert çıkıyorsa, girdi encode edilmeden HTML'e basılıyor demektir. Bu, "XSS var" kanıtı için klasik bir smoke test'tir; gerçek bir pentest raporunda daha anlamlı bir PoC (ör. çerez bayrağı kontrolü, DOM değişikliği) tercih edilir.<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Çıktıyı yorumlama:</span><ul class="mycode_list"><li>Alert çıktı -&gt; girdi script olarak yorumlandı<br />
</li>
<li>Sayfada <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&amp;lt;script&amp;gt;</code></div></div> görünüyorsa encoding çalışıyor olabilir<br />
</li>
<li>WAF/filtre sadece <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&lt;script&gt;</code></div></div> kelimesini kesiyorsa başka etiketlerle bypass denenir; labda High seviyeye geçmeden önce filtre mantığını anlayın<br />
</li>
</ul>
<br />
Medium seviyede çoğu DVWA kurulumunda <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&lt;script&gt;</code></div></div> kelimesi strip edilir. Bu, güvenli encoding değildir; kara liste (blacklist) yaklaşımıdır ve kırılgandır.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Kara listenin zayıflığı (kavramsal örnekler, lab)
&lt;img src=x onerror=alert(1)&gt;
&lt;svg onload=alert(1)&gt;</code></div></div><br />
Impossible seviyesinde htmlspecialchars benzeri doğru encoding kullanılır; payload metin olarak görünür, çalışmaz.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">5) Stored XSS (DVWA)</span></span><br />
Stored (persistent) XSS'te girdi veritabanına veya başka kalıcı depoya yazılır ve her ziyaretçinin sayfasında tekrar gösterilir. Guestbook, yorum, profil bio alanları tipik hedeflerdir.<br />
<br />
DVWA <span style="font-weight: bold;" class="mycode_b">XSS (Stored)</span> sayfasında Low seviyede name/message alanlarına payload bırakın:<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>&lt;script&gt;alert('stored')&lt;/script&gt;</code></div></div><br />
Sayfayı yenilediğinizde veya başka bir tarayıcı profiliyle girdiğinizde alert tekrarlanıyorsa Stored XSS söz konusudur. Etki yüzeyi Reflected'dan genelde daha yüksektir çünkü tek bir kurban linki gerekmez.<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Savunma gözlemi:</span> Impossible seviyeye alıp aynı payload'ı deneyin. Veri saklansa bile gösterilirken encode edilmelidir. "Saklarken temizle, gösterirken encode et" ikilisinden özellikle <span style="font-weight: bold;" class="mycode_b">gösterirken encode</span> vazgeçilmezdir; çünkü veri birden fazla bağlamda kullanılabilir.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">6) DOM-Based XSS</span></span><br />
DOM XSS'te sunucu cevabı "temiz" görünebilir; zafiyet tarayıcıdaki JavaScript'in <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>location</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>hash</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>document.referrer</code></div></div> gibi kaynaklardan okuduğu veriyi <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>innerHTML</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>document.write</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>eval</code></div></div> gibi güvenli olmayan sink'lere yazmasından doğar.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>// Tehlikeli kalıp (kavramsal)
var q = location.hash.substring(1);
document.getElementById('out').innerHTML = q;

// Daha güvenli: textContent kullanmak
document.getElementById('out').textContent = q;</code></div></div><br />
DVWA'da DOM XSS için ayrı sayfa/versiyon farklılıkları olabilir; Juice Shop challenge'larında da DOM XSS örnekleri bulunur. Kaynak (source) ve sink listeleri için OWASP DOM based XSS Prevention Cheat Sheet'e bakın.<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Kaynak örnekleri: location, document.URL, postMessage
# Sink örnekleri: innerHTML, outerHTML, eval, setTimeout(string)</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">7) Uygulamalı: Filtreyi Anlamak (Adım Adım)</span></span><br />
Low -&gt; Medium -&gt; High ilerleyin; her seviyede şu notları alın:<br />
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Not şablonu
Seviye: Medium
Denenen: &lt;script&gt;alert(1)&lt;/script&gt;
Sonuç: script kelimesi silindi / sayfa boş / encode edildi
Çıkarım: blacklist mi, encoding mi?</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># High seviyede sık görülen: gelişmiş filtre veya kısmi encoding
# Impossible: doğru kütüphane encoding + katı kurallar</code></div></div><br />
Burp Suite kullanıyorsanız Proxy ile isteği yakalayıp parametreyi Repeater'da değiştirerek sunucu cevabında girdinin nereye yazıldığını izleyin (yalnızca lab).<br />
<br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">8) Korunma: Geliştirici Kontrol Listesi</span></span><ul class="mycode_list"><li>Şablon motorunun otomatik escaping özelliğini kapatmayın (Django, Jinja2 autoescape, React JSX varsayılanı)<br />
</li>
<li><div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>dangerouslySetInnerHTML</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>|safe</code></div></div>, <div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>v-html</code></div></div> gibi kaçış kapılarını kod incelemesinde işaretleyin<br />
</li>
<li>Bağlama uygun encoding kullanın (HTML, attribute, JS, URL, CSS ayrıdır)<br />
</li>
<li>Zengin metin (WYSIWYG) gerekiyorsa sıkı HTML sanitizer (ör. DOMPurify) kullanın<br />
</li>
<li>CSP ekleyin; inline script'i azaltın<br />
</li>
<li>Çerezlerde HttpOnly; Secure; SameSite ayarlayın<br />
</li>
<li>WAF kara listesine güvenerek "XSS bitti" demeyin<br />
</li>
</ul>
<br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># Python / Jinja2 (otomatik escape açıkken)
{{ user_comment }}

# Bilerek ham HTML (kaçının veya sanitize edin)
{{ user_comment | safe }}</code></div></div><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code># PHP örneği (bağlama göre)
echo htmlspecialchars(&#36;name, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');</code></div></div><br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">9) İleri Seviye Notlar</span></span><br />
<span style="font-weight: bold;" class="mycode_b">Mutation XSS (mXSS):</span> Tarayıcının HTML parser'ının beklenmedik şekilde DOM'u "düzeltmesi" sonucu sanitizer'ların bypass edilmesi. Kendi sanitizer'ınızı yazmak yerine bakımı yapılan kütüphaneleri kullanın.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Blind XSS:</span> Payload'un admin panelinde, log görüntüleyicide veya destek aracında sonradan tetiklenmesi. BeAlert / XSS Hunter benzeri geri çağırma (callback) servisleri pentestlerde kullanılır; izinsiz sistemlerde asla.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Raporlama dili:</span><br />
<div class="codeblock"><div class="title">Kod:</div><div class="body" dir="ltr"><code>Bulgu: Stored XSS (CWE-79)
Konum: /guestbook message alanı
Etki: Oturum çerezi HttpOnly değilse hesap ele geçirme riski
Kanıt: Lab ortamında alert PoC + HTML kaynak çıktısı
Öneri: Çıktı encoding + CSP + HttpOnly</code></div></div><br />
[center][/center]<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">10) Sonuç</span></span><br />
XSS; Reflected, Stored ve DOM olarak üç ana ailede incelenir. Ortak kök neden, güvensiz bağlama yazımdır. DVWA Low'da zafiyeti görün, Impossible'da doğru kodu inceleyin, kendi uygulamanızda escaping + CSP + çerez bayraklarını kontrol edin.<br />
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Kaynakça</span></span><ul class="mycode_list"><li><a href="https://owasp.org/www-community/attacks/xss/" target="_blank" rel="noopener" class="mycode_url">OWASP XSS</a><br />
</li>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html" target="_blank" rel="noopener" class="mycode_url">OWASP XSS Prevention Cheat Sheet</a><br />
</li>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/DOM_based_XSS_Prevention_Cheat_Sheet.html" target="_blank" rel="noopener" class="mycode_url">OWASP DOM based XSS Prevention</a><br />
</li>
<li><a href="https://github.com/digininja/DVWA" target="_blank" rel="noopener" class="mycode_url">DVWA (GitHub)</a><br />
</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP" target="_blank" rel="noopener" class="mycode_url">MDN Content Security Policy</a><br />
</li>
<li><a href="https://cwe.mitre.org/data/definitions/79.html" target="_blank" rel="noopener" class="mycode_url">CWE-79</a><br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b"><span style="font-size: 4pt;" class="mycode_size">Yasal Uyarı</span></span><br />
Bu içerik eğitim ve savunma amaçlıdır. XSS testleri yalnızca <span style="font-weight: bold;" class="mycode_b">kendi labınızda</span> veya <span style="font-weight: bold;" class="mycode_b">yazılı yetki</span> verilen sistemlerde yapılmalıdır. İzinsiz testler TCK <span style="font-weight: bold;" class="mycode_b">243-245</span> kapsamında suç oluşturabilir. Sorumluluk uygulayana aittir.<br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://cdn.turkteam.org/images/attachtypes/image.png" title="PNG Image" border="0" alt=".png" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=126" target="_blank" title="">000-team-06-team-1e62fe.png</a> (Dosya Boyutu: 69.38 KB / İndirme Sayısı: 5)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
	</channel>
</rss>