Basic authentication ile kullanıcı adı ve şifre temelli bir kimlik doğrulama işlemi yapılır. Kullanıcı adı ve şifre her istekte sunucuya gönderilir ve oturum yönetimi sunucu tarafında yapılır.
JWT, kullanıcı bilgilerini içeren bir JSON nesnesidir ve yapılan isteğe eklenir. Sunucu tarafında oturum yönetimi yapılmasını gerektirmez.
HttpOnly Cookie, web tarayıcıları ve sunucular arasında iletişimde kullanılan bir mekanizmadır. Bir HttpOnly Cookie, tarayıcı tarafından sadece HTTP veya HTTPS protokolü aracılığıyla sunucuya gönderilen isteklerle ilişkilendirilir ve JavaScript tarafından erişilemez.
HttpOnly Cookie’lerin kullanılması, güvenlik açısından önemlidir. Bu tür bir çerez, kötü niyetli saldırganların tarayıcı üzerinden çerezlere erişerek kullanıcı bilgilerini çalmasını veya değiştirmesini engellemek için kullanılır. JavaScript tabanlı saldırılar, çerezlere erişmeye çalışan kodların çalıştırılmasını önleyerek etkisiz hale getirilir.
HttpOnly özelliğine sahip bir çerez, tarayıcı tarafından otomatik olarak yönetilir ve sadece sunucu tarafından okunabilir. Bu, çerezin güvenliği artırır ve saldırganların çerezlere erişmesini zorlaştırır.
Özetle, HttpOnly Cookie’ler, tarayıcı tarafından sadece HTTP istekleriyle sunucuya gönderilen çerezlerdir ve JavaScript tarafından erişilemezler. Bu şekilde, kullanıcı bilgilerini korumaya yardımcı olurlar.
JWT
Json Web Token, bilginin taraflar arasında güvenli bir biçimde taşınmasının, az maliyetli ve ek bir bağımlılığa ihtiyaç duymayan bir yolunu belirtir. Bu bilgi dijital olarak imzalandığı için güvenilebilir ve doğrulanabilir. Ayrıca authorization bilgilerini de tutabilir ki bu sayede her bir istek için veritabanına gidilerek kullanıcının rolleri ve izinleri için onaylama yapılmasına gerek kalmaz.
JWT üç bölümden oluşur: header, payload ve signature.
Header, token tipini, imzalama algoritmasını barındıran bir Json nesnesidir. Base64url (byte veri text olarak görüntülenir) kodlanmıştır(encode). Decode görünümü ;
{
"alg": "HS256",
"typ": "JWT
}
Payload kısmı, kullanıcı ve kimlik doğrulama olayı (authentication) hakkında bilgileri tutan veri taleplerini (data claims) içeren bir Json nesnesidir.
Sub (Subject): Kullanıcının kimliğini tanımlar. Örneğin, kullanıcı adı veya bir kullanıcı ID’si olabilir.
Iss (Issuer): JWT’yi oluşturan tarafın (issuer) kimliğini belirtir.
Exp (Expiration Time): JWT’nin geçerlilik süresini belirtir.
Nbf (Not Before): JWT’nin kullanılmaya başlanabileceği tarihi belirtir.
Iat (Issued At): JWT’nin oluşturulma tarihini belirtir.
Base64url kodlanmıştır. Bu bilgi şifrelenmediği için, sadece encode edildiği için gizli değildir, görülebilir. Decode hali örneğin:
{
"sub": "91287346",
"name": "Kullanici Adi",
"iat": 751641011
}
Üçüncü bölüm signature (imza) kısmıdır. JWT’ler iletilirken değiştirilemez olmaları için imzalanırlar.
JWT oluşturulurken birinci ve ikinci kısım Base64url encode edilirler ve ‘.’ ile birleştirilirler. base64urlEncode(header)+”.”+base64urlEncode(payload).
Bu iki kısım birleşerek bir veri seti oluşur.
Bu veri seti, belirtilen algoritma (örneğin, HMACSHA256) ve gizli anahtar (secret key) kullanılarak doğrudan imzalanır. Burada iki aşamalı bir süreç işler.
İlk aşamada veri seti (birleşmiş kısım) SHA-256 algoritması ile hash’lenir.
özet = SHA-256(veriSeti)
Hash’leme bir değeri başka bir değere dönüştürür. Hash işlemi tek yönlüdür, hashlenmiş değer kullanılarak input değerine geri dönülemez. Aynı input kullanılarak yapılan hashleme işlemi her durumda aynı output’u verir.
İkinci aşama ise ilk aşamada elde edilen hashlenmiş değerin bir gizli anahtar kullanılarak şifrelenmesidir.
imza = HMACSHA256(özet(hash), secret).
İmza, JWT’nin signature kısmını oluşturur.
İlk üretilen iki kısım vardır. Onlara veri seti demiştik. Şimdi onların sonuna da bu bu JWT signature (imza) ‘.’ kullanılarak eklenir. Artık JWT oluşturulmuş olur. Kullanıcı bundan sonra yapacağı her istek için Http Authentication Header içinde JWT’yi de sunucuya gönderir.
Sunucu gelen JWT için validasyon yaparken öncelikle header ve payload kısımlarının encoded hallerini alır. Bunları yeniden SHA-256 ile hash’ler. Sonra sunucu tarafında tutulan gizli anahtar ile tekrar imzalama işlemi yapılır.
tekrarImza = HMACSHA256(özet(hash), secret)
Elde edilen tekrarImza, gelen JWT’nin içindeki imza ile karşılaştırılır. Eğer imzalar eşleşiyorsa ve token’ın expiration time değeri dolmadıysa yani yeterli ömrü varsa, JWT geçerli olarak kabul edilir.
Kullanıcı authentication bilgileri ile sisteme giriş yapmak ister. Eğer giriş yapılabilirse, kullanıcının detaylı bilgisini ve servislere erişim için kullanılacak izinlerini tutan bir jwt üretilir. Sunucu jwt’yi şifreleyip imzalayarak istemciye gönderir. istemci jwt’yi belirtilen expiration time kadar bir süre elde tutar. İstemci bütün yapacağı isteklerin header kısmında bu jwt’yi de sunucuya gönderir.
Kullanıcı backend’e bir request gönderir.
JwtAuthenticationFilter içinde token doğrulaması yapılır.
Bir yazılımın performans, ölçeklenebilirlik ve tabii ki güvenlik gibi ana domain içinde yer almayan özellikleri uzun vadede yazılımın sürdürülebilirliğini ciddi anlamda etkileyebilir. Güvenlik açıkları olan bir uygulama istemeden de olsa bir DDOS saldırısının parçası olabilir ve şirketin diğer sistemlerinin çalışma performansını da etkileyebilir. Güvenlik ya da performans konusunda bir eksiklik olup olmadığını tespit etmek, business kodunun eksiklerini tespit etmekten daha zordur. Bu da tehlikeli bir duruma yol açabilir.
Bugün yazılım sistemleri devasa boyutlarda veriyi işleyebilirler. Bu verilerin önemli bir kısmı hassas veri olarak düşünülebilir. Bir sipariş numarası ya da sipariş tarihi hassas bir veri olmayabilir ancak kredi kartı bilgisi hassas bir bilgidir. Hassas bir veriye ilgilisi dışında kimse erişememeli, değişiklik yapamamalı ya da veri akışını izleyememelidir. En genel anlamda uygulama seviyesinde güvenliğin tanımı budur.
İnsanların verilerine sahip olan işletmeleri bu bilgilerin korunması için avrupa GDPR(general data protection regulation)’a tabidir. Ülkemizde bunun karşılığı kvkk’dır. Kişiler verileri koruma kanunu kapsamında kullanıcıların hassas bilgilerini koruyamamanın yasal sonuçları olur.
OWASP – https://www.owasp.org adresinden ulaşabileceğiniz, web ve mobil uygulamalardaki bazı ortak güvenlik zaafiyetlerinin tanımlarını bulabileceğiniz bir gönüllü platform.
Genel güvenlik zaafiyeti örnekleri :
– Broken authentication
– Session fixation
– Cross-site scripting (XSS)
– Cross-site request forgery (CSRF)
– Injections
– Sensitive data exposure
– Lack of method access control
– Using dependencies with known vulnerabilities
Authentication, bir uygulamanın, kendisini kullanmaya çalışan bir kişiyi tanımlama sürecini ifade eder. Bu süreç, bir kullanıcının veya bir sistem varlığının, sisteme girerken belirttiği kimliğinin gerçek ve güvenilir olup olmadığını doğrulama amacındadır.
Authorization, sisteme giriş yapmış ve authenticated olmuş kullanıcının özel bir işlemi yapmaya yetkisinin olup olmadığının belirlenmesi sürecidir.
Bir kullanıcı bir şekilde kendisine ait olmayan verilere erişebileceği bir işlemi çalıştırabildiyse burada “broken authorization” durumu vardır deriz.
Session Fixation (Oturum Sabitleme)
Saldırgan, bir web sitesine login olur ve bir oturum kimliği (Session ID) elde eder. Bu kimliği bir şekilde (mail vb.) bu web sitesini kullanan başka bir kullanıcıya, ilgisini çekecek bir içerik gibi sunarak gönderir. Kullanıcı bu gelen maildeki linke saldırganın gönderdiği session ID ile giderek login olur. login?session_id=345567 gibi bir değer olsun. Bu sırada saldırgan da web sitesi üzerinde aynı session ID ile kullanıcıya özel bir kaynağa erişmeye çalışır. userInfo?session_id=34567 gibi bir içerik olabilir. Eğer session ID değeri login olduktan sonra uygulama tarafından değiştirilmiyorsa – ki bu session fixation açığına yol açıyor- saldırgan kullanıcının oturumuna erişebilir durumda olduğunu görür.
Spring Security, varsayılan olarak Session Fixation saldırılarına karşı koruma sağlar. Kullanıcı oturum açtıktan sonra oturum kimliği değiştirilerek potansiyel bir saldırı engellenir.
Cross Site Scripting (XSS)
Örnek bir forum uygulamasında kullanıcı bir script “<script> alert(‘XSS Saldırısı!’); </script>” yazıp bunu post edebilir. Sistemi ziyaret eden tüm kullanıcılar da bu postu ve içeriğini (bir alert olabilir, ya da başka bir sistemin sunucusundan yüklü miktarda veri çekilmeye çalışılıp o sistemi meşgul etme amacında da olabilir) görebilirler.
CSRF(Cross Site Request Forgery)
Kaynak: owasp.org
Bir son kullanıcı aldatılarak bir uygulamada isteği dışında GET, POST işlemleri yaptırılabilir. Saldırgan öncelikle kullanıcının çalıştırabileceği geçerli bir request oluşturur. Bir banka uygulamasında transfer yapılan işlemi düşünelim.
GET http://bank.com/transfer.do?hesapSahibi=AHMET&miktar=100 HTTP/1.1
Kullanıcı Ahmet’e 100 tl göndermek istediğinde bu request kullanılıyor. Saldırgan sosyal mühendislikle bir şekilde kullanıcıyı manipüle ediyor ve başka bir request’i çalıştırması sağlanıyor. Mail aracılığıyla gönderilen bir link olabilir.
<a href=”http://bank.com/transfer.do?hesapSahibi=MEHMET&miktar=1000″>Resimlere Bak!</a>
CSRF ataklarına karşı savunmasız bir sistem bu request’i çalıştıracaktır.
Post senaryosunda ise, request örneğin link olarak ‘A’ tagleri içinde gönderilemez. Request bir form içinde yapılmalı.
<form action="http://bank.com/transfer.do" method="POST">
<input type="hidden" name="hesapSahibi" value="MEHMET"/>
<input type="hidden" name="miktar" value="1000"/>
<input type="submit" value="Resimlerime Bak"/>
</form>
Normalde bu formu çalıştırabilmek için kullanıcının bir submit butonuna tıklaması gerekir. Ancak bu Javascript kullanılarak otomatik olarak da yapılabilir.
<body onload="document.forms[0].submit()">
<form...