add idea + example of how to bypass SOP w/o CORS

This commit is contained in:
Niko Lockenvitz 2020-06-19 00:06:56 +02:00
parent ddf6f8dbff
commit 97dc0b1b52
No known key found for this signature in database
GPG key ID: 9403BD1956FFF190
2 changed files with 79 additions and 0 deletions

View file

@ -87,6 +87,10 @@ Our first proposal is as follows:
```` ````
You can find an example file and a command line interface to create and edit such files in the [cli folder of this repository](cli). You can find an example file and a command line interface to create and edit such files in the [cli folder of this repository](cli).
Such files can be either loaded as a local file or from a URL.
The latter one can easily be done if CORS headers are present but it might be that not everyone is able to configure this (e.g. static file server).
See [no-cors.md](no-cors.md) for ideas how Same-origin policy can be bypassed without CORS.
### Internal Storing of Decks, Cards and Learning Progress ### Internal Storing of Decks, Cards and Learning Progress
````json ````json
{ {

75
no-cors.md Normal file
View file

@ -0,0 +1,75 @@
# Bypassing Same-origin policy without CORS
For loading decks from external files it is necessary to bypass SOP.
It's not guarenteed that all sites can send CORS headers.
Thus we need another way which works by adjusting the content / file format and not by configuring the server.
## Proxy
Obviously one could setup a server that receives a file URL, reads the corresponding data, adds CORS headers and returns the data.
But the disadvantage is that this requires deploying a server which can handle enough requests.
That would also make our app vulnerable to (D)DoS attacks in some way.
Of course one could also use existing services but then you have to rely on others which should be avoided as much as possible.
## JSONP
One shortly evaluated way of circumventing SOP was to use JSONP.
That means that a `script`-tag is added dynamically that invokes an external JavaScript file.
This JavaScript file could then call a function and pass the JSON data.
It worked to send data from an external site but it also leads to a critical security vulnerability since any code could be injected and not only the desired function call which passes some JSON data.
## iframe and Window.postMessage()
**TODO**: some general introduction
External site which offers decks:
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
</head>
<body>
<!-- e.g. some content to promote the file which is served from this website -->
<script>
const data = { "meta": "...", "decks": "..." };
function receiveMessage(event)
{
window.parent.postMessage(JSON.stringify(data), event.origin);
}
window.addEventListener("message", receiveMessage, false);
</script>
</body>
</html>
```
Loading data:
```js
const EXTERNAL_URL = "https://nikolockenvitz.de/ffc/postmessagetest.html";
const iframe = document.createElement("iframe");
iframe.style.display = "none";
iframe.src = EXTERNAL_URL;
iframe.sandbox = "allow-scripts allow-same-origin";
document.body.appendChild(iframe);
function receiveMessage(event) {
// event.origin needs to be checked
// event.data contains the data, e.g. stringified JSON
console.log(event);
}
window.addEventListener("message", receiveMessage, false);
iframe.contentWindow.postMessage("get fancy decks", EXTERNAL_URL)
```
The security of this approach should be investigated further but at the first look it seems ok.
## Sources
* https://stackoverflow.com/questions/3076414/ways-to-circumvent-the-same-origin-policy
* https://www.w3schools.com/js/js_json_jsonp.asp
* https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe