preface
I am participating in the 2022 Spring Recruitment series – experience review, click here for more details.
A few days ago, dasmarty’s three-year-old app was scanned for a vulnerability, Thought to increase the X – the content-type head can perfectly solve the Options security vulnerabilities (see great wisdom to teach you to learn Java | Spring Boot project set X – the content-type – Options response headers), wildest dreams, Since x-Content-type-options has been added to nosniffing headers, there has been a major problem.
A bumpy road to resolution
Problem description and cause
In your application, you have a page where you need to make an Ajax call to the interface in the background to get the data (jSONP is used in Ajax to solve the cross-domain problem because cross-domain is involved in production), But adding the X-Content-Type-options response header caused Ajax to fail. X-content-type-options: nosniffing problem with response headers (since there have been major problems since the addition of response headers) ๐
$(document).ready(function(){
console.log("Begin the request.");
$.ajax({
url:"http://localhost:8081/searchweb/search/hotWord",
type : 'get',
cache : false,
async : true,
dataType : "jsonp",
timeout:30000,
jsonpCallback:"callback",
processdata:false,
data:{
siteid:"97",
},
success: function(jsonData){
console.log("Request successful");
console.log("jsonData:"+jsonData);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
console.log("Status code:+XMLHttpRequest.status);/ / status code
console.log("State:"+XMLHttpRequest.readyState);/ / state
console.log(Error message:+textStatus);// Error message}}); })Copy the code
@RequestMapping(value = "/search/hotWord", method = RequestMethod.GET ,produces="application/json; charset=UTF-8,text/html; charset=UTF-8")
@ResponseBody
public JSONPObject hotWord(HttpServletRequest request, HttpServletResponse response, @RequestParam int siteid, @RequestParam String callback){
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
if(siteid == 97){
list = searchService.listHotWords(0);
Map<String, String> map = new HashMap<String, String>();
for(int i = 1; i <=4; i++ ){ map.put("word_"+i, (String) list.get(i).get("words"));
}
System.out.println("map --->"+JSON.toJSONString(map));
return new JSONPObject(callback, map);
}else{
list = searchService.listHotWords(5);
Map<String, String> map = new HashMap<String, String>();
for(int i = 1; i <=4; i++ ){ map.put("word_"+i, (String) list.get(i).get("words"));
}
return newJSONPObject(callback, map); }}Copy the code
As expected, x-Content-Type-options: Nosniffing header has been added, leading to the above problems. Later, Baidu found the root cause of the problem ๐
- If a “Nosniff” command is received in the response retrieved from the styleSheet reference, Windows Internet Explorer will not load a “styleSheet” file unless the MIME type matches “text/ CSS “.
- If a “Nosniffing” instruction is received in a response retrieved through a Script reference, Internet Explorer will not load a “script” file unless the MIME type matches one of the following nine values: “Application/ecMAScript” “Application /javascript” “Application /x-javascript” “Text/ecMAScript” “text/javascript” “text/j Script “, “text/x-javascript”, “text/ VBS “, “text/vbscript”
Now that the root cause of the problem is known, let’s begin to solve it ๐ช
solution
As the saying goes, “Trivial problems have a creepy solution”, we can use a most “creepy” method to solve this problem, delete x-Content-Type-options: nosniff response header, obviously this method is not feasible, everyone friends as a joke look at the line ๐
If the content-type value is application/json, it will not match any of the nine values listed above. Replace it with a value that meets the requirements of the project and satisfies one of the above nine types. For the above interface, the return value of the interface does not have to be in Json format. The return value of the interface can also be a String, so we can use text/javascript instead of application/ Json. Let’s look at the error message thrown by the browser: Callback was not called; callback was not called; Jsonp callback was not called; Jsonp callback was not called. Jsonp: Jsonp: Jsonp: Jsonp: Jsonp: Jsonp: Jsonp: Jsonp: Jsonp: Jsonp: Jsonp: Jsonp: Jsonp: Jsonp: Jsonp: Jsonp: Jsonp: Jsonp: Jsonp: Jsonp: Jsonp: Jsonp: Jsonp: Jsonp: Jsonp: Jsonp: Jsonp: Jsonp: Jsonp This brings us to the final step of solving the problem – add a line of code to the interface to solve the cross-domain problem: response.setheader (” access-Control-allow-origin “, “*”).
The complete code
โ we can’t load because of adding security header X-content-type-options. โ -we have fun. ๐
$(document).ready(function(){
console.log("Begin the request.");
$.ajax({
url:"http://localhost:8081/searchweb/search/hotWord",
type : 'get',
cache : false,
async : true,
dataType : "json",
timeout:30000,
data:{
siteid:"97",
},
success: function(jsonData){
console.log("Request successful");
console.log("jsonData:"+jsonData);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
console.log("Status code:+XMLHttpRequest.status);/ / status code
console.log("State:"+XMLHttpRequest.readyState);/ / state
console.log(Error message:+textStatus);// Error message}}); })Copy the code
@RequestMapping(value = "/search/hotWord", method = RequestMethod.GET ,produces = "text/javascript; charset=UTF-8")
@ResponseBody
public Object hotWord(HttpServletRequest request, HttpServletResponse response, @RequestParam int siteid){
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
if(siteid == 97){
list = searchService.listHotWords(0);
Map<String, String> map = new HashMap<String, String>();
for(int i = 1; i <=4; i++ ){ map.put("word_"+i, (String) list.get(i).get("words"));
}
response.setHeader("Access-Control-Allow-Origin"."*"); // Allow cross-domain requests
return JSON.toJSONString(map);
}else{
list = searchService.listHotWords(5);
Map<String, String> map = new HashMap<String, String>();
for(int i = 1; i <=4; i++ ){ map.put("word_"+i, (String) list.get(i).get("words"));
}
returnJSON.toJSONString(map); }}Copy the code
summary
My experience is limited, some places may not be particularly in place, if you think of any questions when reading, welcome to leave a message in the comments section, we will discuss one by one ๐
Please take a thumbs up and a follow (โฟโกโฟโก) for this article ~ a crab (โ’โก’โ)
If there are mistakes in the article, welcome to comment correction; If you have a better, more unique understanding, you are welcome to leave your valuable ideas in the comments area.
Love what you love, do what you do, listen to your heart and ask nothing