多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
## 前言 某些情况,大家的系统会被扫描出低危漏洞,描述如下: ``` 1.未设置Content-Security-Policy或X-Content-Security-Policy响应头. 2.未设置Strict-Transport-Security响应头. 3.Set-Cookie未设置Secure标识. 4.Set-Cookie未设置HttpOnly标识. ``` 处理方式也很简单,有Nginx和Java两种方式,我们更推荐从Nginx进行配置。 <br> ## 一、Nginx配置(推荐,性能更高,可灵活变动,不影响系统运行) ### 1. 在 Nginx 中添加安全 HTTP 响应头 可以通过 `add_header` 指令在 Nginx 配置中全局添加所需的 HTTP 响应头。 #### 示例 Nginx 配置: ```nginx server { listen 443 ssl; server_name yourdomain.com; # SSL 证书配置 ssl_certificate /path/to/your/certificate.crt; ssl_certificate_key /path/to/your/private.key; # 确保客户端只能通过 HTTPS 访问 add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; # 添加 Content-Security-Policy 头,限制资源加载来源 add_header Content-Security-Policy "default-src 'self';" always; # 添加 X-Content-Type-Options 头,防止 MIME 类型嗅探 add_header X-Content-Type-Options "nosniff" always; # 添加 X-Frame-Options 头,防止点击劫持,使用 SAMEORIGIN 来允许同源访问 add_header X-Frame-Options "SAMEORIGIN" always; # 添加 X-XSS-Protection 头,防止 XSS 攻击 add_header X-XSS-Protection "1; mode=block" always; # 添加 X-Permitted-Cross-Domain-Policies 头,阻止跨域策略文件被加载 add_header X-Permitted-Cross-Domain-Policies "none" always; # 添加 X-Download-Options 头,防止文件被下载时自动打开 add_header X-Download-Options "noopen" always; # 添加 Referrer-Policy 头,限制引荐来源的披露 add_header Referrer-Policy "strict-origin-when-cross-origin" always; # 处理反向代理请求 location / { proxy_pass http://your_backend_server; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } ``` ### 2. 全局设置 `Set-Cookie` 的 `Secure` 和 `HttpOnly` 标识 对于 `Set-Cookie` 头,你可以使用 `proxy_cookie_path` 和 `proxy_cookie_flags` 指令来修改 `Set-Cookie` 头,添加 `Secure` 和 `HttpOnly` 标识。 #### 示例 Nginx 配置: ```nginx server { listen 443 ssl; server_name yourdomain.com; # SSL 证书配置 ssl_certificate /path/to/your/certificate.crt; ssl_certificate_key /path/to/your/private.key; # 确保客户端只能通过 HTTPS 访问 add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; # 添加 Content-Security-Policy 头,限制资源加载来源 add_header Content-Security-Policy "default-src 'self';" always; # 添加 X-Content-Type-Options 头,防止 MIME 类型嗅探 add_header X-Content-Type-Options "nosniff" always; # 添加 X-Frame-Options 头,防止点击劫持,使用 SAMEORIGIN 来允许同源访问 add_header X-Frame-Options "SAMEORIGIN" always; # 添加 X-XSS-Protection 头,防止 XSS 攻击 add_header X-XSS-Protection "1; mode=block" always; # 添加 X-Permitted-Cross-Domain-Policies 头,阻止跨域策略文件被加载 add_header X-Permitted-Cross-Domain-Policies "none" always; # 添加 X-Download-Options 头,防止文件被下载时自动打开 add_header X-Download-Options "noopen" always; # 添加 Referrer-Policy 头,限制引荐来源的披露 add_header Referrer-Policy "strict-origin-when-cross-origin" always; # 为所有 Set-Cookie 头添加 Secure 标识(需要 HTTPS) proxy_cookie_flags ~ Secure; # 为所有 Set-Cookie 头添加 HttpOnly 标识 proxy_cookie_flags ~ HttpOnly; # 处理反向代理请求 location / { proxy_pass http://your_backend_server; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } ``` ### 3. 配置说明 - **`add_header`**:用于在 HTTP 响应中添加自定义头。`always` 参数确保即使返回 4xx 或 5xx 错误代码时也会添加这些头。 - `Strict-Transport-Security`: 强制浏览器通过 HTTPS 访问,避免中间人攻击。 - `Content-Security-Policy`: 限制资源加载的来源,防止 XSS 攻击。 - `X-Content-Type-Options`: 防止 MIME 类型嗅探,避免浏览器解析错误的文件类型。 - `X-Frame-Options`: 防止点击劫持攻击。 - `X-XSS-Protection`: 启用浏览器的 XSS 过滤器,防止 XSS 攻击。 - **`proxy_cookie_flags`**:用于修改 `Set-Cookie` 头的标识。`~` 匹配所有 Cookie。 - `Secure`: 仅在 HTTPS 连接下发送 Cookie,避免 Cookie 在明文 HTTP 传输中被窃取。 - `HttpOnly`: 防止 JavaScript 访问 Cookie,减少 XSS 攻击的风险。 ### 4. 其他安全头 你还可以根据需要添加其他安全头,例如: - **Referrer-Policy**: 控制浏览器在发送 HTTP 请求时如何处理 `Referer` 头。 ```nginx add_header Referrer-Policy "no-referrer" always; ``` - **Permissions-Policy**: 控制浏览器的某些特性(如摄像头、麦克风等)的使用权限。 ```nginx add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always; ``` ### 5. 总结 通过在 Nginx 中配置这些安全头和 `Set-Cookie` 标识,你可以确保所有的请求和响应都符合安全要求,而不需要修改应用程序的代码。这样可以集中管理安全策略,并且对所有后端服务生效。 #### 要点: - 使用 `add_header` 指令为响应添加安全头。 - 使用 `proxy_cookie_flags` 指令为所有 `Set-Cookie` 头添加 `Secure` 和 `HttpOnly` 标识。 - 确保 Nginx 配置文件正确无误后,重新加载 Nginx 配置。 通过这种方式,可以在 Nginx 层面上解决安全问题。 <br> ## 二、Java配置(不推荐,影响系统性能,不可灵活配置) 1. java可以用一个filter解决所有请求头、响应头的安全问题,具体范例如下: ```java import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Collection; import java.util.stream.Collectors; import org.springframework.stereotype.Component; @Component public class SecurityHeadersFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // 初始化方法,可选 } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletResponse httpServletResponse = (HttpServletResponse) response; // 设置Content-Security-Policy响应头 httpServletResponse.setHeader("Content-Security-Policy", "default-src 'self'"); // 设置Strict-Transport-Security响应头 httpServletResponse.setHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains"); // 继续处理请求 chain.doFilter(request, response); // 拦截响应中的Set-Cookie头,添加Secure和HttpOnly标识 Collection<String> setCookieHeaders = httpServletResponse.getHeaders("Set-Cookie"); if (setCookieHeaders != null) { // 将现有的Set-Cookie头处理并重新设置 Collection<String> modifiedCookies = setCookieHeaders.stream() .map(cookie -> { if (!cookie.toLowerCase().contains("secure")) { cookie += "; Secure"; } if (!cookie.toLowerCase().contains("httponly")) { cookie += "; HttpOnly"; } return cookie; }) .collect(Collectors.toList()); // 先移除原有的Set-Cookie头 httpServletResponse.setHeader("Set-Cookie", null); // 重新添加修改后的Set-Cookie头 for (String modifiedCookie : modifiedCookies) { httpServletResponse.addHeader("Set-Cookie", modifiedCookie); } } } @Override public void destroy() { // 销毁方法,可选 } } ``` 2. 在 Spring Boot 中,过滤器会自动注册,但也可以通过 `@Bean` 显式注册过滤器。 ```java import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class FilterConfig { @Bean public FilterRegistrationBean<SecurityHeadersFilter> securityHeadersFilter() { FilterRegistrationBean<SecurityHeadersFilter> registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new SecurityHeadersFilter()); registrationBean.addUrlPatterns("/*"); // 对所有请求生效 return registrationBean; } } ``` 3. **`doFilter` 方法中的逻辑**: * 首先,设置需要的安全响应头(如`Content-Security-Policy`和`Strict-Transport-Security`)。 * 然后,调用`chain.doFilter(request, response)`继续处理请求,这样后续的逻辑可以正常执行,并生成响应。 * 当响应生成后,我们获取所有的`Set-Cookie`头。 * 对每个`Set-Cookie`头进行处理,检查是否已经包含`Secure`和`HttpOnly`标识。如果没有,则自动添加这些标识。 * 最后,重新设置修改后的`Set-Cookie`头。 4. **处理流程**: * 过滤器会在每个请求的响应阶段执行,确保所有的`Set-Cookie`头都被检查和修改(如果需要)。 * 这样,你就不需要在每次设置`Cookie`时手动处理`Secure`和`HttpOnly`标识了。 5. **注意事项** * **HTTPS**:`Secure`标识仅在 HTTPS 连接下有效。如果你在本地开发时使用的是 HTTP,则`Secure`标识不会生效,只有在 HTTPS 环境下才会生效。 * **HttpOnly**:这个标识会阻止 JavaScript 访问`Cookie`,因此确保你不需要通过 JavaScript 访问这些`Cookie`。