You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复Java Spring Boot应用中的‘Cookie Security: Cookie not Sent Over SSL (4720)’漏洞

Spring Boot 修复Cookie未通过SSL发送漏洞及Cookie加密方案

一、修复‘Cookie not Sent Over SSL (4720)’漏洞

这个漏洞的核心原因是Cookie未设置Secure属性,导致Cookie可能通过HTTP明文传输。以下是代码/配置层面的修复方式:

1. 配置文件方式(application.properties/yaml)

直接在配置文件中全局设置Session Cookie的安全属性:

# 开启Secure属性,仅允许Cookie通过HTTPS传输
server.servlet.session.cookie.secure=true
# 附加安全配置:禁止JS读取Cookie,降低XSS风险
server.servlet.session.cookie.http-only=true
# 限制Cookie跨站发送,防范CSRF攻击
server.servlet.session.cookie.same-site=Strict

2. Java配置类方式

如果需要更灵活的控制,可通过配置类设置Session Cookie属性:

import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.SessionCookieConfig;
import javax.servlet.ServletContext;

@Configuration
public class CookieSecurityConfig {

    @Bean
    public ServletContextInitializer servletContextInitializer() {
        return servletContext -> {
            SessionCookieConfig sessionCookieConfig = servletContext.getSessionCookieConfig();
            sessionCookieConfig.setSecure(true); // 强制仅HTTPS传输Cookie
            sessionCookieConfig.setHttpOnly(true);
            sessionCookieConfig.setSameSite("Strict");
        };
    }
}

3. 自定义Cookie的处理

如果是业务代码中手动创建的自定义Cookie,必须显式设置Secure属性:

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

public void setCustomCookie(HttpServletResponse response) {
    Cookie customCookie = new Cookie("business-token", "user-specific-value");
    customCookie.setSecure(true); // 关键:开启Secure属性
    customCookie.setHttpOnly(true);
    customCookie.setSameSite("Strict");
    customCookie.setPath("/"); // 根据业务需求设置路径
    response.addCookie(customCookie);
}

二、Cookie加密实现及解密说明

Spring Boot框架本身不会自动加密Cookie,需要手动实现或借助Spring Security的工具类完成:

1. Session Cookie加密(基于Spring Security)

如果是Spring Security管理的Session Cookie,可通过自定义CookieSerializer实现加密:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.web.savedrequest.DefaultCookieSerializer;

@Configuration
public class SecurityCookieConfig {

    @Bean
    public DefaultCookieSerializer cookieSerializer() {
        DefaultCookieSerializer serializer = new DefaultCookieSerializer();
        serializer.setSecure(true);
        serializer.setHttpOnly(true);
        serializer.setSameSite("Strict");
        serializer.setCookieName("SESSION");
        serializer.setDomainName("your-domain.com"); // 替换为实际域名
        // 设置加密密钥(建议从环境变量/配置中心读取,避免硬编码)
        serializer.setCookieCipherKey("your-256-bit-secret-key".getBytes()); // 密钥需为16/24/32字节(对应AES-128/192/256)
        return serializer;
    }
}

这种方式下,Spring Security会自动完成Session Cookie的加密和解密,无需手动处理。

2. 自定义Cookie加密

对于业务自定义的Cookie,需手动实现加密解密逻辑:

加密工具类

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class CookieCryptoUtil {
    private static final String AES_ALGORITHM = "AES";
    // 建议从环境变量读取密钥,密钥长度必须为16/24/32字节
    private static final String SECRET_KEY = System.getenv("COOKIE_ENCRYPT_KEY");

    // 加密Cookie值
    public static String encrypt(String plainValue) throws Exception {
        SecretKeySpec keySpec = new SecretKeySpec(SECRET_KEY.getBytes(), AES_ALGORITHM);
        Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, keySpec);
        byte[] encryptedBytes = cipher.doFinal(plainValue.getBytes());
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }

    // 解密Cookie值
    public static String decrypt(String encryptedValue) throws Exception {
        SecretKeySpec keySpec = new SecretKeySpec(SECRET_KEY.getBytes(), AES_ALGORITHM);
        Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, keySpec);
        byte[] decodedBytes = Base64.getDecoder().decode(encryptedValue);
        byte[] decryptedBytes = cipher.doFinal(decodedBytes);
        return new String(decryptedBytes);
    }
}

设置加密Cookie

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

public void setEncryptedBusinessCookie(HttpServletResponse response) throws Exception {
    String sensitiveData = "user-sensitive-info";
    String encryptedData = CookieCryptoUtil.encrypt(sensitiveData);
    Cookie encryptedCookie = new Cookie("sensitive-cookie", encryptedData);
    encryptedCookie.setSecure(true);
    encryptedCookie.setHttpOnly(true);
    encryptedCookie.setSameSite("Strict");
    encryptedCookie.setPath("/");
    response.addCookie(encryptedCookie);
}

读取并解密Cookie

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

public String getDecryptedBusinessCookie(HttpServletRequest request) throws Exception {
    Cookie[] cookies = request.getCookies();
    if (cookies != null) {
        for (Cookie cookie : cookies) {
            if ("sensitive-cookie".equals(cookie.getName())) {
                return CookieCryptoUtil.decrypt(cookie.getValue());
            }
        }
    }
    return null;
}

解密是否自动处理?

  • Session Cookie:使用Spring Security的CookieSerializer配置加密后,框架会自动完成解密,无需手动干预。
  • 自定义Cookie:框架不会自动处理,必须在读取Cookie时手动调用解密方法。

内容的提问来源于stack exchange,提问作者Jake Turner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 06:02:22