Web Application Layout
Web uygulamaları her zaman aynı yapıda değildir. Her şirket ya da ekip, uygulamasını farklı bir amaç, farklı bir kullanıcı kitlesi ve farklı teknik ihtiyaçlar için geliştirir. Bu yüzden kullanılan tasarım, kodlama yaklaşımı, back-end altyapısı ve güvenlik modeli projeden projeye değişebilir.
Pentest sırasında önemli olan sadece uygulamanın görünüşü değildir. Asıl anlaşılması gereken şey şudur: Uygulama nasıl çalışıyor, hangi bileşenlerden oluşuyor ve bu bileşenler arka planda birbirleriyle nasıl iletişim kuruyor?
Web application layout genel olarak üç ana başlık altında incelenebilir:
Web Application Infrastructure
Web Application Components
Web Application Architecture
Web Application Infrastructure
Infrastructure, uygulamanın çalışması için gereken temel altyapıdır. Örneğin veritabanının nerede bulunduğu, web sunucusunun hangi sunucuya eriştiği veya sistemin tek sunucuda mı yoksa birden fazla sunucuda mı çalıştığı bu başlık altında değerlendirilir.
En temel model Client-Server Model’dir. Bu modelde kullanıcı tarafı yani client, genellikle bir tarayıcıdır. Tarayıcı HTTP request gönderir, server bu isteği işler ve response döner. Front-end tarafında HTML, CSS ve JavaScript çalışırken; back-end tarafında authentication, business logic ve database işlemleri yürütülür.
Daha basit yapılarda tüm sistem tek sunucuda çalışabilir. Buna One Server Model denir. Web uygulaması, veritabanı ve diğer servisler aynı sunucudadır. Kurulumu kolaydır fakat güvenlik açısından risklidir. Çünkü tek bir bileşende oluşan problem tüm sistemi etkileyebilir. Bu durum genellikle “all eggs in one basket” mantığıyla açıklanır.
Daha gelişmiş yapılarda birden fazla web server tek bir veritabanına bağlanabilir. Buna Many Servers - One Database modeli denir. Bu yapı segmentasyon açısından daha güvenlidir. Bir web server ele geçirilse bile diğer sunucular doğrudan etkilenmeyebilir. Ancak segmentasyon tek başına yeterli değildir; doğru access control mutlaka uygulanmalıdır.
En güvenli ve ölçeklenebilir yapılardan biri ise Many Servers - Many Databases modelidir. Bu modelde her uygulama veya servis kendi veritabanına sahip olabilir. Böylece hem izolasyon artar hem de redundancy sağlanır. Ancak bu yapının kurulumu ve yönetimi daha zordur. Load balancer, backup sistemleri ve doğru erişim kontrolleri gerekir.
Günümüzde bu klasik modellere ek olarak serverless architecture ve microservices architecture da sıkça kullanılmaktadır.
Web Application Components
Bir web uygulaması farklı parçalardan oluşur. Bunlar genel olarak client, server, web server, application logic, database, microservices, third-party integrations, serverless functions ve diğer entegrasyonlar olabilir.
Client tarafı, kullanıcının tarayıcıda gördüğü ve etkileşime girdiği bölümdür. Server tarafı ise uygulamanın ana iş mantığını çalıştırır. Web server gelen HTTP request’leri yönetir. Database veriyi saklar. Third-party servisler ise ödeme sistemi, harita servisi, e-posta sağlayıcısı veya authentication servisi gibi dış sistemler olabilir.
Web Application Architecture
Web application architecture, uygulamadaki bileşenlerin birbirleriyle nasıl ilişki kurduğunu açıklar. Temel soru şudur: “Kim, kime, nasıl bağlanıyor?”
Klasik web mimarisi genellikle üç katmanlıdır:
Presentation Layer
Application Layer
Data Layer
Presentation layer, kullanıcının gördüğü arayüzdür. HTML, CSS ve JavaScript bu katmanda yer alır.
Application layer, isteklerin işlendiği bölümdür. Authorization, privilege kontrolü, business logic ve verinin filtrelenmesi burada yapılır.
Data layer ise verinin tutulduğu katmandır. Veritabanları bu katmanda bulunur ve application layer ile birlikte çalışır.
Microservices
Microservice, tek bir göreve odaklanan bağımsız servis anlamına gelir. Örneğin bir online mağazada registration, search, payment, rating ve review gibi işlemler ayrı microservice’ler olarak tasarlanabilir.
Microservices yapısında servisler genellikle birbirinden bağımsızdır. Her servis kendi görevini yapar ve diğer servislerle API üzerinden iletişim kurar. Bu yapı stateless communication mantığına dayanabilir. Servisler farklı programlama dilleriyle geliştirilebilir.
Microservices mimarisinin avantajları şunlardır:
Daha esnek ölçeklendirme
Daha kolay deployment
Daha yüksek dayanıklılık
Tekrar kullanılabilir kod
Daha hızlı geliştirme süreci
Serverless
Serverless mimaride geliştirici doğrudan sunucu yönetimiyle uğraşmaz. AWS, Google Cloud veya Azure gibi cloud provider’lar altyapı yönetimini üstlenir. Uygulama genellikle stateless container veya function mantığıyla çalışır.
Bu yapının en büyük avantajı, geliştiricinin provisioning, scaling ve maintenance gibi işlerle daha az uğraşmasıdır.
Architecture Security
Güvenlik açıkları her zaman kod hatasından kaynaklanmaz. Bazen sorun doğrudan mimaridedir.
Örneğin RBAC yani Role-Based Access Control eksikse, uygulama teknik olarak düzgün yazılmış olsa bile normal bir kullanıcı admin sayfalarına erişebilir veya başka kullanıcıların özel verilerini görebilir. Bu tür problemler sadece küçük bir kod düzeltmesiyle çözülmez; çoğu zaman tasarım değişikliği gerekir. Bu da hem maliyetli hem de zaman alıcıdır.
Pentest sırasında back-end ele geçirilmiş ama veritabanı bulunamamış olabilir. Bu durumda veritabanı ayrı bir sunucuda olabilir. Eğer sadece kısmi veri bulunuyorsa, sistemde birden fazla veritabanı kullanılıyor olabilir.
Bu yüzden güvenlik, yazılım geliştirme yaşam döngüsünün en başından itibaren düşünülmelidir. Pentest de sadece proje sonunda değil, development lifecycle boyunca yapılmalıdır.
Full Stack
Full stack, front-end ve back-end geliştirmeyi birlikte kapsayan bir kavramdır. Front-end kullanıcı tarafında çalışır, back-end ise sunucu tarafında çalışır. İkisi farklı yerlerde çalıştığı için güvenlik riskleri de farklıdır.
Front End
Front-end, kullanıcının tarayıcıda gördüğü kısımdır. HTML, CSS ve JavaScript front-end’in temel yapı taşlarıdır.
HTML sayfanın iskeletini oluşturur. Başlıklar, paragraflar, formlar ve görseller HTML ile tanımlanır.
CSS sayfanın görünümünü belirler. Renkler, fontlar, hizalama, boşluklar, animasyonlar ve responsive tasarım CSS ile yapılır.
JavaScript ise sayfaya işlevsellik katar. Buton tıklamaları, form kontrolleri, dinamik içerik değişiklikleri ve back-end ile iletişim JavaScript ile sağlanabilir.
Modern front-end sadece güzel görünmek zorunda değildir. Aynı zamanda farklı cihazlarda, farklı ekran boyutlarında ve farklı tarayıcılarda düzgün çalışmalıdır. Eğer front-end optimize edilmezse kullanıcı uygulamayı yavaş hissedebilir. Bazen sorun sunucuda değil, client-side tarafta olabilir.
Front-end geliştirme aynı zamanda UI design, UX design ve visual concept gibi alanları da içerir.
Back End
Back-end, web uygulamasının ana motorudur. Authentication, authorization, database işlemleri, API’ler, business logic ve servis entegrasyonları back-end tarafında çalışır.
Back-end’in temel bileşenleri şunlardır:
Back-end servers
Web servers
Databases
Development frameworks
Web server örnekleri Apache, NGINX ve IIS olabilir. Database tarafında MySQL, MSSQL, Oracle, PostgreSQL, MongoDB ve NoSQL sistemleri kullanılabilir.
Back-end geliştirme framework’lerine Laravel, ASP.NET, Spring, Django ve Express örnek verilebilir.
Back-end bileşenleri güvenlik için ayrı ayrı izole edilebilir. Örneğin database ayrı container’da, web application ayrı container’da çalışabilir. Bu yaklaşım segmentasyon sağlar ve bir zafiyetin diğer bileşenlere yayılmasını zorlaştırır.
Front-End ve Back-End Güvenliği
“Back-end kodunu göremiyoruz, o zaman güvenlidir” düşüncesi yanlıştır. Back-end kodu kullanıcıya görünmese bile injection saldırılarıyla exploit edilebilir.
Örneğin hatalı çalışan bir search fonksiyonu SQL Injection’a neden olabilir. Bu durumda saldırgan veritabanından yetkisiz veri çekebilir. Benzer şekilde Command Injection ile işletim sistemi komutları çalıştırılabilir.
Whitebox ve Blackbox Pentest
Whitebox pentestte kaynak kod erişimi vardır. Bu sayede code review yapılabilir. Front-end tarafında kod genellikle tarayıcıya geldiği için incelemek daha kolaydır.
Blackbox pentestte kaynak kod erişimi yoktur. Bu, özellikle back-end için daha yaygın bir senaryodur çünkü back-end kodu sunucuda çalışır ve kullanıcıya gönderilmez.
Ancak open-source projelerde kaynak kod erişilebilir olabilir. Ayrıca LFI gibi zafiyetlerle source code elde edilebilir. Kaynak kod ele geçirilirse hassas bilgiler, hard-coded password’ler veya normal testlerde fark edilmesi zor açıklar bulunabilir.
Yaygın Developer Hataları
Developer kaynaklı hatalar birçok güvenlik açığının temelini oluşturur. En yaygın hatalardan bazıları şunlardır:
Geçersiz veriyi database’e kabul etmek
Güvenliği projenin en sonuna bırakmak
Password’leri plain text saklamak
Zayıf password politikaları kullanmak
Hassas veriyi şifrelemeden saklamak
Client-side kontrollere fazla güvenmek
URL path üzerinden kontrolsüz variable almak
Third-party code’a tamamen güvenmek
Hard-coded backdoor hesaplar bırakmak
WAF’i yanlış yapılandırmak
Bu hataların çoğu OWASP Top 10 kategorileriyle doğrudan ilişkilidir.
OWASP Top 10
OWASP Top 10, web uygulamalarında en kritik güvenlik risklerini listeler. Bunlar arasında şunlar bulunur:
Broken Access Control
Cryptographic Failures
Injection
Insecure Design
Security Misconfiguration
Vulnerable and Outdated Components
Identification and Authentication Failures
Software and Data Integrity Failures
Security Logging and Monitoring Failures
SSRF
HTML
HTML, web sayfalarının temel yapısını oluşturan markup dilidir. Başlıklar, paragraflar, formlar, görseller ve diğer sayfa elementleri HTML ile tanımlanır. Tarayıcı bu elementleri yorumlar ve kullanıcıya görsel olarak sunar.
Basit bir HTML sayfası şu şekildedir:
<!DOCTYPE html> <html> <head> <title>Page Title</title> </head> <body> <h1>A Heading</h1> <p>A Paragraph</p> </body> </html>
HTML elementleri ağaç yapısı şeklinde çalışır. Ana <html> etiketi tüm sayfayı kapsar. <head> genellikle sayfa başlığı, metadata, CSS veya script bağlantılarını içerir. <body> ise kullanıcının gördüğü içerikleri barındırır.
HTML’de her element genellikle bir açılış ve kapanış etiketiyle yazılır. Örneğin paragraf için <p>...</p> kullanılır. Elementlere id veya class verilebilir. Bu bilgiler CSS ve JavaScript ile ilgili elementi seçmek için kullanılır.
DOM
DOM, yani Document Object Model, HTML sayfasının tarayıcı tarafından nesne modeli olarak temsil edilmesidir. JavaScript sayesinde DOM üzerindeki elementlere erişilebilir, içerikleri değiştirilebilir veya yeni elementler oluşturulabilir.
DOM yapısını anlamak özellikle güvenlik testlerinde önemlidir. Çünkü sayfadaki elementleri incelemek, manipüle etmek veya XSS gibi front-end zafiyetlerini analiz etmek için DOM bilgisi gerekir.
URL Encoding
URL’lerde bazı karakterler doğrudan kullanılamaz. Bu karakterler percent-encoding yöntemiyle encode edilir. Örneğin tek tırnak karakteri ', URL içinde %27 olarak gösterilir. Boşluk karakteri ise genellikle %20 veya + ile temsil edilir.
Bu konu özellikle web güvenliği açısından önemlidir çünkü input manipulation, XSS, SQL Injection ve request analizlerinde encoding/decoding sıkça kullanılır. Burp Suite gibi araçlar encoding işlemleri için pratik çözümler sunar.
CSS
CSS, HTML elementlerinin nasıl görüneceğini belirleyen stil dilidir. Renkler, fontlar, hizalama, boşluklar, animasyonlar ve responsive tasarım CSS ile yapılır.
Örnek:
body { background-color: black; } h1 { color: white; text-align: center; } p { font-family: Helvetica; font-size: 10px; }
CSS syntax temel olarak şu yapıdadır:
selector { property: value; }
CSS sadece basit stiller için değil, animasyonlar ve gelişmiş görsel efektler için de kullanılabilir. @keyframes, animation, transition gibi özelliklerle dinamik arayüzler oluşturulabilir.
CSS geliştirmeyi kolaylaştırmak için birçok framework kullanılır. Bootstrap, SASS, Foundation, Bulma ve Pure bunlara örnektir.
JavaScript
JavaScript, web sayfalarına etkileşim ve dinamiklik kazandıran programlama dilidir. HTML sayfanın yapısını, CSS görünümünü belirlerken; JavaScript sayfanın davranışını kontrol eder.
JavaScript kodu HTML içinde <script> etiketiyle yazılabilir veya ayrı bir dosyadan çağrılabilir:
<script src="./script.js"></script>
Basit bir örnek:
document.getElementById("button1").innerHTML = "Changed Text!";
Bu kod, button1 id’sine sahip elementin içeriğini değiştirir.
Modern web uygulamaları JavaScript’e yoğun şekilde bağımlıdır. Sayfanın gerçek zamanlı güncellenmesi, kullanıcı girdilerinin işlenmesi, Ajax istekleriyle back-end’e veri gönderilip alınması JavaScript ile yapılabilir.
Popüler JavaScript framework’leri arasında Angular, React, Vue ve jQuery bulunur.
Sensitive Data Exposure
Front-end bileşenleri client-side çalıştığı için kullanıcı tarafından görüntülenebilir. Bu nedenle hassas bilgilerin HTML kaynak kodunda, JavaScript dosyalarında veya client-side yorum satırlarında bırakılması ciddi bir güvenlik problemidir.
Sensitive Data Exposure, hassas verinin kullanıcıya açık şekilde sunulmasıdır. Örneğin API key, password, token, internal endpoint veya admin panel bilgileri page source içinde bulunuyorsa bu ciddi bir zafiyettir.
Front-end açıkları doğrudan sunucuyu ele geçirmeyebilir; ancak admin kullanıcılara karşı kullanıldığında yetkisiz erişim, hassas veri sızıntısı veya servis kesintisi gibi ciddi sonuçlara yol açabilir.
Bu yüzden pentest sırasında sadece back-end değil, front-end kaynak kodu, JavaScript dosyaları, DOM yapısı ve client-side kontroller de dikkatlice incelenmelidir.

Page Source İnceleme
Herhangi bir web sitesinin kaynak kodunu tarayıcı üzerinden görmek oldukça kolaydır. Sayfanın herhangi bir yerine sağ tıklayıp View Page Source seçeneğine tıklayarak page source açılabilir.
Bazı geliştiriciler web uygulamasında sağ tıklamayı kapatabilir. Ancak bu, kaynak kodun incelenmesini gerçekten engellemez. Çünkü kaynak kodu görüntülemek için farklı yollar vardır:
CTRL + U kısayolu kullanılabilir.
Tarayıcı adres çubuğunda view-source: kullanılabilir.
Burp Suite gibi bir web proxy aracı üzerinden response içeriği incelenebilir.
Örneğin Google’ın kaynak kodu şu şekilde açılabilir:
view-source:https://www.google.com/
Bu sayfada HTML kodları, JavaScript dosyaları, dış bağlantılar ve import edilen kaynaklar görülebilir.
Page Source İçinde Neler Bulunabilir?
Page source incelemesi, web uygulaması testlerinde yapılması gereken ilk kontrollerden biridir. Çünkü bazen kaynak kod içinde veya dışarıdan yüklenen JavaScript dosyalarında hassas bilgiler bulunabilir.
Örneğin:
Credential bilgileri
Hash değerleri
API key’ler
Gizli linkler
Test sayfaları
Dizin bilgileri
Kullanıcı bilgileri
Debug parametreleri
Hidden functionality
Bu tür bilgiler, uygulama içinde daha fazla erişim elde etmek veya altyapı hakkında fikir sahibi olmak için kullanılabilir. Bu nedenle page source incelemesi, pentest sürecinde “low-hanging fruit” aramak için oldukça değerlidir.
Buradaki amaç, karmaşık exploit aşamalarına geçmeden önce açıkta bırakılmış basit ama kritik bilgileri tespit etmektir.
Örnek Senaryo
İlk bakışta standart bir login formu normal görünebilir. Kullanıcı adı, şifre alanı ve login butonundan oluşan basit bir form düşünelim.
Ancak page source incelendiğinde şöyle bir kodla karşılaşılabilir:
<form action="action_page.php" method="post"> <div class="container"> <label for="uname"><b>Username</b></label> <input type="text" required> <label for="psw"><b>Password</b></label> <input type="password" required> <!-- TODO: remove test credentials test:test --> <button type="submit">Login</button> </div> </form>
Burada geliştiricinin kaldırmayı unuttuğu bir yorum satırı vardır:
<!-- TODO: remove test credentials test:test -->
Bu yorum satırı test kullanıcı bilgilerini içeriyor olabilir. Her ne kadar bu credential’ların hâlâ geçerli olduğu kesin olmasa da, pentest sırasında mutlaka denenmesi ve not edilmesi gereken bir bulgudur.
Gerçek sistemlerde kaynak kod içinde doğrudan kullanıcı adı ve şifre görmek çok yaygın değildir. Ancak test endpoint’leri, gizli dizinler, debug parametreleri veya unutulmuş fonksiyonlar daha sık karşımıza çıkabilir.
Neden Önemlidir?
Front-end kaynak kodu kullanıcı tarafına gönderildiği için aslında gizli değildir. Tarayıcıya gelen her HTML, CSS ve JavaScript dosyası kullanıcı tarafından incelenebilir.
Bu yüzden şu mantık yanlıştır:
“Bu bilgi sadece JavaScript içinde duruyor, kimse görmez.”
Client-side tarafta bulunan her bilgi potansiyel olarak görülebilir, kopyalanabilir ve analiz edilebilir. Bu bilgiler doğrudan sunucuyu ele geçirmese bile saldırgana keşif aşamasında ciddi avantaj sağlayabilir.
Örneğin kaynak koddan bulunan bir debug endpoint, admin panel yolu veya test API’si daha sonra back-end’e yönelik saldırılar için kullanılabilir.
Otomatik Analiz Araçları
Page source ve JavaScript dosyalarını manuel incelemek önemlidir. Ancak büyük uygulamalarda bu işlem zaman alabilir. Bu nedenle bazı otomatik araçlar kaynak kodu tarayarak potansiyel hassas bilgileri bulmaya yardımcı olur.
Bu araçlar genellikle şunları arar:
URL path’leri
API endpoint’leri
Token benzeri değerler
Credential pattern’leri
Yorum satırları
Gizli parametreler
Harici JavaScript dosyaları
Yine de otomatik araçlar tek başına yeterli değildir. Manuel analiz, özellikle bağlamı anlamak açısından hâlâ çok önemlidir.
Önleme Yöntemleri
İdeal olarak front-end kaynak kodu yalnızca uygulamanın çalışması için gerçekten gerekli olan kodları içermelidir. Kullanıcıya gönderilen HTML, CSS ve JavaScript içinde gereksiz veya hassas bilgi bırakılmamalıdır.
Kaynak kod içinde bulunmaması gereken şeylere örnek olarak şunlar verilebilir:
Test credential’ları
Gereksiz yorum satırları
Gizli linkler
Debug endpoint’leri
Kullanılmayan eski kodlar
API key veya token değerleri
Internal sistem bilgileri
Geliştirme sürecinde client-side kod mutlaka review edilmelidir. Production ortamına çıkmadan önce kaynak kod, hem manuel olarak hem de otomatik araçlarla taranmalıdır.
Ayrıca veri sınıflandırması yapılmalı ve hangi verilerin client-side tarafta gösterilebileceği net şekilde belirlenmelidir. Hassas bilgiler mümkün olduğunca server-side tarafta tutulmalı, front-end’e yalnızca gerekli ve güvenli veri gönderilmelidir.
JavaScript tarafında hassas veri sızıntısını azaltmak için bazı ekipler obfuscation veya JavaScript packing tekniklerini kullanabilir. Bu yöntemler kodun okunmasını zorlaştırır ve otomatik araçların bazı bilgileri tespit etmesini güçleştirebilir.
Ancak önemli nokta şudur: Obfuscation bir güvenlik kontrolü değildir. Sadece analizi zorlaştırır. Eğer hassas bilgi client-side’a gönderiliyorsa, yeterli zaman ve analizle yine bulunabilir.
Bu yüzden en doğru yaklaşım, hassas veriyi front-end kaynak koduna hiç koymamaktır.







