Soru bankası · Güvenlik

Uygulama güvenliği: Spring Security, JWT, OAuth2

Authentication/authorization, Spring Security mimarisi ve 6+/7 yapılandırması, JWT ve token yaşam döngüsü, OAuth2/OIDC akışları, CORS/CSRF, şifre ve secret saklama, OWASP riskleri ve bankacılığa özgü önlemler üzerine başlangıçtan ileri seviyeye mülakat soruları.

32 soru21 çoktan seçmeli
Konu özeti

Authentication, authorization ve 401/403

Authentication (kimlik doğrulama) "sen kimsin?" sorusunu cevaplar: şifre, token, sertifika ya da biyometriyle kimliğin kanıtlanması. Authorization (yetkilendirme) "bunu yapmaya iznin var mı?" sorusudur: rol, scope ve kaynak sahipliği. Sıra hep aynıdır: önce kimlik, sonra yetki. HTTP karşılıkları da farklıdır: kimlik yoksa ya da geçersizse 401 Unauthorized (adı yanıltıcıdır, anlamı "unauthenticated"dır; WWW-Authenticate header'ıyla döner), kimlik belli ama yetki yoksa 403 Forbidden. Başkasına ait kaynakta varlığı gizlemek için 404 dönmek de meşru bir tercihtir (bkz. Kitap Bölüm 18).

Session mı, token mı?

Klasik web uygulamasında sunucu login sonrası bir session açar ve istemciye sadece rastgele bir session id'si (JSESSIONID cookie'si) verir; kullanıcının kim olduğu sunucuda (bellek, Redis, Spring Session) durur. İptal anlıktır (session'ı sil), ama yatay ölçeklemede ortak bir session deposu gerekir ve cookie tarayıcı tarafından otomatik gönderildiği için CSRF koruması şarttır. Token tabanlı yaklaşımda (çoğunlukla JWT) kimlik bilgisi imzalı token'ın içindedir; istemci her istekte Authorization: Bearer <token> gönderir, sunucu imzayı ve süreyi doğrulayıp veritabanına gitmeden kullanıcıyı tanır. Bedeli iptal zorluğu ve token boyutudur. "JWT modern, session eski" diye bir kural yoktur: tek bir tarayıcı uygulaması için session hâlâ çok iyi bir seçimdir; çok servisli ve çok istemcili sistemlerde token öne çıkar.

Spring Security mimarisi

Spring Security servlet tarafında bir filter zinciridir ve controller'dan önce çalışır. Servlet container'a kayıtlı DelegatingFilterProxy, işi bir Spring bean'i olan FilterChainProxy'ye devreder; o da isteğe uyan ilk SecurityFilterChain'i seçip içindeki filter'ları sırayla çalıştırır. Kabaca sıra şöyledir: context'i yükleyen filter, CORS, CSRF, logout, kimlik doğrulama filter'ları (form login, HTTP Basic, BearerTokenAuthenticationFilter), anonymous, ExceptionTranslationFilter ve en sonda AuthorizationFilter.

Kimlik doğrulama filter'ı istekten bir Authentication nesnesi üretip AuthenticationManager'a verir. Varsayılan uygulama ProviderManager, işi bir AuthenticationProvider listesine devreder. Kullanıcı adı/şifre için DaoAuthenticationProvider, kullanıcıyı UserDetailsService ile yükler ve şifreyi PasswordEncoder ile karşılaştırır. Başarılı sonuç SecurityContext'e konur; SecurityContextHolder bunu varsayılan olarak ThreadLocal'da tutar, FilterChainProxy da istek bitince temizler. Hatalar ExceptionTranslationFilter'da HTTP'ye çevrilir: AuthenticationException (ya da anonim kullanıcının yetki reddi) AuthenticationEntryPoint ile 401'e, kimliği doğrulanmış kullanıcının AccessDeniedException'ı AccessDeniedHandler ile 403'e.

Spring Security 6+ ve 7 yapılandırması

WebSecurityConfigurerAdapter 5.7'de deprecate edildi, 6.0'da kaldırıldı; yerine SecurityFilterChain tipinde bir bean tanımlanır. 7.0'da (Kasım 2025; Spring Boot 4.0 bu nesli kullanır) and() zinciri ve authorizeRequests kaldırıldı; lambda DSL ve authorizeHttpRequests tek yoldur. Spring Boot 3.x Spring Security 6.x ile gelir. Aşağıdaki stil iki nesilde de çalışır:

java
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
class SecurityConfig {

    @Bean
    SecurityFilterChain api(HttpSecurity http) throws Exception {
        http
            .securityMatcher("/api/**")
            .authorizeHttpRequests(auth -> auth
                .requestMatchers(HttpMethod.GET, "/api/public/**").permitAll()
                .requestMatchers(HttpMethod.POST, "/api/payments/**").hasAuthority("SCOPE_payments.write")
                .anyRequest().authenticated())
            .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()))
            .sessionManagement(s -> s.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .csrf(csrf -> csrf.disable());   // safe only because credentials travel in a header, not a cookie
        return http.build();
    }

    @Bean
    PasswordEncoder passwordEncoder() {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();   // bcrypt by default
    }
}

Kurallar yazıldığı sırayla değerlendirilir ve ilk eşleşen kazanır; bu yüzden özelden genele yazılır ve sonda anyRequest() olur. Method security için @EnableMethodSecurity (deprecate edilmiş @EnableGlobalMethodSecurity'nin yerine) @PreAuthorize ve @PostAuthorize'ı açar. Bu kontroller Spring AOP proxy'siyle çalışır: aynı sınıf içinden this.method() çağrısı proxy'yi atladığı için kontrol çalışmaz (@Transactional ile aynı tuzak). hasRole('ADMIN') aslında ROLE_ADMIN yetkisini arar; OAuth2 resource server ise scope'ları SCOPE_ önekiyle yetkiye çevirir.

Şifre saklama

Şifre asla düz metin ya da geri çözülebilir şekilde (encryption) saklanmaz; tek yönlü, kasıtlı olarak yavaş ve salt'lı bir hash ile saklanır. MD5 ve SHA-256 gibi hızlı hash'ler şifre için uygun değildir, çünkü GPU ile saniyede milyarlarca deneme yapılabilir. OWASP Password Storage Cheat Sheet'in sırası: Argon2id, scrypt, bcrypt (eski sistemler için), FIPS gerekiyorsa PBKDF2. Salt her kullanıcı için rastgeledir ve hash'le birlikte saklanır; aynı şifrelerin aynı hash'i üretmesini ve hazır tabloları (rainbow table) engeller. Spring'in DelegatingPasswordEncoder'ı hash'i {bcrypt}$2a$10$... biçiminde önekle saklar, böylece algoritma ileride değiştirilebilir. BCryptPasswordEncoder'ın varsayılan strength'i 10'dur; Spring dokümanı maliyetin, doğrulama sistemde yaklaşık bir saniye sürecek şekilde ayarlanmasını önerir. bcrypt'in 72 byte girdi sınırı da unutulmamalıdır.

JWT

JSON Web Token (RFC 7519) üç Base64URL parçadan oluşur: header.payload.signature. Header algoritmayı (alg, ör. RS256) ve anahtar kimliğini (kid), payload claim'leri (iss, sub, aud, exp, iat, nbf, jti, scope/rol) taşır; imza ilk iki parçanın üzerinden atılır. En yaygın yanlış: yaygın kullanılan JWT (JWS) şifreli değildir, imzalıdır. Payload'u herkes okur; imza sadece içeriğin değişmediğini ve kimin ürettiğini kanıtlar. Gizlilik gerekiyorsa JWE vardır, ama çoğu zaman doğru çözüm token'a hassas veri koymamaktır.

Doğrulamada imza, sunucunun belirlediği algoritma listesi, exp/nbf, iss ve aud kontrol edilir. İki klasik tuzak: alg: none ile imzasız token kabul eden kütüphaneler ve algoritma karışıklığı (RS256 sisteminde token'ı HS256'ya çevirip RSA public key'ini HMAC secret'ı olarak kullandırmak). RFC 8725 (JWT BCP) bu yüzden kabul edilen algoritmaların çağıran tarafından belirlenmesini şart koşar. İptal JWT'nin doğal zayıflığıdır: imza geçerli ve süre dolmamışsa token geçerlidir. Bu yüzden kısa ömürlü access token (ör. 5-15 dakika) ve sunucuda izlenen, her kullanımda yenilenen (rotation) refresh token birlikte kullanılır; anlık iptal için jti denylist'i ya da kullanıcı bazlı token sürümü gibi durum tutan ek bir mekanizma gerekir.

OAuth2 ve OpenID Connect

OAuth 2.0 (RFC 6749) bir yetki devri (delegated authorization) çerçevesidir: kullanıcı şifresini paylaşmadan bir uygulamaya kendi adına sınırlı erişim verir. Dört rol vardır: resource owner (kullanıcı), client (uygulama), authorization server (token veren; Keycloak, Okta, Spring Authorization Server) ve resource server (token'ı kabul eden API; senin Spring Boot servisin). OAuth2 bir protokoldür, JWT ise bir token formatıdır; OAuth2 access token'ı JWT olabilir ya da opaque olabilir.

Önerilen akışlar: kullanıcı varsa authorization code + PKCE (RFC 7636), makineler arası client credentials. RFC 9700 (OAuth 2.0 Security BCP, Ocak 2025) implicit grant'in kullanılmamasını (SHOULD NOT), resource owner password credentials grant'in ise hiç kullanılmamasını (MUST NOT) söyler; public client'lar için PKCE zorunludur. Hâlâ taslak olan OAuth 2.1 bu iki akışı tamamen çıkarır ve PKCE'yi tüm authorization code akışlarına zorunlu kılar; taslak olduğu için ona standart gibi değil, yön gösteren bir derleme gibi atıf yapmak doğrudur.

OAuth2 tek başına bir kimlik doğrulama protokolü değildir. OpenID Connect üzerine kimlik katmanı ekler: openid scope'u, userinfo endpoint'i ve ID token (client'a kullanıcının kim olduğunu söyleyen JWT; aud değeri client id'sidir). ID token API çağırmak için değil, access token API için kullanılır. Spring Boot'ta bir API'yi resource server yapmak için starter eklenip issuer-uri verilir; Spring ilk JWT'li istekte issuer'ın metadata'sından jwks_uri'yi bulur, public key'leri çeker, exp, nbf ve iss'i varsayılan olarak doğrular; aud için audiences eklenir:

yaml
spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://idp.example.com/realms/bank
          audiences: payments-api

Starter adı Boot 3.x'te spring-boot-starter-oauth2-resource-server; Boot 4.0'da spring-boot-starter-security-oauth2-resource-server olarak yeniden adlandırıldı (eski ad geçiş için deprecated tutuluyor).

CORS ve CSRF

İkisi sık karıştırılır. CORS, tarayıcının farklı origin'den gelen JavaScript'in cevabı okumasına izin verip vermeyeceğini belirleyen kontrollü bir gevşetmedir; sunucuyu korumaz, curl'ü durdurmaz (bkz. Kitap Bölüm 18). CSRF bir saldırıdır: kötü site, kullanıcının tarayıcısına otomatik gönderilen cookie ile hedef siteye istenmeyen bir işlem yaptırır. Koruma CSRF token, SameSite cookie ve durum değiştiren işlemlerin GET ile yapılmamasıdır. Spring Security CSRF korumasını varsayılan açık getirir. REST API'de kapatmak, kimlik bilgisi otomatik gönderilmiyorsa (bearer token header'ı, tarayıcı dışı istemciler) güvenlidir; token cookie'de taşınıyorsa API "stateless" olsa bile CSRF yeniden gündemdedir.

OWASP listeleri

OWASP Top 10, web uygulaması riskleri için en bilinen farkındalık listesidir. 2021 sürümü: A01 Broken Access Control, A02 Cryptographic Failures, A03 Injection, A04 Insecure Design, A05 Security Misconfiguration, A06 Vulnerable and Outdated Components, A07 Identification and Authentication Failures, A08 Software and Data Integrity Failures, A09 Security Logging and Monitoring Failures, A10 Server-Side Request Forgery. 2025 sürümü Kasım 2025'te önce release candidate olarak duyuruldu; owasp.org bugün onu güncel liste olarak sunuyor. Broken Access Control birinci kaldı, Security Misconfiguration ikinciye çıktı, A03 Software Supply Chain Failures ve A10 Mishandling of Exceptional Conditions eklendi, SSRF A01'in içine alındı. Mülakatta hangi sürümden bahsettiğini söylemen yeterlidir. API'ler için ayrıca OWASP API Security Top 10 (2023) vardır; birinci maddesi BOLA, yani nesne düzeyinde yetki kontrolünün eksikliğidir (IDOR).

Sık görülen açıklar

  • SQL injection: Kullanıcı girdisinin sorgu metnine eklenmesi. Çözüm parametreli sorgudur (PreparedStatement, JPQL'de :param). JPA kullanmak tek başına korumaz: JPQL ya da native sorguyu string birleştirerek kurmak aynı açığı yaratır. ORDER BY kolonu gibi parametreleştirilemeyen yerlerde beyaz liste kullanılır.
  • XSS: Girdinin başka bir kullanıcının tarayıcısında script olarak çalışması. Çözüm bağlama göre output encoding, Content-Security-Policy ve token'ı JavaScript'in okuyamayacağı yerde tutmaktır.
  • SSRF: Sunucunun kullanıcının verdiği URL'ye istek atması (webhook, "URL'den içe aktar"). Saldırgan iç ağa ya da bulut metadata servisine (169.254.169.254) eriştirir. Çözüm hedef allowlist'i, DNS çözümlendikten sonra iç IP aralıklarının engellenmesi, yönlendirmelerin kapatılması ve ağ seviyesinde egress kısıtıdır.
  • Rate limiting: Login, OTP ve kupon gibi tahmin edilebilir uç noktalarda kaba kuvvete karşı; reddedilen isteğe 429 ve Retry-After dönülür.

Taşıma, secret'lar ve loglar

HTTPS (TLS) üç şey sağlar: gizlilik, bütünlük ve sunucu kimliğinin sertifikayla doğrulanması. Bearer token TLS olmadan anlamsızdır, çünkü token'ı ele geçiren onun sahibi olur. Secret'lar (DB şifresi, imza anahtarı, API key) kodda ve git'te durmaz; ortam değişkeni, Kubernetes Secret (Base64 şifreleme değildir) ya da tercihen Vault, AWS Secrets Manager gibi bir secret yöneticisinde tutulur, döndürülür ve sızıntıda önce iptal edilir. Loglara şifre, token, Authorization header'ı, kart numarası ve gereksiz kişisel veri yazılmaz; gerekiyorsa maskelenir (KVKK, PCI DSS).

Bankacılıkta ek katmanlar

Finans API'lerinde genellikle şunlar eklenir: servisler ve kurumlar arasında mTLS (iki taraf da sertifikayla kimliğini kanıtlar; RFC 8705 access token'ı istemci sertifikasına bağlamayı tanımlar), isteğin bütünlüğü ve inkâr edilemezliği için imzalı istekler (JWS ya da HTTP Message Signatures), kritik işlemlerde adım yükseltmeli doğrulama (step-up, OTP), kim-ne-zaman-nereden-sonuç bilgisini değiştirilemez biçimde tutan audit log ve FAPI gibi finansa özel OAuth profilleri. Mülakatta bu kısım derinlemesine değil, "bunların farkında mı" diye yoklanır.

Sorular (32)

01BaşlangıçTahminiauthenticationauthorization

Authentication ile authorization arasındaki fark nedir?

02BaşlangıçTahminihttp401403spring-security

401 ile 403 arasındaki fark nedir? Spring Security hangisini ne zaman döner?

03BaşlangıçTahminipasswordhashingbcryptargon2

Şifreler veritabanında nasıl saklanır?

04BaşlangıçTahminihashingencryptionencodinghmac

Hash, encryption ve encoding arasındaki fark nedir?

05BaşlangıçTahminijwttokensignature

JWT nedir ve nasıl çalışır?

06BaşlangıçTahminijwtjwsjwepii

JWT şifreli midir? Payload'a ne koyarsın, ne koymazsın?

07BaşlangıçAday raporujwtexpirationexpclock-skew

Token süresi (expiration) nasıl çalışır?

08BaşlangıçTahminisessionjwtstatelesscookie

Session tabanlı kimlik doğrulama ile JWT arasındaki fark nedir? Hangisini seçersin?

09BaşlangıçTahminicorscsrfbrowser

CORS nedir ve CSRF'ten farkı nedir?

10BaşlangıçTahminisql-injectionjpajpqlowasp

SQL injection nedir ve JPA kullanırken nasıl önlenir?

11BaşlangıçTahminihttpstlsmtlszero-trust

HTTPS ne sağlar? Kurum içi ağda da gerekli mi?

12BaşlangıçTahminisecretsvaultkubernetesconfiguration

Secret'ları (DB şifresi, API key, imza anahtarı) nerede tutarsın?

13BaşlangıçTahminiowasptop-10

OWASP Top 10'dan üç örnek verir misin?

14OrtaTahminispring-securityfilter-chainarchitecture

Spring Security'de bir HTTP isteği hangi aşamalardan geçer?

15OrtaTahminispring-securitysecurity-contextthreadlocalasync

SecurityContext ve SecurityContextHolder nedir? Async kodda ne olur?

16OrtaTahminispring-securitymethod-securitypreauthorizeaop

@PreAuthorize nasıl çalışır? Neden bazen hiç çalışmaz?

17OrtaAday raporuoauth2jwttoken-formatprotocol

OAuth ile JWT arasındaki fark nedir?

18OrtaAday raporuoauth2refresh-tokenrotationjwt

Refresh token akışı nasıl işler?

19OrtaTahminijwtlocalstoragecookiexss

JWT'yi istemcide nerede saklarsın? localStorage mı, HttpOnly cookie mi?

20OrtaTahminicsrfrestspring-securitycookie

REST API'de CSRF koruması gerekir mi? Ne zaman kapatırsın?

21OrtaTahminioauth2oidcid-tokenaccess-token

OAuth2 bir authentication protokolü müdür? OpenID Connect ne ekler?

22OrtaTahminiidorbolaauthorizationowasp-api

IDOR/BOLA nedir? Bir örnek ver, nasıl önlersin?

23OrtaTahminixsscspoutput-encodingowasp

XSS nedir? Backend geliştirici olarak ne yaparsın?

24OrtaTahminiloggingpiimaskingkvkk

Loglarda hassas veri ve PII nasıl ele alınır?

25OrtaTahminibrute-forcecredential-stuffingrate-limitingmfa

Login endpoint'ini brute force ve credential stuffing'e karşı nasıl korursun?

26İleriAday raporujwtrevocationrefresh-tokendenylist

JWT'ler geçersiz kılınabilir mi?

27İleriTahminioauth2pkceauthorization-coderfc-9700

Authorization code + PKCE akışını anlatır mısın? Implicit ve password grant neden önerilmiyor?

28İleriTahminiclient-credentialsmtlsservice-to-servicetoken-exchange

Servisler arası kimlik doğrulamayı nasıl kurarsın?

29İleriTahminijwtalg-nonealgorithm-confusionresource-server

JWT doğrulamada algoritma tuzakları nelerdir? Spring Boot resource server'ı güvenli nasıl yapılandırırsın?

30İleriAday raporuapi-gatewayauthenticationrate-limitingzero-trust

API gateway'de kimlik doğrulama ve güvenlik nasıl kurgulanır?

31İleriTahminissrfowaspegresscloud-metadata

SSRF nedir, nasıl önlenir?

32İleriTahminiloginauthenticationsessionmfa

Güvenli bir login endpoint'i tasarlar mısın?

Çoktan seçmeli (21)

01Başlangıç

Kullanıcının JWT'si geçerli ve süresi dolmamış, ancak ADMIN yetkisi gerektiren bir endpoint'e USER yetkisiyle istek atıyor. API hangi status kodunu dönmelidir?

Tek doğru cevap var.

02Başlangıç

Kullanıcı şifrelerini veritabanında saklamak için hangisi doğrudur?

Tek doğru cevap var.

03Başlangıç

İmzalı bir JWT'nin (JWS) payload'u hakkında hangisi doğrudur?

Tek doğru cevap var.

04Başlangıç

Aşağıdakilerden hangisi bir authorization (yetkilendirme) kontrolüdür?

Tek doğru cevap var.

05Başlangıç

Spring Data JPA kullanan bir projede hangi yaklaşım SQL/JPQL injection'a açıktır?

Tek doğru cevap var.

06Başlangıç

CORS hakkında hangisi doğrudur?

Tek doğru cevap var.

07Başlangıç

Production veritabanı şifresi için en uygun yaklaşım hangisidir?

Tek doğru cevap var.

08Başlangıç

HTTPS (TLS) aşağıdakilerden hangilerini sağlar? (Birden fazla doğru var)

Birden fazla doğru olabilir.

09Başlangıç

OWASP Top 10 2021 listesinde birinci sıradaki kategori hangisidir?

Tek doğru cevap var.

10Orta

Kullanıcının yetkileri arasında öneksiz ADMIN var. @PreAuthorize("hasRole('ADMIN')") ile korunan metot çağrıldığında ne olur?

Tek doğru cevap var.

11Orta

AccountService içindeki korumasız closeFromBatch() metodu, aynı sınıftaki @PreAuthorize("hasRole('ADMIN')") ile korunan close() metodunu doğrudan (this üzerinden) çağırıyor. Ne olur?

Tek doğru cevap var.

12Orta

GET /api/v1/accounts/{id} endpoint'inde IDOR'u önlemenin en doğru yolu hangisidir?

Tek doğru cevap var.

13Orta

Hangi durumda bir REST API için Spring Security CSRF korumasını kapatmak güvenlidir?

Tek doğru cevap var.

14Orta

OAuth 2.0 ile JWT arasındaki ilişki için hangisi doğrudur?

Tek doğru cevap var.

15Orta

Refresh token akışı için hangisi doğrudur?

Tek doğru cevap var.

16Orta

OpenID Connect'teki ID token'ın doğru kullanımı hangisidir?

Tek doğru cevap var.

17İleri

RS256 ile imzalanan token'ları doğrulayan bir API'de saldırgan header'ı alg: HS256 yapıp imzayı sunucunun public key'ini HMAC secret'ı olarak kullanarak üretiyor. En doğru savunma hangisidir?

Tek doğru cevap var.

18İleri

PKCE (RFC 7636) authorization code akışında hangi saldırıya karşı koruma sağlar?

Tek doğru cevap var.

19İleri

Müşterinin hesabı ele geçirildi ve tüm token'larının hemen geçersiz olması gerekiyor. Aşağıdakilerden hangileri buna yardım eder? (Birden fazla doğru var)

Birden fazla doğru olabilir.

20İleri

API gateway arkasındaki servisler için hangi tasarım en güvenlidir?

Tek doğru cevap var.

21İleri

Kullanıcının verdiği URL'den resim indiren bir özellikte SSRF'e karşı en etkili önlem hangisidir?

Tek doğru cevap var.

Kaynaklar