Spring Boot Security Headers Sinhala | CSP, X-Frame-Options | ආරක්ෂිත Spring Boot
ආයුබෝවන් යාළුවනේ! Spring Boot App එක ආරක්ෂා කරගන්න Security Headers දාමු!
අද කාලේ cyber security කියන්නේ අපිට මඟ අරින්න බැරි මාතෘකාවක්. විශේෂයෙන්ම, අපි develop කරන applications ආරක්ෂා කරගන්න එක developers විදිහට අපේ ලොකු වගකීමක්. Spring Boot කියන්නේ applications හදන්න අපිට ගොඩක් උදව් වෙන powerful framework එකක්. ඒත්, ඒක ආරක්ෂිතව පාවිච්චි කරන්නේ කොහොමද කියලා දැනගන්න එකත් ගොඩක් වැදගත්.
මේ article එකෙන් අපි කතා කරන්නේ Spring Boot applications වලට HTTP Security Headers එකතු කරන්නේ කොහොමද කියලයි. මේ headers කියන්නේ browser එකට ඔයාගේ web application එක load කරද්දී කොහොම behave කරන්න ඕනෙද කියලා කියන පොඩි instructions ටිකක්. මේවා පාවිච්චි කරලා අපිට Cross-Site Scripting (XSS), Clickjacking, සහ තවත් ගොඩක් attack වලින් අපේ app එක ආරක්ෂා කරගන්න පුළුවන්.
අපි අද මේ ගැන විස්තරාත්මකව කතා කරමු, මොකද මේවා ඔයාගේ app එකට ඇතුල් කරන එක එච්චර සංකීර්ණ දෙයක් නෙවෙයි. ඒ වගේම, මේ headers දාපු ගමන් ඔයාගේ app එකේ security level එක ගොඩක් වැඩි වෙනවා. එහෙනම්, අපි පටන් ගමු!
HTTP Security Headers කියන්නේ මොනවද?
සරලවම කිව්වොත්, HTTP Security Headers කියන්නේ web server එකෙන් client ගේ browser එකට යවන HTTP response එකේ තියෙන special instructions. මේ instructions වලින් browser එකට කියනවා website එකේ content එක display කරද්දී මොනවා කරන්න ඕනෙද, මොනවා කරන්න හොඳ නැද්ද කියලා.
උදාහරණයක් විදිහට, සමහර headers වලින් browser එකට කියනවා මේ site එක frames ඇතුලේ load කරන්න එපා කියලා. තවත් headers වලින් කියනවා මේ site එකේ scripts දුවවන්න පුළුවන් sources මොනවද කියලා. මේ විදිහට, අපේ app එකට attack කරන්න හදන malicious scripts වලින්, හෝ phishing attacks වගේ දේවල් වලින් user ලා ආරක්ෂා කරගන්න මේ headers අපිට උදව් වෙනවා.
මේ headers සාමාන්යයෙන් web server (Nginx, Apache) මට්ටමෙන් configure කරන්න පුළුවන් වුණත්, Spring Security framework එක පාවිච්චි කරලා අපේ Spring Boot application එක ඇතුලෙන්ම මේවා configure කරන්න පුළුවන් වීම විශාල වාසියක්.
Spring Boot Application එකකට Headers එකතු කරන්නේ කොහොමද?
Spring Security framework එකේ HttpSecurity object එක පාවිච්චි කරලා අපිට පහසුවෙන් මේ security headers add කරන්න පුළුවන්. මේ සඳහා අපි WebSecurityConfigurerAdapter (හෝ Spring Security 6+ වල SecurityFilterChain) class එක extend කරලා අපේම custom configuration එකක් හදාගන්නවා.
මුලින්ම, ඔයාගේ project එකේ Spring Security dependency එක තියෙනවද කියලා බලන්න. pom.xml (Maven) හෝ build.gradle (Gradle) එකේ මේක තියෙන්න ඕනේ:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>දැන් අපි බලමු කොහොමද මේ configuration class එක හදාගන්නේ කියලා. අපි @Configuration සහ @EnableWebSecurity annotations පාවිච්චි කරනවා.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// මෙතන තමයි අපේ Security Headers configure කරන්නේ
.headers(headers -> headers
// මෙතනට headers add කරමු
);
// අනෙකුත් Spring Security configurations
// .authorizeHttpRequests(authorize -> authorize.anyRequest().authenticated());
// .formLogin();
return http.build();
}
}Spring Security 5.7.0 සිට WebSecurityConfigurerAdapter Deprecated කරලා තියෙන නිසා, අපි අලුත් ක්රමය වන SecurityFilterChain එක පාවිච්චි කරනවා. දැන් අපි එකින් එක security headers ගැන කතා කරලා, ඒ ටික මේ filterChain method එක ඇතුලට දාන්නේ කොහොමද කියලා බලමු.
1. Content Security Policy (CSP) - XSS වලින් ආරක්ෂා වෙන්න
Content Security Policy (CSP) කියන්නේ XSS (Cross-Site Scripting) attacks වලින් ඔයාගේ application එක ආරක්ෂා කරගන්න පුළුවන් powerful header එකක්. CSP එකෙන් browser එකට කියනවා මොන sources වලින්ද scripts, styles, images වගේ content load කරන්න පුළුවන් කියලා. මේක හරියට whitelist එකක් වගේ වැඩ කරනවා.
CSP එකක් configure කරද්දී, ඔයාට විවිධ directives පාවිච්චි කරන්න පුළුවන්:
default-src: default source එක. මේක තමයි අනිත් directives වලට default විදිහට apply වෙන්නේ.script-src: JavaScript files වලට source.style-src: CSS files වලට source.img-src: Images වලට source.connect-src: AJAX, WebSocket වගේ connections වලට source.
ඔයාගේ Spring Boot config එකට CSP එකතු කරන්නේ මෙහෙමයි:
// ... SecurityConfig class එක ඇතුලේ filterChain method එක තුල
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.headers(headers -> headers
.contentSecurityPolicy("default-src 'self'; script-src 'self' https://trusted.cdn.com; style-src 'self' 'unsafe-inline';")
);
// ... rest of the config
return http.build();
}මේ උදාහරණයේ තේරුම:
default-src 'self': හැම content එකක්ම load වෙන්න ඕනේ site එකේම domain එකෙන්.script-src 'self' https://trusted.cdn.com: Scripts load වෙන්න පුළුවන් site එකේ domain එකෙන් හෝhttps://trusted.cdn.comවගේ trusted CDN එකකින්.style-src 'self' 'unsafe-inline': Styles load වෙන්න පුළුවන් site එකේ domain එකෙන්, ඒ වගේම inline styles (<style>tags හෝstyle="..."attributes) පාවිච්චි කරන්නත් පුළුවන්. ('unsafe-inline'පාවිච්චි කරද්දී පරිස්සම් වෙන්න, හැකිනම් avoid කරන්න.)
CSP policies හදද්දී ගොඩක් පරිස්සම් වෙන්න ඕනේ. වැරදි policy එකක් දැම්මොත් ඔයාගේ site එකේ සමහර features වැඩ නොකර යන්න පුළුවන්.
2. X-Frame-Options - Clickjacking වලින් ආරක්ෂා වෙන්න
X-Frame-Options header එකෙන් ඔයාගේ web page එක <frame>, <iframe>, <embed>, <object> වගේ tags ඇතුලේ load වෙන එක control කරනවා. මේක වැදගත් වෙන්නේ Clickjacking attacks වලින් ආරක්ෂා වෙන්නයි. Clickjacking attack එකකදී, attacker කෙනෙක් ඔයාගේ site එක විනිවිද පෙනෙන iframe එකක් ඇතුලේ තියලා user ලාව රැවටලා buttons click කරවන්න පුළුවන්.
මේ header එකට options දෙකක් තියෙනවා:
DENY: කිසිම වෙලාවක ඔයාගේ page එක frame එකක් ඇතුලේ load කරන්න බෑ.SAMEORIGIN: ඔයාගේ page එකට frame කරන්න පුළුවන් තමන්ගේම site එකේ pages වලට විතරයි.
Spring Boot config එකට X-Frame-Options එකතු කරන්නේ මෙහෙමයි:
// ... SecurityConfig class එක ඇතුලේ filterChain method එක තුල
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.headers(headers -> headers
.frameOptions(frameOptions -> frameOptions.sameOrigin())
// .frameOptions(frameOptions -> frameOptions.deny())
);
// ... rest of the config
return http.build();
}sameOrigin() කියන්නේ හොඳ default choice එකක්. ඔයාට කිසිම වෙලාවක frame කරන්න ඕනේ නැත්නම් deny() පාවිච්චි කරන්න පුළුවන්.
3. Strict-Transport-Security (HSTS) - HTTPS විතරක් පාවිච්චි කරන්න
HTTP Strict-Transport-Security (HSTS) header එකෙන් browser එකට කියනවා ඔයාගේ site එකට හැමවිටම HTTPS හරහාම සම්බන්ධ වෙන්න කියලා. මේක Man-in-the-Middle (MITM) attacks වලින් user ලා ආරක්ෂා කරනවා. සාමාන්යයෙන් user කෙනෙක් http://example.com කියලා type කලොත්, browser එක මුලින්ම HTTP request එකක් යවනවා. HSTS තියෙනවා නම්, browser එක කෙලින්ම HTTPS request එකක් යවනවා.
මේ header එක වැඩ කරන්න නම්, ඔයාගේ application එක HTTPS හරහා serve කරන්න ඕනේ. HSTS වලට parameters දෙකක් තියෙනවා:
max-age: මේ site එකට HSTS policy එක apply වෙලා තියෙන්නේ කොච්චර කාලෙකටද (seconds වලින්).includeSubDomains: Subdomains වලටත් මේ policy එක apply වෙන්න ඕනෙද කියලා.
Spring Boot config එකට HSTS එකතු කරන්නේ මෙහෙමයි:
// ... SecurityConfig class එක ඇතුලේ filterChain method එක තුල
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.headers(headers -> headers
.httpStrictTransportSecurity(hsts -> hsts
.maxAgeInSeconds(31536000) // අවුරුදු 1ක්
.includeSubDomains(true)
)
);
// ... rest of the config
return http.build();
}maxAgeInSeconds(31536000) කියන්නේ අවුරුද්දකට ආසන්න කාලයක්. මේක සාමාන්යයෙන් අවුරුදු 1ක් හෝ 2ක් වගේ කාලයකට දාන එක තමයි හොඳ.
4. අනෙකුත් වැදගත් Security Headers
ඉහත Headers වලට අමතරව, තවත් වැදගත් Headers කීපයක්ම තියෙනවා:
X-Content-Type-Options - MIME-sniffing වලින් ආරක්ෂා වෙන්න
මේ header එකෙන් browser එකට කියනවා response එකේ Content-Type header එක ignore කරලා content එක 'sniff' කරලා type එක තීරණය කරන්න එපා කියලා. මේකෙන් attacker කෙනෙක් HTML file එකක් image එකක් විදිහට upload කරලා XSS attack එකක් කරන එක වළක්වනවා. හැමවිටම nosniff value එක පාවිච්චි කරන්න.
// ... headers configuration block එක ඇතුලේ
.contentTypeOptions(withDefaults())X-XSS-Protection - Browser එකේ XSS filter එක activate කරන්න
මේ header එකෙන් browser එකේ built-in XSS filter එක activate කරනවා. mode=block කියන්නේ XSS attack එකක් detect වුණොත් page එක load වෙන එක නවත්වනවා.
නමුත්, CSP තියෙන app වලට මේක එච්චර අවශ්ය නෑ, මොකද CSP එකෙන් වඩා හොඳ ආරක්ෂාවක් දෙනවා. ඒ වගේම, සමහර වෙලාවට මේ XSS filter එකෙන් legitimate scripts block කරන්නත් පුළුවන්. ඒත් old browsers වලට මේක පොඩි ආරක්ෂාවක් දෙනවා.
// ... headers configuration block එක ඇතුලේ
.xssProtection(xss -> xss.headerValue("1; mode=block"))Referrer-Policy - Referrer information control කරන්න
Referrer-Policy header එකෙන් browser එකට කියනවා වෙනත් site එකකට link එකක් click කරද්දී Referer header එකේ මොන වගේ information එකක් යවන්න ඕනෙද කියලා. මේක user ගේ privacy එකට වැදගත්.
// ... headers configuration block එක ඇතුලේ
.referrerPolicy(referrer -> referrer.policy(ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN))STRICT_ORIGIN_WHEN_CROSS_ORIGIN කියන්නේ cross-origin requests වලදී domain එක විතරක් යවනවා, same-origin requests වලදී සම්පූර්ණ URL එක යවනවා.
සියල්ල එකට එකතු කරමු - Complete SecurityConfig Class එකක්!
දැන් අපි කතා කරපු හැම header එකක්ම එකට එකතු කරලා complete SecurityConfig class එකක් බලමු:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.header.ReferrerPolicy;
import static org.springframework.security.config.Customizer.withDefaults;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.anyRequest().permitAll() // මේක demo එකක් විතරයි, ඔයාගේ app එකේ actual authorization rules දාන්න
)
.headers(headers -> headers
.contentSecurityPolicy(csp -> csp
.policyDirectives("default-src 'self'; script-src 'self' https://code.jquery.com; style-src 'self' 'unsafe-inline'; img-src 'self'; font-src 'self'; connect-src 'self';")
)
.frameOptions(frameOptions -> frameOptions.sameOrigin())
.httpStrictTransportSecurity(hsts -> hsts
.maxAgeInSeconds(31536000) // 1 year
.includeSubDomains(true)
)
.contentTypeOptions(withDefaults())
.xssProtection(xss -> xss.headerValue("1; mode=block"))
.referrerPolicy(referrer -> referrer.policy(ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN))
.permissionsPolicy(permissions -> permissions
.policy("geolocation=(self \"https://example.com\"), microphone=()")
)
)
// CSRF protection enabled by default. If you need to disable it (e.g. for stateless APIs),
// use .csrf(csrf -> csrf.disable()); but be aware of the security implications.
.csrf(withDefaults()); // CSRF protecton by default
return http.build();
}
}
සැලකිය යුතුයි: .authorizeHttpRequests(authorize -> authorize.anyRequest().permitAll()) කියන්නේ හැම request එකකටම access දෙන්න කියන එක. ඔයාගේ production app එකකදී ඔයාට මේකට වඩා specific authorization rules දාන්න සිද්ධ වෙනවා. මේක උදාහරණයක් විතරයි.
ඒ වගේම CSRF (Cross-Site Request Forgery) protection Spring Security වල default විදිහට enable වෙලා තියෙන්නේ. ඒක අයින් කරන්න අවශ්ය නම් .csrf(csrf -> csrf.disable()); පාවිච්චි කරන්න පුළුවන්. හැබැයි එහෙම කරද්දී ඒකෙන් ඇතිවෙන security implications ගැන හොඳටම දැනුවත් වෙන්න.
අවසන් වශයෙන්
ඉතින් යාළුවනේ, මේ ලිපියෙන් ඔයාට Spring Boot application එකක් HTTP Security Headers පාවිච්චි කරලා ආරක්ෂා කරගන්න විවිධ ක්රම ගැන හොඳ අවබෝධයක් ලැබෙන්න ඇති කියලා හිතනවා. මේ headers add කරන එක එච්චර අමාරු දෙයක් නෙවෙයි, ඒත් ඔයාගේ application එකට විශාල ආරක්ෂාවක් ලබා දෙනවා.
ආරක්ෂාව කියන්නේ එක වෙලාවක කරලා ඉවර කරන දෙයක් නෙවෙයි. ඒක අඛණ්ඩව කරගෙන යන්න ඕනේ දෙයක්. අලුත් attacks එන හැම වෙලාවකම අපිටත් අලුත් ක්රම වලින් ආරක්ෂා වෙන්න සිද්ධ වෙනවා.
දැන් ඔයා දන්නවා Spring Boot application එකක security headers configure කරන්නේ කොහොමද කියලා. මේ දැනුම ඔයාගේ ඊළඟ project එකේදී පාවිච්චි කරන්න අමතක කරන්න එපා. ඔයාගේ app එකට මේ headers එකතු කරලා බලන්න. ඔයාට ප්රශ්න තියෙනවා නම්, comment section එකේ අහන්න! අපි එකට ඉගෙන ගනිමු!
ඔබ සැමට සුබ දවසක්!