Cross domain interpretation
What is cross domain
When any of the protocol, domain name and port of a request url is different from the url of the current page, it is cross domain
Why do cross domain problems occur
Homology policy is an important security policy, which is used to restrict how an origin document or its loaded script can interact with resources from another source. It can help block malicious documents and reduce the media that may be attacked. The same origin policy of the browser leads to cross domain, but the solution can be solved from the front to the back
Two dangerous scenarios without restriction of homology strategy
Interface requests without homology policy restrictions
On CSRF attack mode: Cross Station Request Forgery
CSRF attack principle
As can be seen from the above figure, to complete a CSRF attack, the victim must complete two steps in turn:
- Log in to trusted website A and generate cookies locally.
- Visit dangerous website B without logging out of A.
Dom query without homology policy restriction
It's website forgery
The bank website you usually visit is www.yinhang.com COM, and now visit www.yinghang.com com,www.yinghang. What does this phishing website do?
// HTML <iframe name="yinhang" src="www.yinhang.com"></iframe> // JS // Since there is no restriction of homology strategy, phishing websites can directly get the Dom of other websites const iframe = window.frames['yinhang'] const node = iframe.document.getElementById('You enter the account password Input') console.log(`Got this ${node},Can't I get the account password you just entered`)
Cross domain solutions
CORS
CORS is the abbreviation of cross origin resource sharing. It is the W3C standard and belongs to the fundamental solution of cross source AJAX requests.
- Common cross domain request: only set access control allow origin on the server side
- Cross domain request with cookie: both front and back ends need to be set
[front end setting] according to XHR The withcredentials field determines whether there is a cookie
Native Ajax (common cross domain requests do not need to be set)
var xhr = new XMLHttpRequest(); // IE8/9 needs window Xdomainrequest compatible // Front end setting whether to bring cookie s xhr.withCredentials = true; xhr.open('post', 'http://www.domain2.com:8080/login', true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.send('user=admin'); xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { alert(xhr.responseText); } };
[server settings]
/* * Import package: import javax servlet. http. HttpServletResponse; * Interface parameters: httpservletresponse */ // Domain name that allows cross domain access: if there is a port, write it all (protocol + domain name + port). If there is no port, don't add '/' at the end response.setHeader("Access-Control-Allow-Origin", "http://www.domain1.com"); // Allow authentication cookie s on the front end: after this option is enabled, the domain name above cannot be '*', you must specify a specific domain name, otherwise the browser will prompt response.setHeader("Access-Control-Allow-Credentials", "true"); // Two common custom headers that need to be set at the back end when prompting OPTIONS pre check response.setHeader("Access-Control-Allow-Headers", "Content-Type,X-Requested-With");
nginx agent
nginx configuration
server{ # Listen to port 9099 listen 9099; # The domain name is localhost server_name localhost; #Anything like localhost:9099/api will be forwarded to the real server address http://localhost:9871 location ^~ /api { proxy_pass http://localhost:9871; } }
Front end request http://localhost:9099/ Then nginx will forward the request to http://localhost:9871 ,
Request forwarding through Java or jsp
Because the cross domain problem is caused by the browser, you can use Java or jsp to request the cross domain interface by accessing the Java or jsp of the server,
Case: post jsp
<%@ page import="java.io.PrintWriter" %> <%@ page import="java.io.BufferedReader" %> <%@ page import="java.io.IOException" %> <%@ page import="java.io.InputStreamReader" %> <%@ page import="java.net.ConnectException" %> <%@ page import="java.net.HttpURLConnection" %> <%@ page import="java.net.URL" %> <%@ page import="java.util.Map" %> <%@ page import="java.net.URLEncoder" %> <%@ page contentType="text/html;charset=UTF-8" %> <%! public class InternetModule { public String getJson(String str) { System.out.println(str); StringBuffer json = new StringBuffer(); HttpURLConnection conn = null; try { URL url = new URL(str); conn = (HttpURLConnection) url.openConnection(); conn.setRequestProperty("Content-Type", "text/xml; charset=utf-8"); conn.setRequestMethod("GET"); conn.setUseCaches(false); conn.setDoInput(true); conn.setDoOutput(true); conn.setConnectTimeout(30000); conn.connect(); BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8")); String temp; while ((temp = br.readLine()) != null) { json.append(temp); } br.close(); } catch (ConnectException e) { System.out.println("Error getting data online,url:" + str); e.printStackTrace(); return e.getMessage(); } catch (IOException e) { System.out.println("networking I/O error"); e.printStackTrace(); return e.getMessage(); } finally { conn.disconnect(); } return json.toString(); } } %> <% String url = "http://116.210.254.90:8080/"; String keyAndSp = "?apikey=123456&secretkey=123456&sp=dianxin"; String apiUrl = request.getParameter("apiUrl"); String userId = request.getParameter("userId"); InternetModule im = new InternetModule(); String json = null; if ("api/GetHotVodRecommends".equals(apiUrl)) { String type = request.getParameter("type"); json = im.getJson(url + apiUrl + keyAndSp + "&size=5&userId=" + userId + "&type=" + type); } else if ("user/GetSearchLog".equals(apiUrl)) { String size = request.getParameter("size"); json = im.getJson(url + apiUrl + keyAndSp + "&userId=" + userId + "&size=" + size); } else if ("api/GetSearch".equals(apiUrl)) { String key = request.getParameter("key"); String word = request.getParameter("word"); word = URLEncoder.encode(word,"UTF-8"); String actor = request.getParameter("actor"); actor = URLEncoder.encode(actor,"UTF-8"); String page1 = request.getParameter("page"); String pageSize = request.getParameter("pageSize"); json = im.getJson(url + apiUrl + keyAndSp + "&userId=" + userId + "&key=" + key + "&word=" + word + "&actor=" + actor + "&page=" + page1 + "&pageSize=" + pageSize); } else if ("user/DeleteSearchLog".equals(apiUrl)) { json = im.getJson(url + apiUrl + keyAndSp + "&userId=" + userId); } else if ("user/PutSearchLog".equals(apiUrl)) { String assetId = request.getParameter("assetId"); String cpid = request.getParameter("cpid"); String name = request.getParameter("name"); name = URLEncoder.encode(name,"UTF-8"); json = im.getJson(url + apiUrl + keyAndSp + "&userId=" + userId + "&assetId=" + assetId + "&cpid=" + cpid + "&name=" + name); } else if ("api/GetHotVodRecommendsAll".equals(apiUrl)){ String size = request.getParameter("size"); json = im.getJson(url + apiUrl + keyAndSp + "&userId=" + userId + "&size=" + size); } response.setHeader("Content-Type", "application/json;charset=UTF-8"); out.println(json); %>
The following two methods are not understood. Please refer to the following two links
JSONP and cross document communication API: window postMessage()
Pit encountered across domains
Because we do set-top box pages, we will adapt all kinds of set-top boxes. When adapting set-top boxes, three boxes will display exceptions when initializing the page, because the interface data will be requested when initializing the page, and the interface is not deployed to the same server. At that time, colleagues thought it might be caused by cross domain, but the page initialization is partially successful and partially failed, So at that time, I felt that if it involved cross domain, all of them should fail. Later, after looking at the content of the packet capture, our director found that one of the multiple requests returned the header information that allowed cross domain. Some did not return, the returned information would be displayed normally, and those that did not return would fail, because all of our cross domain problems were set on the server side, Therefore, this misleads us. We can still have this operation. Some of the multiple requests of the same interface return the allowed cross domain header, some do not return, and some encounter it. Even if they return, they are not displayed normally, because it is different from the cross domain header information that can be displayed normally
Cross domain header information normally displayed
HTTP/1.1 200 OK Server: nginx Date: Thu, 29 Apr 2021 03:18:47 GMT Content-Type: application/json; charset=UTF-8 Content-Length: 624 Connection: keep-alive Access-Control-Allow-Credentials: true Access-Control-Allow-Headers: access-control-allow-origin, access-control-allow-headers, Accept-Encoding, X-Real-Ip, Connection, Pragma, Cache-Control, User-Agent, Accept, Referer, Accept-Language, X-Forwarded-For, Origin, X-Requested-With Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE Access-Control-Allow-Origin: * Access-Control-Expose-Headers: Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type X-Frame-Options: SAMEORIGIN
Failed cross domain header information
HTTP/1.1 200 OK Server: nginx Date: Thu, 29 Apr 2021 02:27:05 GMT Content-Type: application/json; charset=UTF-8 Content-Length: 624 Connection: keep-alive Access-Control-Allow-Credentials: true Access-Control-Allow-Headers: access-control-allow-origin, access-control-allow-headers, Accept-Encoding, Accept-Language, Connection, Origin, User-Agent, Referer Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE Access-Control-Allow-Origin: * Access-Control-Expose-Headers: Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type X-Frame-Options: SAMEORIGIN Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET,POST Access-Control-Allow-Headers: DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization
Through the comparison tool, we can see that there are differences between the two. The specific reason why the first one can and the second can't is not found
reference resources: https://blog.csdn.net/qq_38128179/article/details/84956552
https://segmentfault.com/a/1190000015597029