0% found this document useful (0 votes)
21 views16 pages

Understanding Cross-Origin Issues and Solutions

Uploaded by

杜韦萱
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
21 views16 pages

Understanding Cross-Origin Issues and Solutions

Uploaded by

杜韦萱
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Same-origin policy & Cross-Origin Issues

Origin & Cross Origin


Cross Origin
Cross Origin in Network
Restriction
Solutions

1. Cross-Origin Resource Sharing (CORS)

Request Classification
Exercise
Check
Detail 1 - cookie
Detail 2 - Get Cross Origin Response Header
2. JSONP

3. Proxy

Making Choice
1. Production environment cross origin, development environment cross origin.

2. Production environemnt doesn't cross origin.

Same-origin policy & Cross-Origin Issues


Cross Origin Issue only exists in browsers.

same origin policy: a security measure to restrict the network interaction of resource (script/
documents) between two different origin.

same origin: allowed


cross origin: restricted.

the degree of restriction might vary based on case.

fetch('[Link] => [Link]()).then(body => {con


Origin & Cross Origin
origin = protocol + host name + port

// Example 1
[Link]

origin: [Link]

// Example 2
[Link]

origin: [Link]

comparison between two urls:

when two url is not same, they are deemed to be crossed origin.
note: path is not our concern.

Cross Origin
different situation, different way, different restriction.

situations:

1. network communication
redirection of a tag, loading of js, css, img, etc, AJAX , ...
// page url
[Link]/

// scritp element
<script src="url1">

// a tag
<a href="url2">

// link element
<link href="url3">

// img
<img src="url4" alt="">

Note: when the origin of the page url !== origins of url1/ url2/ url3/ url4 => cross origin

2. JS API

[Link]
[Link]
[Link]

3. Storage

WebStorage: localStorage, sessionStorage


IndexedDB,...

This note focus on cross-origin problem in AJAX.

Cross Origin in Network


page origin - url of the page

target origin (other url) - request sent by the page

page origin === target origin => same origin request, otherwise cross origin request.
Restriction
restriction is different.

usually,

1. lightly restriction in sending requests to the url of the element tag.


2. strictly restriction in the request sent by AJAX.

How to check cross origin?

request and response as usual.


check happens in browser internal based on response.

Solutions

1. Cross-Origin Resource Sharing (CORS)


1. if server agrees, check passed.
2. if server declines, check failed.

Note: solving cross origin issue with CORS, the server must be our own people.
Request Classification
1. Simple Request

a. request methods must be one of these: GET, POST, HEAD


b. request header must be CORS-satisfied.

browser default headers fulfill the requirement, as long as we don't touch it.

c. if header contains Content-Type can be any of these:

text/plain
multipart/form-data
application/x-www-form-urlencoded

2. Preflighted Request
Exercise

1. fetch('[Link]
- simple request

2. fetch('[Link] {
headers: {
a: 1,
},
});
- preflighted

3. fetch('[Link] {
method: 'POST',
body: [Link]({a: 1, b: 2}),
});
- simple
- Note: if use third-party library (axious): preflight
- reason: axious will add content-type to header based on request body.
- e.g., [Link](url, {xxx})
- headers: {'content-type': 'application/json'}

4. fetch('[Link] {
method: 'POST',
header: {
'content-type': 'application/json',
},
body: [Link]({a: 1, b: 2}),
})

5. upload file
- simple - if upload format is binary data
- preflighted - if upload format is application/json

Check
1. simple request

Origin: [Link]

server can allow the passing of the origin by adding a response header with origin url as value.

Access-Control-Allow-Origin:origin
or

* means anything shall pass.

Access-Control-Allow-Origin:*

Note: not recommended usign * .

// Example Backend Code


// Access-Control-Allow-Origin can be controlled by backend program.
const origin = [Link]('Origin')
[Link]('acc...', origin);

2. preflight request

sending two requests.

a. sending preflight request

request headers and response headers must match to pass.


Note: preflight request method is OPTION.
Access-Control-Max-Age : the verification last for how long.
b. sending real request (similar to simple request)

Detail 1 - cookie

by default, AJAX cross origin request won't attach cookie.


Thus, some authorization operation can't perform.

set cookie manually:

// xhr
var xhr = new XMLHttpRequest();
[Link] = true;

// fethc api
fetch(url, {
credentials: "include"
});

Note:

which cookies to bring depends on its rules, which is constantly updating.


cookie + session mode is very widespread.
especially in big tech company
e.g., single sign on
request attaches with cookie must add cookie to the request header.

when server response, it must tell the client in the response header:

// server side
// response header
Access-Control-Allow-Credentials: true

If not, browser might treat it as cross-origin and fail.

Importance:

with credential request, server can't set Access-Control-Allow-Origin value to * . That's why it is
discouraged to use * .
If the above detail can't solve the problem, it might be due to cookies itself.

Detail 2 - Get Cross Origin Response Header

cross origin access, js can only get some basic response headers.
Cache-control
Content-Language
Content-Type
Expires
Last-Modified
Pragma
otherwise, require server to explicitly set the response header.

// Example:
Access-Control-Expose-Headers: authorization, a, b

// how js get the header


[Link]([Link]('authorization'))

Note: without this, js can't get certain info from the response header, despite the header is available on
the network tab of the dev tool.

2. JSONP
appears before CORS.
server must be own people.

Why learn?

1. for old project


Note: choosing a technology depends on the cost

current cost (maintenance)


future cost (maintenance)
technology is one of the factors affecting cost.

2. just learn.
How JSONP solves CORS error?

element tag is not as strictly restricted as making a AJAX request.

let server sends back a callback.

the code is executed immediately.

html:
<!--Example: theory

parsing script send out request, and server send back a function call callback(xxx).

js code execute immediately.


-->
<script src="[Link]

<!--Example 2: optimised JSONP request-->


<script>
// might consider passing second parameter and add to query
function request(url) {
return new Promise(resolve => {// consider success, not yet consider failure
const cbName = '__callback__' + [Link]().toString(36).substring(2) + '_' + [Link]
[Link](cbName);
window[cbName]= function (resp) {
delete window[cbName]; // remove callback name
[Link](); // remove element when getting result - no polluting element.
resolve(resp);
};
const script = [Link]('script'); // create a script
[Link] = url + '?callback=' + cbName; //TODO: consider case when url already has ?.
[Link](script);
});
}

request('[Link] => {
[Link]('server:', resp);
});
</script>

server:
// jsonp
[Link]('/jsonp', (req, res) => {
const cbname = [Link] || 'callback';
const data = {
msg: 'coming from server',
};
[Link]('content-type', 'application/json');
[Link](`${cbname}(${[Link](data)})`);
});

Weaknesses:

1. only send GET request.


2. pose security threat (XSS attack - callback = malicious function)
3. might be called by malicious site.

Note: unless some special reason, don't use JSONP.

3. Proxy
Note: CORS & JSONP requires server to be own people.

If not?

through a middle man - everyone is own people.

Same Origin Policy only works in browser - outside browser there is no such policy.

write a proxy server - own people forwarding request and getting data.

Note: browser don't know about proxy - target server is transparent to the browser.
send request to proxy:

<script>
fetch('[Link] => {
return [Link]();
}).then(body => {
[Link](body);
});
</script>

proxy server:

[Link]('/hero', async (req, res) => {


const axios = require('axios'); // axios - works in both browser and node environment (adopt b
const resp = await [Link]('[Link]
// use CORS resolving cross origin issue of the proxy server
[Link]('access-control-allow-origin', '*');
[Link]([Link]);
});
Making Choice
production environment & development environment must be same.

old browser - e.g., IE ver.5 / ver.6

Situations:
1. Production environment cross origin, development
environment cross origin.

don't use proxy!


2. Production environemnt doesn't cross origin.

frontend gives resource to Ops, they help deploy.


backend gives resource to Ops, they help deploy.
production environment use nginx as a reverse proxy to get resource - use same origin.
browser can't directly access the menu and data server
nginx helps request resources using pageUrl/**
development environment mimic production environment - use dev server as proxy
goal: ensure the structure is similar in both environment - minimize issue.

page:
dev-server
localhost:8080/
ajax: localhost:8080/api...

data: [Link]/

Common questions

Powered by AI

The primary methods for addressing cross-origin issues in web development include Cross-Origin Resource Sharing (CORS), JSONP, and Proxy servers. CORS involves setting special headers on the response from the server to indicate which origins are permitted to access the resource. If a server agrees, it sends a response with Access-Control-Allow-Origin header to approve the request . JSONP, on the other hand, works by using script tags to make GET requests, allowing a more lenient cross-origin access; the server returns a script that is immediately executed . Proxy servers serve as intermediaries that forward requests from the client to the target server, effectively bypassing the same-origin policy as the browser interacts only with the proxy, not realizing it accesses a cross-origin resource . Unlike CORS or JSONP, proxy servers are not subject to origin restrictions because they operate server-side .

CORS offers a robust solution for modern applications by allowing explicit server-side control over which origins can access resources. It's suitable for securing complex REST APIs but requires proper configuration to avoid exposure . JSONP bypasses strict restrictions by using script tags for GET requests; it's easier to implement for quick fixes but poses significant security risks, making it suitable for older systems where simplicity overrules security concerns . Proxy servers work well in development, offering more flexibility by encapsulating requests, invisible to browsers, and bypassing origin checks altogether; however, they might introduce latency and are less suited for production without careful consideration . Each method has contextual applications, with CORS being the most widely applicable across secure server applications, JSONP in legacy environments, and proxies in testing and development setups where origin policy requires bypassing .

JSONP poses significant security risks as it involves loading scripts into the client’s page, which allows potential XSS attacks if a malicious script is executed . Its usage is generally discouraged in modern applications unless necessary for compatibility with older systems. CORS, while generally safer than JSONP, relies on correctly configuring server-side permissions to grant specific cross-origin requests, potentially exposing vulnerabilities if misconfigured . Developers might choose JSONP for compatibility with older systems or in cases where non-protected GET requests suffice. CORS is preferred when server-side control of permissions is feasible and more comprehensive RESTful interactions are required .

In browser environments, the same-origin policy is enforced as a security measure that restricts interactions such as reading data from different origins to prevent malicious activities like XSS . This necessitates the use of mechanisms like CORS or JSONP to bypass these restrictions safely. However, in non-browser environments, like server-side applications, these restrictions do not apply, enabling developers to handle cross-origin requests without needing CORS for security . Servers can access any origin without the restrictions placed on browser environments, making it feasible to use proxy servers to fetch data from multiple origins without encountering the same-origin constraints .

JSONP has significant limitations that make it less favorable compared to CORS. It only supports GET requests, limiting its applicability to operations that can be executed without modifying resources . JSONP also introduces potential security vulnerabilities, such as cross-site scripting (XSS) attacks by allowing execution of arbitrary scripts returned from servers, which could be exploited by injecting malicious code into the response . Moreover, JSONP exposes the client to possible interception and execution by non-trusted scripts, lacking the selective permission control and robustness provided by CORS. This restricted use, along with modern security standards, often leads developers to prefer CORS when cross-origin requests are necessary .

Preflight requests in CORS are used to determine if the actual request is safe to send across domains. They are triggered when requests don't fulfill the criteria of simple requests: using methods other than GET, POST, or HEAD, or when custom headers and non-standard content types are present . A preflight request uses the OPTIONS method to fetch supported methods and headers from the server, allowing the server to explicitly approve the actual request based on specific criteria like Access-Control-Allow-Headers and Access-Control-Allow-Methods . If the preflight check passes, the real request is sent; otherwise, the customer's browser will abort the transaction .

The Access-Control-Expose-Headers response header determines which headers are safe for JavaScript to access via the XMLHttpRequest or Fetch APIs when a cross-origin request is made . By default, browsers only allow certain simple headers like Cache-Control and Content-Type to be accessible. Access-Control-Expose-Headers allows the server to expose additional headers for the client-side script to read, thus enabling JS access to specific response headers like Authorization, which would otherwise be inaccessible despite being present in the network transmission .

Using a proxy server in development environments allows developers to simulate the same-origin interactions, facilitating testing and debugging by resolving cross-origin barriers without the need to configure CORS headers . In these settings, a proxy server mediates requests between the client and the target server, effectively masking the origin differences. However, in production environments, this approach is less desirable due to increased latency, security considerations, and potential misalignments with the architecture. In production, solutions like CORS or serving resources through a single domain using tools like reverse proxy are preferred for efficiency and security .

The same-origin policy determines a request as cross-origin if the protocol, hostname, or port of the requesting URL differs from that of the resource URL . The path is not considered when determining same-origin status. If a request is cross-origin, browsers impose restrictions on accessing the resource to prevent security vulnerabilities such as data leaks and unauthorized requests. This means resources like AJAX requests, scripts, and media may be blocked unless specific cross-origin permissions are granted via headers like those used in CORS .

Using '*' in the Access-Control-Allow-Origin header allows any origin to access the resource, which can lead to security vulnerabilities by permitting unrestricted access to sensitive resources . This is especially concerning with cookies, as sending cookies in a cross-origin request requires the server to explicitly list the specific origin in the header due to security measures against intercepted credentials. Browsers won't attach cookies or allow access if '*' is used and cookies are involved, thus compromising session security and potentially exposing private data across unauthorized origins .

You might also like