HTTP协议安全头部X-Content-Type-Options引入的问题

这篇具有很好参考价值的文章主要介绍了HTTP协议安全头部X-Content-Type-Options引入的问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文于2016年4月完成,发布在个人博客网站上。 考虑个人博客因某种原因无法修复,于是在博客园安家,之前发布的文章逐步搬迁过来。


前段时间测试MM反馈了一个问题,在富文本编辑器里上传的图片无法正常呈现。因为Jackie在本机的环境上没有观察类似的现象,而恰好那天测试环境的某个重要配项被改错了,于是Jackie想当然的归类为配置项错误引入的问题。但修改完测试环境的配置项后,测试反馈富文本编辑器内图片无法呈现的现象依然存在。

这下就有点麻烦了,问题是在版本上线的前一天晚上发现的,如果问题不能尽快处理,势必对第二天的版本上线产生影响。虽然逢上线必加班至深夜,但也不能让问题挂在Jackie手里。

时间紧急,问题诡异,Jackie马上放下手头的工作,全力投入分析工作中。

排查过程

  • 如前所述,配置项修改正确后,问题现象仍然存在,因此首先排除了配置项配置引入问题的可能。
  • 请测试MM帮忙复现问题,仔细观察之后,发现使用不同浏览器访问问题页面时可以观察到不同的现象:
    • 使用Chrome访问页面时,富文本编辑器内的图片可以正常呈现。
    • 使用IE9、IE11访问页面时,富文本编辑器内的图片无法呈现。从浏览器的呈现效果看,貌似是图片加载失败;但在调试器的网络面板查看页面资源的加载情况,可以观察到浏览器发起了图片的获取请求,而Web应用确实返回了图片信息;但就是没有呈现出来。
    • 直接把富文本编辑器的内图片的URL复制出来,贴到浏览器的地址栏里访问,图片可以正常呈现。
  • 在生产环境和体验环境上做对比验证,使用IE9、IE11访问这两个环境,查看富文本编辑器内的图片,没有观察到前述的问题,因此可以判定测试MM在测试环境上发现的问题是最近引入的,时间范围不超过2个星期,因为那段时间项目组早已切换为两周一迭代的节奏。
  • 检查富文本编辑器相关代码的提交记录,发现最近的提交记录远在几个月前,因此基本可以排除富文本编辑器自身代码的问题。
  • 肿么搞呢?似乎进入了死胡同。看来常规的方法都不见效,只能逐一排查代码提交记录了。

幸运的是提交记录不多,10分钟之内被Jackie扫描了一遍;大部分提交记录都是清白了,唯一可疑的提交记录来自于Jackie本人,果然这个问题只能由Jackie来定位和分析。为了解决AppScan报告中提到的“HTTP响应缺少安全头部”的警告,Jackie在发现问题的那天早上修改了Tomcat的配置,增加了安全头部相关的过滤器,而晚上留在办公室加班,目的就是要确认前述的警告是否已消除。

为了确认前述问题和HTTP安全头部的相关性,Jackie手工修改测试环境上Tomcat的配置,去掉了增加安全头部的过滤器,重启Tomcat后尝试重现问题,惊喜的发现,富文本编辑器内的图片恢复正常呈现,这说明HTTP响应增加安全头部之后,对基本功能产生了影响。

当前启用了HTTP协议的安全头部的如下几个:

  • Strict-Transport-Security
  • X-Frame-Options
  • X-Content-Type-Options
  • X-XSS-Protection

范围比较小,逐个排查之后,发现前述问题现象和X-Content-Type-Options相关,因此决定仍然启用HTTP安全头部的输出,但禁用X-Content-Type-Options,富文本编辑器内的图片可以正常呈现,同时不会对安全性造成很大的影响。

本来觉得修改Tomcat的配置和业务不相关,不会有什么问题,也没有过基本功能,结果偏偏天不遂人愿,还真让测试MM发现个诡异问题。看来侥幸心理不能有,该做的工作不能省,否则就得加班、加倍的补回来。

下面使用最少的样例代码来说明问题是如何发生的。

问题是如何发生的

准备复现环境

jsp页面

<%@ page session="false" pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %>
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title><%=request.getServletContext().getServerInfo() %></title>
    </head>
        <div>
            <img alt="FileDownload" src="<%=request.getContextPath()%>/GetPicture">
        </div>
    <body>
        
    </body>
</html>

GetPicture的实现

如下这段代码的实现存在问题,使用流方式返回数据时,没有显式指定Content-Type

package com.struts2.servlets;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;

public class GetPictureServlet extends HttpServlet {

	private static final long serialVersionUID = -5935833295545479697L;
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {			
		String path = req.getServletContext().getRealPath("");

		byte[] buffer = new byte[4096];
		int count = 0;
		InputStream is = null;
		OutputStream os = null;

		try
		{
			is = new FileInputStream(new File(path, "tomcat.png"));
			os = resp.getOutputStream();
			
			while ((count = is.read(buffer)) > 0) {
				os.write(buffer, 0, count);
			}
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		finally
		{
			IOUtils.closeQuietly(is);
			IOUtils.closeQuietly(os);
		}
	}
}

web.xml

<servlet>
    <servlet-name>GetPictureServlet</servlet-name>
    <servlet-class>com.struts2.servlets.GetPictureServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>GetPictureServlet</servlet-name>
    <url-pattern>/GetPicture</url-pattern>
</servlet-mapping>    

使用浏览器观察

重温一些安全相关的HTTP响应头中对X-Content-Type-Options的介绍。

互联网上的资源有各种类型,通常浏览器会根据响应头的Content-Type字段来分辨它们的类型。例如:"text/html"代表html文档,"image/png"是PNG图片,"text/css"是CSS样式文档。然而,有些资源的Content-Type是错的或者未定义。这时,某些浏览器会启用MIME-sniffing来猜测该资源的类型,解析内容并执行。

使用浏览器调试面板来观察HTTP响应的头部,对上文做验证。

  1. 未启用HttpHeaderSecurityFilter时,HTTP响应的头部如下

     Content-Length:5103
     Date:Mon, 02 May 2016 05:07:22 GMT
     Server:Apache-Coyote/1.1
    
  2. 修改$CATALINA_BASE/conf/web.xml,启用HttpHeaderSecurityFilter

     <filter>
         <filter-name>httpHeaderSecurity</filter-name>
         <filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
         <async-supported>true</async-supported>        
     </filter>
    

    使用浏览器的调试面板观察Tomcat响应浏览器请求时的HTTP头部

     Cache-Control:private
     Content-Length:5103
     Date:Mon, 02 May 2016 05:42:00 GMT
     Expires:Thu, 01 Jan 1970 08:00:00 CST
     Server:Apache-Coyote/1.1
     Strict-Transport-Security:max-age=30;includeSubDomains
     X-Content-Type-Options:nosniff
     X-Frame-Options:SAMEORIGIN
     X-XSS-Protection:1; mode=block
    

    此时,使用浏览器访问页面时,图片不能正常呈现。

  3. 修改$CATALINA_BASE/conf/web.xml,禁用X-Content-Type-Options特性

     <filter>
         <filter-name>httpHeaderSecurity</filter-name>
         <filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
         <async-supported>true</async-supported>           
         <init-param>
             <param-name>blockContentTypeSniffingEnabled</param-name>
             <param-value>false</param-value>
         </init-param>
     </filter>
    

    使用浏览器的调试面板观察Tomcat响应浏览器请求时的HTTP头部

     Cache-Control:private
     Content-Length:5103
     Date:Mon, 02 May 2016 05:50:39 GMT
     Expires:Thu, 01 Jan 1970 08:00:00 CST
     Server:Apache-Coyote/1.1
     Strict-Transport-Security:max-age=30;includeSubDomains
     X-Frame-Options:SAMEORIGIN
     X-XSS-Protection:1; mode=block
    

    此时,使用浏览器访问页面时,图片可以正常呈现。

  4. 修改$CATALINA_BASE/conf/web.xml,恢复X-Content-Type-Options特性

     <filter>
         <filter-name>httpHeaderSecurity</filter-name>
         <filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
         <async-supported>true</async-supported>           
     </filter>
    

    修改GetPictureServlet类的实现,写入图片流前先设置HTTP响应头部Content-Type,取值为image/png

     resp.setHeader("Content-Type", "image/png");
    

    使用浏览器的调试面板观察Tomcat响应浏览器请求时的HTTP头部

     Cache-Control:private
     Content-Length:5103
     Content-Type:image/png
     Date:Thu, 05 May 2016 15:38:12 GMT
     Expires:Thu, 01 Jan 1970 08:00:00 CST
     Server:Apache-Coyote/1.1
     Strict-Transport-Security:max-age=30;includeSubDomains
     X-Content-Type-Options:nosniff
     X-Frame-Options:SAMEORIGIN
     X-XSS-Protection:1; mode=block
    

    此时,使用浏览器访问页面时,图片可以正常呈现。

结论

按照减少 MIME 类型的安全风险的介绍,IE的行为受X-Content-Type-Options的影响,如果Web应用没有返回Content-Type,那么IE9、IE11将拒绝加载相关资源。

如果服务器发送响应头 "X-Content-Type-Options: nosniff",则 script 和 styleSheet 元素会拒绝包含错误的 MIME 类型的响应。这是一种安全功能,有助于防止基于 MIME 类型混淆的攻击。

从前述的测试结果看,的确证实了X-Content-Type-Options对IE9、IE11的影响。

但仍有不明之事,文章减少 MIME 类型的安全风险只提到了scriptstylesheet标签,没有提到img标签,不了解为什么X-Content-Type-Options对图片的加载也会产生影响。后来使用Windows 10的Edge做验证,发现Edge也存在相同的问题,只要启用了X-Content-Type-Options,那么图片必定呈现不出来。Jackie猜,这也许是文档太旧了,或者是Jackie没有找到最新的文档。

另外按照Jerry Qu的文章一些安全相关的HTTP响应头的描述,X-Content-Type-Options应该会影响Chrome的行为,但从测试结果看,使用img标签加载图片时,如果Web应用没有返回Content-Type,无论是否启用X-Content-Type-Options,Chrome都可以正常呈现图片,这一点比较奇怪。文章来源地址https://www.toymoban.com/news/detail-764968.html

参考资料

  • 一些安全相关的HTTP响应头
  • header的安全配置指南
  • ZT header的安全配置指南
  • 减少 MIME 类型的安全风险

到了这里,关于HTTP协议安全头部X-Content-Type-Options引入的问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 关于允许TRACE方法,HTTP X-XSS-Protection缺失,HTTP Content-Security-Policy缺失,X-Frame-Options Header未配置安全处理方法

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 基于Apache Web服务器对一下发现的安全问题进行配置处理,包含允许TRACE方法,HTTP X-XSS-Protection缺失,HTTP Content-Security-Policy缺失,X-Frame-Options Header未配置,HTTP X-Download-Options缺失,HTTP X-Content-Type-Options缺失,HTTP

    2024年02月07日
    浏览(31)
  • http中的Content-Type类型

    最近在做web端下载的时候需要给前端返回一个二进制的流,需要在请求头中设置一个 那么http中的Content-Type有具体有哪些呢?他们具体的使用场景又是怎样的呢? MediaType,即是Internet Media Type,互联网媒体类型;也叫做MIME类型,在Http协议消息头中,使用Content-Type来表示具体请

    2024年02月06日
    浏览(43)
  • 详解Http的Content-Type

    目录 1.概述 2.常用类型 2.1.application/x-www-form-urllencoded 2.2.application/json 3.Spring MVC支持的编码 3.1.实验 3.2.适配器 3.3.自定义适配器 HTTP(HyperText Transfer Protocol),超文本传输协议。超文本(Hypertext)是一种结构化的文本,其中包含了超链接(Hyperlink)的能力,通过超链接可以在不

    2024年02月09日
    浏览(29)
  • Http请求中的Content-Type

    前阵子公司接回了一个旧的项目,刚开始的时候没有注意看前端设置的content-type,然后与后端同事进行接口联调的时候就,有时候发现数据就是对不上,后面看了一下代码中的axios请求相关设置,才发现是自己走坑了!主要是在请求拦截和响应拦截这块的处理,请求拦截这块

    2024年02月12日
    浏览(69)
  • Http Content-type 对照表

    文件扩展名 Content-Type(Mime-Type) 文件扩展名 Content-Type(Mime-Type) .*( 二进制流,不知道下载文件类型) application/octet-stream .tif image/tiff .001 application/x-001 .301 application/x-301 .323 text/h323 .906 application/x-906 .907 drawing/907 .a11 application/x-a11 .acp audio/x-mei-aac .ai application/postscript .aif audio/aiff

    2024年02月09日
    浏览(31)
  • HTTP的Content-type 和 responseType

    后端返回字节流,前端进行图片下载时遇到了问题,定位花了不少时间,本文再次记录梳理下  XMLHttpRequest本身支持responseType 允许我们手动的设置返回数据的类型 \\\'\\\' responseType 为空字符串时,采用默认类型 DOMString,与设置为 text 相同。 arraybuffer response 是一个包含二进制数据的

    2024年01月22日
    浏览(28)
  • HTPP入门教程||HTTP 状态码||HTTP content-type

    当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含 HTTP 状态码的信息头(server header)用以响应浏览器的请求。 HTTP 状态码的英文为  HTTP Status Code 。。 下面是常见的 HTTP 状态码: 200

    2024年02月16日
    浏览(35)
  • HTTP content-type内容类型的常见格式

    本专栏是汇集了一些HTML常常被遗忘的知识,这里算是温故而知新,往往这些零碎的知识点,在你开发中能起到炸惊效果。我们每个人都没有过目不忘,过久不忘的本事,就让这一点点知识慢慢渗透你的脑海。 本专栏的风格是力求简洁明了。 Content-Type(内容类型),一般是指

    2024年02月04日
    浏览(47)
  • HTTP请求头响应头的Content-type和Response Type是什么?

    写代码写着写着发现这些HTTP的概念还不清楚,缕一缕。 根据MDN的解释 Content-Type 实体头部用于指示资源的 MIME 类型 MIME 类型,即媒体类型,是一种标准,用来表示文档、文件或字节流的性质和格式。 根据MDN的解释: response.type的值可以是: basic 标准值,同源响应 cors 接收到一

    2024年02月15日
    浏览(39)
  • http请求头Content-Type的值为text/plain报错415解决方案

    问题描述:http请求报错415,经过了解主要是请求头Content-Type的值为text/plain,为了方便演示,创建一个测试类 测试类 如果请求的请求头是text/plain,则会报错,错误码415 具体报错 解决方案很简单,直接用字符串接收参数就行,示例代码

    2024年02月15日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包