Original address: http://www.jackieathome.net/archives/369.html?Utm_source=tuicool&utm_medium=referral
Some time ago, testing MM feedback a problem, uploaded images in rich text editor can not be properly rendered. Because Jackie did not observe similar phenomena in the local environment, and just that day an important component of the test environment was corrected, Jackie naturally classified it as a problem of incorrect introduction of configuration items. However, after modifying the configuration items of the test environment, the phenomenon that the pictures in the test feedback rich text editor can not be presented still exists.
This is a bit of trouble, the problem was found the night before the release was launched, if the problem can not be dealt with as soon as possible, it is bound to have an impact on the release of the next day. Although it is necessary to work overtime until late at night when going online, Jackie can't let the problem hang in his hands.
Time is urgent and the problem is bizarre. Jackie immediately put down the work at hand and devoted himself to the analysis work.
Troubleshooting process
- As mentioned earlier, the problem still exists after the configuration item is correctly modified, so the possibility of introducing the problem into the configuration item is excluded first.
-
Please test MM to help reproduce the problem. After careful observation, we find that different browsers can observe different phenomena when accessing the problem page.
- When using Chrome to access pages, images in rich text editors can be rendered normally.
- When accessing pages with IE9 and IE11, images in rich text editors cannot be rendered. From the view of browser's rendering effect, it seems that the image loading failed; but when viewing the loading of page resources in the debugger's network panel, we can observe that the browser initiated the request for image acquisition, and the Web application did return the image information; but it did not show up.
- Copy the URL of the picture in the rich text editor directly and paste it into the browser's address bar for access. The picture can be rendered normally.
- Comparing the production environment and experience environment, we use IE9 and IE11 to access the two environments and view the pictures in rich text editor without observing the aforementioned problems. Therefore, we can judge that the problems found in the test environment by testing MM were introduced recently, and the time range is not more than 2 weeks, because the project team has already switched to the rhythm of two-week iteration.
- Checking the submission records of rich text editors'related codes shows that the latest submission records were a few months ago, so the problem of rich text editors' own codes can be basically eliminated.
- What about the swelling? It seems to have reached a dead end. It seems that the conventional methods are ineffective, only one by one code to submit records.
Fortunately, the submission records were scanned by Jackie within 10 minutes; most of the submission records were innocent, and the only suspicious submission records came from Jackie himself. Sure enough, Jackie could only locate and analyze the problem. To address the warning in AppScan's report that "HTTP response lacks security headers", Jackie modified Tomcat's configuration on the morning of finding the problem, added filters related to security headers, and stayed in the office overtime at night to confirm that the warning had been eliminated.
In order to confirm the correlation between the above problems and HTTP security headers, Jackie manually modified the configuration of Tomcat in the test environment, removed the filter that added security headers, and tried to reproduce the problem after restarting Tomcat. It was surprising to find that the images in the rich text editor returned to normal presentation, which showed that HTTP response had an impact on the basic functions after adding security headers.
The following security headers are currently enabled for HTTP protocol:
- Strict-Transport-Security
- X-Frame-Options
- X-Content-Type-Options
- X-XSS-Protection
Scope is relatively small. After checking one by one, it is found that the aforementioned problems are related to X-Content-Type-Options. Therefore, it is decided to still enable the output of HTTP security headers, but to disable X-Content-Type-Options, the images in the rich text editor can be rendered normally without significant impact on security.
Originally, I thought it was irrelevant to modify Tomcat's configuration and business. There would be no problems or basic functions. As a result, it failed to meet people's expectations. It really made testing MM find a weird problem. It seems that lucky mentality can not exist, the work should not be saved, otherwise we have to work overtime, double back.
The following is a minimum of sample code to illustrate how the problem occurred.
How did the problem happen?
Prepare to recreate the environment
jsp page
<%@ 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>
Implementation of GetPicture
There is a problem with the implementation of the following code. Content-Type is not explicitly specified when data is returned by stream.
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>
Use browser to observe
Review Some security-related HTTP response headers Introduction to X-Content-Type-Options.
There are various types of resources on the Internet, and browsers typically identify them based on the Content-Type field of the response header. For example, "text/html" stands for HTML documents, "image/png" is a PNG picture, "text/css" is a CSS style document. However, the Content-Type of some resources is wrong or undefined. At this point, some browsers will enable MIME-sniffing to guess the type of the resource, parse the content and execute.
Use the browser debugging panel to observe the HTTP response head and verify the above.
-
When HttpHeader Security Filter is not enabled, the head of the HTTP response is as follows
Content-Length:5103 Date:Mon, 02 May 2016 05:07:22 GMT Server:Apache-Coyote/1.1
-
Modify $CATALINA_BASE/conf/web.xml to enable HttpHeader Security Filter
<filter> <filter-name>httpHeaderSecurity</filter-name> <filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class> <async-supported>true</async-supported> </filter>
Use the browser's debugging panel to observe Tomcat's HTTP header in response to browser requests
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
At this point, when using the browser to access the page, the picture can not be rendered properly.
-
Modify $CATALINA_BASE/conf/web.xml to disable the X-Content-Type-Options feature
<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>
Use the browser's debugging panel to observe Tomcat's HTTP header in response to browser requests
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
At this point, when using the browser to access the page, the picture can be rendered normally.
-
Modify $CATALINA_BASE/conf/web.xml to restore the X-Content-Type-Options feature
<filter> <filter-name>httpHeaderSecurity</filter-name> <filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class> <async-supported>true</async-supported> </filter>
Modify the implementation of GetPictureServlet class, set the HTTP response header Content-Type before writing to the image stream, and take the value image/png
resp.setHeader("Content-Type", "image/png");
Use the browser's debugging panel to observe Tomcat's HTTP header in response to browser requests
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
At this point, when using the browser to access the page, the picture can be rendered normally.
conclusion
according to Reducing MIME-type security risks IE behavior is influenced by X-Content-Type-Options. If Web applications do not return Content-Type, IE9 and IE11 will refuse to load related resources.
If the server sends the response header "X-Content-Type-Options: nosniff", script and styleSheet elements reject the MIME-type response that contains the error. This is a security feature that helps prevent attacks based on MIME type obfuscation.
From the above test results, it is confirmed that X-Content-Type-Options has an impact on IE9 and IE11.
But there is still something unknown, the article Reducing MIME-type security risks Only script and stylesheet tags were mentioned, and img tags were not mentioned. It was not clear why X-Content-Type-Options also had an impact on image loading. Later, Windows was used. 10 Edge validation found that Edge also has the same problem, as long as X-Content-Type-Options is enabled, then the picture must not appear. Jackie guessed that it might be that the document was too old, or that Jackie had not found the latest document.
In addition, according to Jerry Qu Articles Some security-related HTTP response headers Description, X-Content-Type-Options should affect the behavior of Chrome, but from the test results, it is strange that when loading images with img tags, Chrome can normally render images if the Web application does not return Content-Type, regardless of whether X-Content-Type-Options is enabled or not.