HTTP Header Security Principles

Introduction

This guideline focuses on the importance of HTTP header security in web applications. HTTP headers play a crucial role in enhancing the security of web applications by mitigating various attack vectors such as Cross-Site Scripting (XSS), Cross-Site Request Forgery (CSRF), clickjacking, and more. By properly configuring HTTP headers, developers can significantly improve the security posture of their applications and protect sensitive data.

This is only recommendation. The HTTP header settings will impact the application operation or affected by the system architecture, and should be considered on a case-by-case basis to balance security risks and operational needs.

  1. HTTP Strict Transport Security (HSTS)

    • Forces the browser to use HTTPS instead of HTTP.

    • Example: Strict-Transport-Security: max-age=31536000; includeSubDomains

  2. Content Security Policy (CSP)

    • Controls which resources the browser is allowed to load.

    • Example: Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.com;

  3. X-Content-Type-Options

    • Prevents MIME type sniffing.

    • Example: X-Content-Type-Options: nosniff

  4. X-Frame-Options

    • Protects against clickjacking attacks.

    • Example: X-Frame-Options: DENY

  5. X-XSS-Protection

    • Enables XSS filtering.

    • Example: X-XSS-Protection: 1; mode=block

  6. Referrer-Policy

    • Controls the amount of referrer information sent with requests.

    • Example: Referrer-Policy: strict-origin-when-cross-origin

  7. Permissions-Policy

    • Controls which browser features can be used.

    • Example: Permissions-Policy: geolocation=(), microphone=(), camera=()

  8. Cross-Origin Resource Policy (CORP)

    • Prevents certain cross-origin requests.

    • Example: Cross-Origin-Resource-Policy: same-origin

  9. Cross-Origin Opener Policy (COOP)

    • Prevents certain types of cross-origin attacks.

    • Example: Cross-Origin-Opener-Policy: same-origin

  10. Subresource Integrity (SRI)

    • Ensures that resources fetched from third-party servers have not been tampered with.

    • Example: <script src="https://trusted.com/script.js" integrity="sha384-abc123" crossorigin="anonymous"></script>

  11. Set-Cookie

    • Manages user sessions securely by setting cookie attributes.

    • Example: Set-Cookie: sessionId=abc123; HttpOnly; Secure; SameSite=Strict

      • HttpOnly: Prevents client-side scripts from accessing the cookie, mitigating the risk of XSS attacks.

      • Secure: Ensures the cookie is only sent over secure HTTPS connections.

      • SameSite: Prevents the browser from sending the cookie along with cross-site requests, protecting against CSRF attacks. Values can be Strict, Lax, or None.

Spring Security Configuration with HTTP Headers

import javax.servlet.http.Cookie;

public class SecureCookie extends Cookie {
    
    public SecureCookie(String name, String value) {
        super(name, value);
        setHttpOnly(true);
        setSecure(true);
        setPath("/");
        setMaxAge(3600); // 1 hour
        setDomain("example.com");
        setSameSite("Strict");
    }

    // Additional constructor if needed
    public SecureCookie(String name, String value, int maxAge) {
        super(name, value);
        setHttpOnly(true);
        setSecure(true);
        setPath("/");
        setMaxAge(maxAge); // Custom max age
        setDomain("example.com");
        setSameSite("Strict");
    }

    private void setSameSite(String sameSite) {
        // You might need to use reflection or a custom response header to set SameSite attribute, depending on your server implementation
        // Example: Add SameSite attribute to response header in a custom filter
    }
}

We can then update the custom filter to use this SecureCookie class.

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.springframework.web.filter.OncePerRequestFilter;

public class CustomCookieFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        filterChain.doFilter(request, response);

        // Use the SecureCookie class
        SecureCookie sessionCookie = new SecureCookie("sessionId", "abc123");
        response.addCookie(sessionCookie);
    }
}

Secure HTTP Header in Spring Security

Update the Spring Security configuration to include the custom filter.

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.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.context.SecurityContextPersistenceFilter;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeRequests(authorizeRequests ->
                authorizeRequests
                    .antMatchers("/", "/home").permitAll()
                    .anyRequest().authenticated()
            )
            .sessionManagement(sessionManagement ->
                sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            )
            .headers(headers ->
                headers
                    .httpStrictTransportSecurity(hsts -> hsts
                        .maxAgeInSeconds(31536000)
                        .includeSubDomains(true)
                    )
                    .contentTypeOptions(contentTypeOptions -> contentTypeOptions
                        .disable()
                    )
                    .frameOptions(frameOptions -> frameOptions
                        .deny()
                    )
                    .xssProtection(xssProtection -> xssProtection
                        .block()
                    )
                    .referrerPolicy(referrerPolicy -> referrerPolicy
                        .strictOriginWhenCrossOrigin()
                    )
                    .permissionsPolicy(permissionsPolicy -> permissionsPolicy
                        .geolocation("()").microphone("()").camera("()")
                    )
            )
            .sessionManagement(sessionManagement -> sessionManagement
                .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                .sessionFixation().migrateSession()
                .invalidSessionUrl("/login?invalid-session=true")
            )
            .rememberMe(rememberMe -> rememberMe
                .key("uniqueAndSecret")
                .tokenValiditySeconds(86400) // 1 day
            )
            .logout(logout -> logout
                .deleteCookies("JSESSIONID")
            )
            .addFilterBefore(new CustomCookieFilter(), SecurityContextPersistenceFilter.class);

        return http.build();
    }
}

Tips for Developers

  1. Understand the Purpose of Each Header: Familiarize yourself with the security benefits each HTTP header provides. Knowing how headers like HSTS, CSP, and X-Frame-Options work will help you implement them effectively.

  2. Use Secure Defaults: Always set secure defaults for your HTTP headers. For example, set X-Frame-Options to DENY unless you have a specific need to allow framing.

  3. Regularly Review and Update Headers: Keep your HTTP header configurations up-to-date. Security best practices evolve, and new headers may be introduced. Regularly review your header settings to ensure they remain effective.

  4. Test for Header Implementation: Use tools like browser developer tools, OWASP ZAP, and online scanners (e.g., securityheaders.com) to verify that your HTTP headers are correctly implemented and effective.

  5. Customize CSP for Your Application: Craft a Content Security Policy (CSP) that matches your application's requirements. Avoid using overly permissive settings, and refine your policy as your application evolves.

  6. Use Secure Cookie Attributes: When setting cookies, always use the HttpOnly, Secure, and SameSite attributes to protect against XSS and CSRF attacks.

  7. Educate Your Team: Ensure that all developers and team members understand the importance of HTTP header security and know how to configure and implement these headers correctly.

  8. Monitor and Log Header Activity: Monitor your application's HTTP header activity and log any deviations or suspicious behavior. This can help you detect and respond to potential security threats.

  9. Perform Regular Penetration Testing: Conduct regular penetration testing to identify and address any gaps in your HTTP header security. This will help ensure that your headers are providing the intended protection.

  10. Stay Informed: Keep up-to-date with the latest security trends and threats related to HTTP headers. Follow security blogs, join security communities, and participate in relevant training sessions to stay informed.

Last updated