Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 1

Taint Analizi: Kaynak ve Hedef Arasındaki Veri Akışı Takibi

Recommended resources

Merhaba, "İleri Seviye Güvenli Kod İnceleme" kursunun ilk dersine hoş geldiniz. Bu ilk modül, karmaşık kod tabanlarında güvenlik zafiyetlerini sistematik olarak tespit etmek için gereken ileri düzey metodolojileri oluşturmaya odaklanacak.

Bu derste, güvenli kod incelemesinin temel taşı olan bir kavramı ele alacağız: Taint Analysis (Kirlilik Analizi). Dersin sonunda, bir programdaki güvenilmeyen verinin yolculuğunu, başlangıç noktası olan kaynaktan (source) tehlikeli operasyonların gerçekleştirildiği hedefe (sink) nasıl ulaştığını takip etme mantığını tam olarak kavramış olacaksınız. Bu, sonraki derslerde ele alacağımız daha karmaşık veri akışı ve kontrol akışı analizi teknikleri için sağlam bir zemin oluşturacak.

Taint Analysis: Verinin Yolculuğunu İzlemek

Uygulama güvenliğinin temelinde yatan en önemli sorulardan biri şudur: "Kullanıcıdan veya dış sistemlerden gelen veri, uygulamanın neresinde, neye dönüşüyor ve nerede kullanılıyor?" Taint analysis, bu soruyu cevaplamak için kullandığımız en temel ve güçlü zihinsel modeldir. Bu model, güvenilmeyen bir kaynaktan gelen veriyi "kirli" (tainted) olarak etiketler ve bu kirliliğin program içinde nereye yayıldığını adım adım izler.

Bu görsel, taint analysis'in temel mantığını basit bir huni metaforuyla özetliyor: Geniş ağız, verinin sisteme girdiği sayısız kaynağı (source), daralan alt kısım ise bu verinin tehlikeli bir eyleme dönüştüğü kritik hedef noktalarını (sink) temsil eder.

Bu kavramları daha somut bir şekilde anlamak için LiveOverflow tarafından hazırlanan aşağıdaki kısa videoyu izleyerek başlayalım. Video, kaynak (source) ve hedef (sink) kavramlarını basit ve etkili bir PHP örneği üzerinden açıklıyor.

Sources and Sinks - Code Review Basics

"Sources and Sinks - Code Review Basics" başlıklı bu video, konunun temel mantığını kavramak için harika bir başlangıç noktasıdır.

Lütfen videonun ilk bölümünü izleyin. Bu bölümde, "source" ve "sink" kavramları tanımlanıyor ve kullanıcı girdisinin ($_POST) nasıl bir kaynak, komut çalıştıran exec fonksiyonunun ise nasıl bir hedef olduğu gösteriliyor.

Videoda da gördüğünüz gibi, temel bileşenler şunlardır:

  • Kaynak (Source): Uygulamanın kontrolü dışındaki bir yerden gelen verinin giriş noktasıdır. Bu, bir web uygulamasındaki GET/POST parametreleri, dosya yüklemeleri, veritabanından okunan kayıtlar, API'lerden gelen yanıtlar veya hatta bir Wi-Fi adı gibi beklenmedik girdiler olabilir. Kısacası, güvenmediğimiz her veri bir kaynaktır.
  • Hedef (Sink): Kirli verinin ulaştığında bir güvenlik zafiyetine yol açabileceği programdaki kritik bir işlev veya operasyondur. Örneğin, bir SQL sorgusu çalıştıran, bir işletim sistemi komutu yürüten (exec, system), bir dosyaya yazan veya HTML çıktısı üreten (innerHTML) fonksiyonlar tipik hedeflerdir.
  • Kirlilik (Taint): Bir kaynaktan gelen veriye atanan soyut bir özelliktir. Bu kirlilik, veri program içinde hareket ettikçe ve dönüştükçe diğer değişkenlere, nesnelere ve veri yapılarına "bulaşır".

Kirliliğin Yayılması (Taint Propagation)

Taint analysis'in en kritik yönü, kirliliğin nasıl yayıldığını anlamaktır. Kirlilik, sadece bir değişkenin diğerine atanmasıyla yayılmaz. Bir kirli veri parçası bir ifadenin içinde kullanıldığında, o ifadenin sonucu da kirli hale gelir.

Bu ayrım, özellikle sizin gibi deneyimli profesyoneller için, yüzeysel bir tarama ile derinlemesine bir analiz arasındaki farkı ortaya koyar. CodeQL dokümantasyonundaki kısa bir bölüm, bu konsepti "normal veri akışı" ile "taint tracking" arasındaki farkı vurgulayarak çok net bir şekilde açıklıyor.

About data flow analysis - CodeQL - GitHub

GitHub'ın statik analiz motoru CodeQL'in bu dokümanı, taint tracking'in geleneksel veri akışından nasıl daha fazlasını ifade ettiğini açıklıyor.

Lütfen "Normal data flow vs taint tracking" başlıklı bölümü okuyun. Özellikle y = x + 1 örneğine dikkat edin. Normal bir veri akışı analizi x'in kullanımını takip ederken, taint tracking x kirli olduğu için artık y'nin de kirli olduğunu anlar. Kirlilik, verinin tam değerini değil, "etkisini" takip eder.

Okuduğunuz metindeki gibi, x kirli ise y = x + 1 ifadesinden sonra y de kirli kabul edilir. Matematiksel altyapınızla bu duruma bir tür bağımlılık takibi olarak bakabilirsiniz: y'nin değeri, x'in değerine bağlıdır, dolayısıyla x'in taşıdığı "güvenilmezlik" özelliği y'ye de miras kalır.

Bu yayılmayı bir SQL enjeksiyonu senaryosu üzerinden görselleştirelim:

Bu akış şeması, bir Java uygulamasında `request.getParameter` (kaynak) ile alınan `studentId` verisinin, string birleştirme yoluyla `query` değişkenine nasıl bulaştığını ve `st.executeQuery` (hedef) fonksiyonunda bir SQL enjeksiyonu zafiyetine nasıl yol açtığını gösteriyor.

Şemadaki adımlar:

  1. Kaynak: request.getParameter("studId") çağrısı ile dış dünyadan alınan veri, studentId değişkenine atanır. Bu noktada studentId değişkeni kirlenir.
  2. Yayılma: studentId değişkeni, bir SQL sorgusu oluşturmak için string birleştirme (+) işleminde kullanılır. Bu işlem sonucunda, query değişkeninin tamamı artık kirli hale gelir. studentId'nin taşıdığı kirlilik, query değişkenine yayılmıştır.
  3. Hedef: Kirli query değişkeni, st.executeQuery(query) fonksiyonuna parametre olarak verilir. Veritabanı üzerinde sorgu çalıştıran bu fonksiyon, bizim için tehlikeli bir hedeftir. Kirli verinin bu hedefe ulaşmasıyla SQL enjeksiyonu zafiyeti tetiklenir.

Elbette, bu akışı kesintiye uğratan mekanizmalar da vardır. Temizleyiciler (Sanitizers), kirli veriyi güvenli hale getiren fonksiyonlardır. Parametreli sorgular kullanmak, gelen veriyi belirli bir formata göre doğrulamak (validation) veya çıktıyı doğru şekilde kodlamak (output encoding) gibi işlemler, kirliliği ortadan kaldıran temizleyicilerdir.


Kod İnceleme Stratejileri: İleri ve Geri Yönlü Analiz

Peki, bu zihinsel modeli gerçek bir kod incelemesinde nasıl uygularız? Genellikle iki ana strateji izlenir:

LiveOverflow videosunun ilgili bölümünü izleyerek bu iki stratejinin nasıl işlediğini görebilirsiniz.

Sources and Sinks - Code Review Basics

Aynı videonun bu bölümü, taint analysis'i pratik bir kod inceleme stratejisine nasıl dönüştüreceğimizi açıklıyor.

Lütfen bu bölümü izleyin. Burada, ileri yönlü (kaynaktan hedefe) ve geri yönlü (hedeften kaynağa) analiz yöntemleri karşılaştırılıyor.

Videoda anlatıldığı gibi stratejiler şunlardır:

  • İleri Yönlü Analiz (Forward Analysis): Bilinen bir veri giriş noktasından (kaynak) başlar ve verinin program içinde hangi yolları izlediğini takip ederek tehlikeli bir hedefe ulaşıp ulaşmadığını kontrol edersiniz. Az sayıda giriş noktası ama çok sayıda potansiyel hedef olduğunda etkili bir yöntemdir.
  • Geri Yönlü Analiz (Backward Analysis): eval, os.system veya bir ORM'deki "raw query" metodu gibi bilinen tehlikeli bir hedeften (sink) başlar ve bu hedefe gelen verinin kaynağını geriye doğru takip edersiniz. Hedef sayısı yönetilebilir olduğunda ve bu hedeflerin nerede olduğunu bildiğinizde oldukça verimlidir.

Modern SAST araçlarının (Semgrep, CodeQL vb.) temelinde de bu iki stratejinin otomatize edilmiş versiyonları yatar. Bu araçlar, önceden tanımlanmış kaynak ve hedef listeleriyle kodun soyut sözdizimi ağacı (AST) üzerinde bu akışları analiz ederler. Sizin SAST araçları yönetimi ve çıktılarını yorumlama konusundaki tecrübeniz, bu otomatize sürecin arkasındaki mantığı anlamanızı kolaylaştıracaktır.


Kavramın Teorik Temelleri (İleri Okuma)

Bu konunun teorik ve akademik yönüyle ilgileniyorsanız, taint analysis'in "points-to analysis" gibi daha temel statik analizlerle nasıl birleştirilebileceğini inceleyen araştırmalar mevcuttur. Bu, özellikle sizin matematik ve karmaşıklık teorisi ilgi alanlarınızla örtüşebilecek derin bir konudur.

[PDF] P/Taint: Unified Points-to and Taint Analysis - Yannis Smaragdakis

Bu akademik makale, taint analysis'i points-to analysis ile birleştiren bir yaklaşım sunmaktadır. Konunun teorik temellerine inmek için mükemmel bir kaynaktır.

Makalenin Bölüm 2 başlığı altındaki "Information-Flow Analysis Basics" alt bölümünü okuyarak kaynak, hedef ve temizleyici gibi kavramların daha resmi tanımlarını görebilirsiniz. Ardından, "Approach" alt bölümüne göz atarak, kirlilik kaynaklarının points-to analiz algoritmaları tarafından takip edilen "yapay soyut nesneler" olarak nasıl modellendiğine dair temel fikri edinebilirsiniz.

Bu okuma, taint analysis'in sadece bir "sezgi" veya tecrübeye dayalı bir yöntem olmadığını, aynı zamanda Datalog gibi mantıksal dillerle ifade edilebilen, sağlam ve titiz bir teorik temeli olduğunu gösterir.


Özet ve Sonraki Adımlar

Bu derste güvenli kod incelemesinin temel bir yapı taşı olan taint analysis kavramını inceledik. Anahtar çıkarımlarımız şunlar:

  • Taint Analysis, güvenilmeyen verinin program içindeki akışını izlemek için kullanılan sistematik bir yöntemdir.
  • Bu yöntem; verinin girdiği kaynakları, zarara yol açabileceği hedefleri belirlemeyi ve bu ikisi arasında kirliliğin yayılmasını takip etmeyi içerir.
  • Kirliliğin yayılması, verinin tam değerinden ziyade, "etkisinin" veya "kökeninin" takibidir.
  • Kod incelemesi sırasında ileri yönlü (source-to-sink) veya geri yönlü (sink-to-source) analiz stratejileri kullanılabilir.
  • Temizleyiciler (Sanitizers), bu akışı güvenli bir şekilde kesintiye uğratan ve zafiyetleri önleyen kritik kontrol noktalarıdır.

Bu temel kavramlar artık zihninizde yer ettiğine göre, bir sonraki dersimizde bu bilgiyi pratiğe dökeceğiz. "Ne" sorusundan "nasıl" sorusuna geçerek, veri akış analizi (data flow analysis) tekniklerini kullanarak kirliliğin fonksiyon çağrıları, nesne özellikleri ve dillerin diğer karmaşık yapıları arasında nasıl takip edileceğini somut örneklerle ele alacağız.