Spring Container tarafından yönetilen bean nesnelerinin nasıl oluşturulacağını, ne kadar süre yaşayacağını ve hangi kapsamda kullanılcağını belirleyen yapılandırma ayarıdır.
Scope Türü Açıklama Yaşam döngüsü Singleton Tek bir instance oluşturur Container başlangıcından sonuna kadar Prototype Her talep için yeni bir instance Talep edildiğinde oluşturulur. Request HTTP isteği boyunca yaşar Tek bir HTTP isteği süresince Session HTTP session boyunca yaşar Kullanıcı session süresi dolana kadar
Singleton Scope
- Varsayılan scope türüdür.
- Container başına sadece bir instance oluşturur.
- Tüm bean referansları aynı nesneyi işaret eder.
- Thread-safe olmaya dikkat edilmelidir.
@Component
@Scope("singleton")
public class DatabaseService{
private String ConnectionUrl;
public void connect(){// Connection process...}
}Kullanım alanları: Service Sınıfları, DAO katmanı, Utility Sınıfları
Prototype Scope
- Her getBean() çağrısında yeni bir instance
- Spring Container sadece oluşturmakla sorumlu
- Lifecycle yönetimi geliştiriciye bırakılır.
- Memory Leak riski yüksek
@Component
@Scope("prototype")
public class ShoppingCart{
private List<Item> items = new ArrayList<>();
public void addItem(Item item){
items.add(item);
}
}Kullanım alanları: Stateful nesneler, Kullanıcıya özel veriler, geçici işlem nesneleri
Web Application Scope
Request Scope
- HTTP request süresince yaşar.
- Response gönderildikten sonra yok edilir.
- Request-specific veriler için kullanılır
@Scope("request")
@Component
public class RequestLogger{
private String requestId;
}Session Scope
- HTTP Session süresince yaşar.
- Kullanıcı çıkışında veya session süresi bitiminde temizlenir.
- Kullanıcı bazlı veriler için kullanılır.
@Scope("session")
@Component
public class UserPreferences{
private String theme;
}Application ve WebSocket Scope
Application Scope
- Tüm web uygulaması boyunca yaşar.
- ServletContext ile aynı yaşam döngüsüne sahip.
- Global application veriler için kullanılır.
WebSocket Scope
- WebSocket session süresince yaşar.
- Real-time uygulamalar için kullanılır.
- WebSocket bağlantısına özeldir.
Best practices ve Scope Seçimi
- Stateless servisler: Singleton scope
- Kullanıcı verileri: Session scope
- İstek bazlı işlemler: Request scope
- Geçici nesneler: Prototype scope (fakat dikkatli kullanılmalıdır.)
Dikkat edilmesi gerekenler
- Prototype bean'lerde memory leak riski bulunmaktadır.
- Singleton bean'lerde thread safety'e dikkat edilmelidir.
- Web scope'ları sadece web uygulamalarında.
- Web scope'ları proxy gerektirir.
Pekiştirme
Singleton
- Bir sınıfı @Component veya @Service yaparsan tüm uygulama boyunca o sınıftan bir tane nesne üretir.
- Yani ne kadar @Autowired yaparsan yapalım hep aynı nesneyi elde edersin.
@Component
public class MyBean{
}
@Autowired
private MyBean bean1;
@Autowired
private MyBean bean2;
// bean1 == bean2 -> truePrototype
@Component
@Scope("prototype")
public class MyBean{
}
@Autowired
private MyBean bean1;
@Autowired
private Mybean bean2;
// bean1 == bean2 -> false
// çünkü her istekte farklı bir nesne oluşturur.Web projelerinde kullanılanlar
- request -> Her HTTP için yeni bir nesne üretilir.
- session -> Her kullanıcı oturumu için tek nesne.
- application -> Tüm uygulama boyunca tek nesne ( singleton gibi değil, Servlet-context'e bağlı).
- websocket -> Her websocket bağlantısı içi tek nesne.
Dikkatsiz oluşturulmuş bean nesnelerinde oluşabilecek zafiyetler
1. @Component, @Service, @Repository, @Controller
Bunların hepsi Spring Container tarafından otomatik bean olarak oluşturulur (component scanning).
Olası Zafiyetler
A. İstenmeyen Bean Yüklenmesi (Component Scanning Abuse)
Yanlış package scanning:
@ComponentScan("com")Bu durumda:
- test class'ları
- debug endpoint'leri
- admin utility class'ları
- PoC exploit bean'leri production ortamına yüklenebilir.
Riskler
- Gizli endpoint açılması
- Yetkisiz admin servisleri
- Backdoor bean injection
- Shadow bean override
Örnek
@Servicepublic class AdminBypassService { public boolean isAdmin() { return true; }}Yanlış scan sonucu production'a dahil olabilir.
B. Bean Override Saldırıları
Aynı isimde bean tanımlanması:
@Service("paymentService")saldırgan dependency chain içine sahte bean yerleştirebilirse:
- auth bypass
- log manipulation
- crypto downgrade oluşabilir.
Özellikle:
- plugin architecture
- dynamically loaded jars
- multi-tenant platform ortamlarında kritiktir.
C. Reflection/Proxy Tabanlı Exploit Surface
Spring:
- CGLIB
- JDK Dynamic Proxy
- Reflection kullanır.
Yanlış proxy chain:
- method interception abuse
- AOP bypass
- security annotation bypass üretebilir.
Örnek:
@Secured("ADMIN")public void deleteUser() {}Self-invocation durumunda AOP çalışmayabilir.
Sonuç:
- authorization bypass
2. @Bean
Manuel bean üretir.
@Beanpublic ObjectMapper mapper() { return new ObjectMapper();}Olası Zafiyetler
A. Insecure ObjectMapper Konfigürasyonu
En kritik örneklerden biridir.
Yanlış kullanım:
mapper.enableDefaultTyping();Bu:
- insecure deserialization
- gadget chain execution
- RCE oluşturabilir.
Geçmişte:
- Jackson CVE zincirleri
- Spring Boot RCE'leri buradan çıkmıştır.
B. Güvensiz Third-Party Bean Enjeksiyonu
@Beanpublic ScriptEngine engine() { return new NashornScriptEngine();}Eğer kullanıcı girdisi script'e giderse:
- command execution
- sandbox escape oluşabilir.
C. Secret Leakage
@Beanpublic AwsClient client() { return new AwsClient("hardcoded-secret");}Secrets:
- heap dump
- actuator
- logs
- memory inspection ile sızabilir.
3. @Scope
Bean yaşam döngüsünü belirler.
Singleton Scope Riskleri
Default scope singleton'dır.
@Servicepublic class UserContext { private String currentUser;}Bu kritik bir hatadır.
Sonuç
Concurrent request'lerde:
- user data leakage
- session confusion
- privilege mixup oluşabilir.
OWASP karşılığı
- Broken Access Control
- Sensitive Data Exposure
Prototype Scope Riskleri
@Scope("prototype")Aşırı object creation:
- memory exhaustion
- DoS üretebilir.
Request / Session Scope Riskleri
Yanlış cache veya static kullanımında:
- session fixation
- stale session exposure oluşabilir.
Request / Session Scope Riskleri
Yanlış cache veya static kullanımında:
- session fixation
- stale session exposure oluşabilir.
4. @Autowired
Dependency Injection annotation'ı.
Riskler
A. Unsafe Dependency Injection
Eğer attacker-controlled bean sisteme eklenebilirse:
@AutowiredPaymentService paymentService;dependency hijacking oluşabilir.
B. Null Injection / Optional Abuse
@Autowired(required = false)Security bean null olabilir:
if(authService == null) { return true;}=> authentication bypass
5. @Value
@Value("${api.key}")Riskler
A. Expression Injection (SpEL Injection)
En kritik Spring açıklarından biridir.
Yanlış kullanım:
@Value("#{${user.input}}")veya:
parser.parseExpression(userInput)Sonuç:
- arbitrary method execution
- RCE Örnek payload:
T(java.lang.Runtime).getRuntime().exec('calc')6. @Configuration
Proxy bean üretir.
Riskler
A. Proxy Bypass
@Configuration(proxyBeanMethods = false)Yanlış kullanım:
- duplicate singleton
- inconsistent security state oluşturabilir.
Güvenli Kullanım Önerileri
1.Component Scan Kısıtla
@ComponentScan(basePackages = { "com.myapp.service"})2. Stateless Singleton Kullan
Bean içinde:
- request data
- user state
- mutable shared state tutma.
3. SpEL Kullanımını Minimize Et
User input'u:
- parseExpression
- dynamic evaluation içine verme.
4. ObjectMapper Harden Et
mapper.disableDefaultTyping();5. Bean Override Kapat
spring.main.allow-bean-definition-overriding=false