comez.dev
tr
~/article/sql-injection-genis-kapsamli-anlatimTüm yazılar

makale7 dk okuma0 görüntülenme

Sql injection Geniş kapsamlı anlatım

Kapsamlı SQL Injection Kılavuzu: Anatomi, Türler, Zafiyet Analizi ve Korunma Yöntemleri Web uygulamalarının ve veri tabanı sistemlerinin gelişimiyle birlikte veri güvenliği, dijit…

Bu sayfada (17)
  1. Kapsamlı SQL Injection Kılavuzu: Anatomi, Türler, Zafiyet Analizi ve Korunma Yöntemleri
  2. 1. SQL Injection Nedir?
  3. 2. Teknik Temel: Dinamik SQL ve Bind Variable İlişkisi
  4. Veri Tabanı Yapısının Oluşturulması (Oracle SQL)
  5. Örnek Verilerin Eklenmesi
  6. 3. PL/SQL Üzerinde SQL Injection Senaryosu
  7. Normal ve Meşru Kullanım
  8. İstismar Senaryosu 1: Tüm Verileri İfşa Etme
  9. İstismar Senaryosu 2: UNION Tabanlı Bilgi Toplama
  10. 4. Web Uygulamalarında SQL Injection Anatomisi
  11. Ne Kadar Sıklıkta Görülür?
  12. Tehdit Altındaki Hedef Sistemler
  13. 5. Kimlik Doğrulama Atlama (Authentication Bypass)
  14. Zafiyetli Arka Plan Kod Mantığı (Örnek: Classic ASP / JScript)
  15. Saldırının Gerçekleştirilmesi
  16. 6. Nümerik Alanlarda SQL Injection Tehdidi
  17. Zafiyetli PHP / MySQL Yapısı

Kapsamlı SQL Injection Kılavuzu: Anatomi, Türler, Zafiyet Analizi ve Korunma Yöntemleri

Web uygulamalarının ve veri tabanı sistemlerinin gelişimiyle birlikte veri güvenliği, dijital dünyanın en kritik unsurlarından biri haline gelmiştir. Bilgilerin statik HTML sayfalarından dinamik dillere (PHP, ASP.NET, Java, Python vb.) ve ilişkisel veri tabanlarına (MySQL, MS SQL Server, Oracle, PostgreSQL vb.) taşınması, performansı ve ölçeklenebilirliği artırırken beraberinde ciddi bir güvenlik riskini de getirmiştir: Uygulama Güvenliği Eksikliği.

Bu kılavuzda, web uygulamalarını tehdit eden en yaygın ve en tehlikeli zafiyetlerden biri olan SQL Injection (SQLi) konusunu tüm detayları, kod örnekleri, mantıksal analizleri ve korunma yöntemleri ile ele alacağız.

1. SQL Injection Nedir?

SQL Injection (SQL Enjeksiyonu), bir web uygulamasının kullanıcıdan aldığı girdileri (input) yeterince doğrulamadan veya filtrelemeden doğrudan SQL sorgularının içerisine dahil etmesi sonucu ortaya çıkan bir güvenlik zafiyetidir.

Kelime anlamından da anlaşılacağı üzere, saldırganın uygulama arayüzünü kullanarak veri tabanı motoruna dışarıdan zararlı SQL komutları "enjekte etmesi" durumudur. Programcının iyi niyetle yazdığı masum bir sorgu, saldırganın müdahalesiyle tamamen farklı bir amaca hizmet edebilir. Bu durum veri sızıntılarına, veri tabanının silinmesine, yetkisiz erişimlere ve hatta hedef sunucunun tamamen ele geçirilmesine yol açabilir.

2. Teknik Temel: Dinamik SQL ve Bind Variable İlişkisi

SQL Injection zafiyetinin temel varoluş sebebi, uygulama katmanında Dinamik SQL (Dynamic SQL) kullanılmasıdır. Yani SQL sorgusunun, dışarıdan gelecek parametrelere göre çalışma zamanında (runtime) bir string birleştirme (concatenation) işlemiyle oluşturulmasıdır.

Önemli Not: "Bind Variable" (Parametrik Sorgu) kullanmanın tek avantajı performans artışı değildir. Veri tabanı güvenliğinin (Database Security) sağlanmasındaki en güçlü kalkan bind variable kullanımıdır.

Zafiyetin çalışma mantığını anlamak için somut bir senaryo oluşturalım. Elimizde müşterilerin bilgilerini tutan customers adında bir tablo olsun.

Veri Tabanı Yapısının Oluşturulması (Oracle SQL)

SQL
CREATE TABLE customers (
    customer_forname VARCHAR2(30),
    customer_surname VARCHAR2(30),
    customer_phone   VARCHAR2(30),
    customer_fax     VARCHAR2(30),
    customer_type    NUMBER(10)
);

Örnek Verilerin Eklenmesi

SQL
BEGIN
    INSERT INTO customers VALUES ('Ali', 'Yilmaz', '999444888', '999444889', 3);
    INSERT INTO customers VALUES ('Ahmet', 'Celik', '999555888', '999555889', 2);
    INSERT INTO customers VALUES ('Veli', 'Gocer', '999777888', '999777889', 1);
    COMMIT;
END;
/

3. PL/SQL Üzerinde SQL Injection Senaryosu

Müşterinin soyadını parametre olarak alıp, ona ait telefon numarasını ekrana yazdıran hatalı (zafiyet barındıran) bir PL/SQL prosedürünü inceleyelim:

SQL
CREATE OR REPLACE PROCEDURE getCustPhone(p_surname IN VARCHAR2) IS
    TYPE refCursor IS REF CURSOR;
    rc refCursor;
    thePhone customers.customer_phone%TYPE;
    -- SQL stringi dinamik olarak birleştiriliyor (Zafiyet Noktası!)
    stmt VARCHAR2(32767) := 'SELECT customer_phone FROM customers WHERE customer_surname = ''' || p_surname || '''';
BEGIN
    DBMS_OUTPUT.PUT_LINE('Çalıştırılan SQL Metni: ' || stmt);
    
    OPEN rc FOR stmt;
    LOOP
        FETCH rc INTO thePhone;
        EXIT WHEN rc%NOTFOUND; -- Orijinal koddaki imleç hatası rc%notfound olarak düzeltilmiştir.
        DBMS_OUTPUT.PUT_LINE('Müşteri Telefonu: ' || thePhone);
    END LOOP;
    CLOSE rc;
END getCustPhone;
/

Normal ve Meşru Kullanım

Prosedüre beklenen kurallara uygun bir soyadı (Yilmaz) gönderildiğinde sistem hatasız çalışır:

SQL
BEGIN
    getCustPhone('Yilmaz');
END;
/

Çıktı:

Plaintext
Çalıştırılan SQL Metni: SELECT customer_phone FROM customers WHERE customer_surname = 'Yilmaz'
Müşteri Telefonu: 999444888

İstismar Senaryosu 1: Tüm Verileri İfşa Etme

Bir saldırgan, tek bir müşterinin telefonu yerine tüm müşterilerin numaralarını çekmek isterse, parametreyi SQL mantığını bozacak şekilde manipüle edebilir.

Gönderilen zararlı parametre: Yilmaz' OR EXISTS (SELECT 1 FROM sys.dual) AND 'x' = 'x

SQL
DECLARE
    cust VARCHAR2(200) := 'Yilmaz'' OR EXISTS (SELECT 1 FROM sys.dual) AND ''x'' = ''x';
BEGIN
    getCustPhone(cust);
END;
/

Çıktı:

Plaintext
Çalıştırılan SQL Metni: SELECT customer_phone FROM customers WHERE customer_surname = 'Yilmaz' OR EXISTS (SELECT 1 FROM sys.dual) AND 'x' = 'x'
Müşteri Telefonu: 999444888
Müşteri Telefonu: 999555888
Müşteri Telefonu: 999777888

Analiz: Saldırgan, girdi alanına tek tırnak (') koyarak programcının açtığı string ifadesini erken kapattı. Ardından OR mantıksal operatörünü ekleyerek her zaman doğru (TRUE) dönecek bir koşul enjekte etti. En sondaki 'x'='x' ifadesi ise sorgunun sağ tarafında açıkta kalan orijinal tek tırnağı kapatmak ve sentaks hatası (Syntax Error) almamak için eklenmiştir.

İstismar Senaryosu 2: UNION Tabanlı Bilgi Toplama

Saldırgan, veri tabanına bağlantı sağlayan mevcut aktif kullanıcıyı öğrenmek için UNION operatörünü kullanabilir.

Gönderilen zararlı parametre: Yilmaz' UNION SELECT sys.login_user FROM sys.dual WHERE 'x'='x

SQL
DECLARE
    cust VARCHAR2(200) := 'Yilmaz'' UNION SELECT sys.login_user FROM sys.dual WHERE ''x''=''x';
BEGIN
    getCustPhone(cust);
END;
/

Çıktı:

Plaintext
Çalıştırılan SQL Metni: SELECT customer_phone FROM customers WHERE customer_surname = 'Yilmaz' UNION SELECT sys.login_user FROM sys.dual WHERE 'x'='x'
Müşteri Telefonu: 999444888
Müşteri Telefonu: CUSTINFOUSER

Bu yöntemle saldırgan veri tabanı şemasını, tablo isimlerini, diğer veri tabanlarına giden DB Link (Database Link) bilgilerini ve hassas sistem verilerini tamamen dışarı sızdırabilir.

4. Web Uygulamalarında SQL Injection Anatomisi

Web uygulamaları kullanıcılar ile sürekli etkileşim halindedir. Girdiler form alanlarından, URL sorgu dizilerinden (QueryString), çerezlerden (Cookies) veya HTTP Header bilgilerinden gelebilir.

Zafiyetin web üzerindeki etkileri, veri tabanı yönetim sisteminin (DBMS) yeteneklerine ve uygulamanın çalıştığı işletim sistemi izinlerine bağlı olarak şu felaketlere yol açabilir:

  • Kimlik doğrulama mekanizmalarını şifresiz geçmek (Auth Bypass).

  • Veri tabanındaki tüm tabloları okumak, değiştirmek veya silmek (DROP, DELETE, UPDATE).

  • Veri tabanı sunucusu üzerinde işletim sistemi komutları çalıştırmak (Örn: MS SQL Server'da xp_cmdshell).

  • Yerel ağdaki diğer sunuculara sızmak için bir sıçrama tahtası olarak kullanılması.

Ne Kadar Sıklıkta Görülür?

  • Dinamik web siteleri ve API'ler için tarihten bugüne en sık rastlanan kritik güvenlik açıklarının başında gelir (OWASP Top 10 listesinin her dönem üst sıralarındadır).

  • Veri tabanı veya web sunucusunun bir hatası değil, tamamen yazılımcının kodlama hatasıdır.

  • Pek çok geliştirici, modern framework'lerin arkasındaki ham SQL yapılarını kontrol etmediği için bu risk halen güncelliğini korumaktadır.

Tehdit Altındaki Hedef Sistemler

Herhangi bir dil veya veri tabanı ayrımı yoktur. SQL standartlarını kullanan tüm yapılar bu tehditle karşı karşıyadır:

  • Veri Tabanları: MS SQL Server, Oracle, MySQL, PostgreSQL, MariaDB, MS Access, DB2, Sybase, Informix vb.

  • Diller ve Teknolojiler: PHP, ASP, ASP.NET, JSP/Java, Python, Node.js, Perl, CGI, XML/XSL, Javascript (Node/NoSQL enjeksiyonları dahil), ODBC/ADO.NET tabanlı API'ler.

5. Kimlik Doğrulama Atlama (Authentication Bypass)

En sık rastlanan SQL Injection türlerinden biri, kullanıcı giriş formlarını herhangi bir şifre bilmeden aşmaktır.

Zafiyetli Arka Plan Kod Mantığı (Örnek: Classic ASP / JScript)

Giriş formundan gelen kullanıcı adı (formusr) ve şifre (formpwd) değişkenlerinin SQL içerisine doğrudan eklendiğini varsayalım:

JavaScript
var query = "SELECT * FROM users WHERE login = '" + formusr + "' AND password = '" + formpwd + "'";

Saldırının Gerçekleştirilmesi

Saldırgan kullanıcı adı alanına aşağıdaki ifadeyi girer:

  • Kullanıcı Adı: admin' OR 1=1 --

  • Şifre: (Rastgele herhangi bir şey)

Oluşan nihai SQL sorgusu şu şekle dönüşür:

SQL
SELECT * FROM users WHERE login = 'admin' OR 1=1 --' AND password = 'xyz'

Analiz: Birçok veri tabanında (MS SQL, PostgreSQL, Oracle) -- karakteri o satırın geri kalanını yorum satırı (comment) haline getirir ve veri tabanı motoru tarafından işlenmesini engeller. Böylece AND password = ... kontrolü tamamen devre dışı kalır. Sorgu WHERE login = 'admin' OR 1=1 haline geldiği için, 1=1 koşulu her zaman doğru kabul edilir ve saldırgan şifre doğrulaması yapılmadan admin kullanıcısı olarak sisteme giriş yapar.

6. Nümerik Alanlarda SQL Injection Tehdidi

Geliştiricilerin düştüğü en büyük yanılgılardan biri, sadece string (metinsel) alanlarda tek tırnak kullanımıyla SQL Injection oluşabileceğini sanmalarıdır. Veri tabanında veri tipi NUMBER, INT veya BIGINT olan alanlarda tek tırnak işareti kullanılmadığı için zafiyet çok daha doğrudan tetiklenir.

Zafiyetli PHP / MySQL Yapısı

Veri tabanı şeması:

SQL
CREATE TABLE IF NOT EXISTS `accounts` (
  `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
  `account` BIGINT(20) NOT NULL DEFAULT '0',
  `pin` BIGINT(20) NOT NULL DEFAULT '0',
  `user_name` VARCHAR(128) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM;

INSERT INTO `accounts` VALUES (1, 123, 123, 'ULKER');
INSERT 

Genel

güncellendi
Yorumlar14
  • Talha K.

    Gene döktürmüşsün hocam bayada uzun olmuş 7-8 dakikada zor bitirdim

    yanıt
  • HastaneBul

    Sql Injection’dan korunmanın en sabit yöntemi, sorgularınızı direk değildide veritabanına parametre olarak göndermek.

    yanıt
    • [email protected]yazar

      Sorguları laaaap diyo gönderirsen birileri de sana laaaap diye iteler dimi hacı

      yanıt
  • WebTasarimci

    PDO prepared statements kullanmayan kaldı mı ya bu devirde hala düz query yazıp sitede açık bırakan varsa hacklenmeyi hakediyordur zaten.

    yanıt
    • [email protected]yazar

      Hacı sen öyle diyorsun da piyasada hala kaç yıllık scriptleri kullanan eski siteler var adam farkında bile değil açık olduğunun 😄

      yanıt
  • caner_34

    Eline sağlık ali abi, güvenlik makalelerin çok faydalı oluyor. Sırada XSS koruması gelse çok iyi olur.

    yanıt
    • [email protected]yazar

      Eyvallah Caner, xss listemde var bir ara çay sigara eşliğinde onu da patlatırım blogda pamp 😄

      yanıt
  • Güvenlikçi_Mert

    Yalnız yazıda addslashes fonksiyonundan bahsetmişsin ama o tam çözüm değil, mysql_real_escape_string veya direkt PDO kullanmak şart.

    yanıt
    • [email protected]yazar

      Aynen hacım haklısın, addslashes eski usul kalıyor biraz ama mantığı anlaşılsın diye araya sıkıştırdım tek başına kurtarmaz zaten.

      yanıt
  • Burak

    Yazıyı yer imlerine ekledim, baştan sona tam bir başvuru kaynağı olmuş. Teşekkürler ali abi.

    yanıt
  • SiberSavaşçı

    Hocam dork taraması yapıp sql açığı bulan botlar var ya, bu aralar benim siteye çok dadandılar. Yazıdaki koruma adımları işe yarar mı?

    yanıt
    • [email protected]yazar

      İşe yarar moruk, kod tarafını sağlama alırsan botlar istedikleri kadar tarasın hata alıp dönerler anca sjsjsj 😄

      yanıt

Yorum yaz

İlgili

Benzer bir iş üzerinde mi çalışıyorsunuz?
Mimariyi incelemekten teslimata kadar yardımcı olmaktan memnuniyet duyarım.

iletişim