一、前言

前端上线一套批注系统,该批注系统需由院内去调用我方云端批注系统,最后报错"net::ERR_SSL_PROTOCOL_ERROR",如下图所示:

记一次企业级CSP安全策略引发请求响应无效事件_HTTPS

二、需求场景分析:

首先能确定线上是正常可以正常访问,一个院内内网环境Nginx做了代理去访问官方域名,通过IP去调用导致一直无法正常请求.

记一次企业级CSP安全策略引发请求响应无效事件_HTTPS_02

两个疑问?

1、为什么我内部Nginx代理去访问云端的批注系统,部分接口能正常响应返回200,而有的资源无法正常响应呢?
2、上游内部nginx代理官网默认是http协议,并未配置https协议,Ip访问为什么会跳转https去访问?

记一次企业级CSP安全策略引发请求响应无效事件_HTTPS_03

遇到了HTTP请求被强制跳转到HTTPS的问题,但你的nginx服务器并没有配置HTTPS。这通常是由以下几个原因造成的:

可能的原因和解决方案

  • 后端服务器强制HTTPS
  • 代理的目标网站 可能设置了HTTP严格传输安全(HSTS)或强制HTTPS
  1. 浏览器HSTS缓存
  • 如果你之前访问过该网站的真实HTTPS版本,浏览器可能缓存了HSTS策略
  • 解决方案:清除浏览器HSTS设置或使用隐私模式访问
  1. 应用代码中的强制HTTPS
  • 被代理的网站可能在代码中强制HTTPS

此时检查目标端域名所在的服务器,细致排查了可能会造成拦截来自IP请求的静态资源或者是强制跳转https的请求的参数。其中定位到了有两个参数

add_header Content-Security-Policy "upgrade-insecure-requests;connect-src *.51trust.com;
  add_header Strict-Transport-Security "max-age=31536000;includeSubdomains;";
  • 1.
  • 2.

针对上述两个参数,我做了细致的了解。

add_header Strict-Transport-Security 

简称HSTS,是一种安全响应头,用来强制客户端(浏览器)只能通过HTTPS与服务器通信

参数详解:

  • max-age=31536000

指定HSTS策略有效时间为31536000,即一年,在这段时间内浏览器会自动将该域名的HTTPS请求升级为HTTPS,不会在访问HTTPS

  • includeSubdomains

该策略同时适用于所有子域名,比如设置了这个之后,比如server端 上面所有二级域名

 add_header Content-Security-Policy

简称CSP,是一项Web安全机制,用来限制网页可以加载哪些资源,连接哪些服务、执行哪些脚本,从而防止XSS和数据泄露。

参数详解:

  • upgrade-insecure-request

自动把页面中所有的HTTP请求升级成HTTPS请求;主要是用来解决部分静态资源仍然使用http导致混合内容问题。

  • connect-src *.51trust.com

限制页面中JS的连接目标范围,假设JS静态资源尝试使用,其他区域名,将会浏览器阻止访问请求

结合上述对参数的理解,在回过头来看看报错的响应,可以发现,用于以内部IP的作为请求地址,去调用前端静态资源确实存在拦截...

为什么被拦截?是因为你的请求来源是IP地址,而不是下游服务器所允许的域名范围。再者下游CSP安全策略告诉浏览器,不允许访问http,必须要以https去访问,同时也返回了“net::ERR_SSL_PROTOCOL_ERROR”错误,也就是说下游Nginx将资源都自动升级为HTTPS,当你用户请求是http,结果上游Nginx没有配置HTTPS,最终导致失败。

记一次企业级CSP安全策略引发请求响应无效事件_HTTPS_04

三、解决方案

经过上述一轮分析,渐渐有了解决办法,要么我狠下心将上游目标端代理的Nginx CSP安全策略给移除掉,一了百了,这样我们下游Nginx 以http协议请求的时候,不在强制升级HTTP,浏览器就会正常请求到下游Nginx云端资源

但是,作为专业的技术人员我能去一刀切,为了去解决这个问题,去引发另外一个安全问题吗?前面讲到,CSP策略是什么?干什么用的?说白了不就是防止XSS和用户数据泄露吗?所以不能直接去在下游Nginx移除这个安全策略。

那既然如此,有没有一种能在源头去解决这个问题呢?能不能在源头去拦截这个策略响应?

答案是有的,很简单,直接在上游Nginx配置"proxy_hide_header Content-Security-Policy"这个参数即可,

该参数是拦截/移除上游服务器返回的Content-Security-Policy响应头,防止他传递到客户端浏览器。

最后在nginx.conf配置文件中新增一个,加到loccation配置中即可完美解决!

location /onLineEdit/ {
        proxy_hide_header Content-Security-Policy;
        proxy_pass  https//xxx.xxx.com;
      }
  • 1.
  • 2.
  • 3.
  • 4.

可以发现,浏览器再去请求的时候前端静态资源加载就正常。

记一次企业级CSP安全策略引发请求响应无效事件_HTTPS_05

记一次企业级CSP安全策略引发请求响应无效事件_HTTPS_06