Konubinix' opinionated web of thoughts

Cross-Origin Resource Sharing

Fleeting

CORS (Cross-Origin Resource Sharing) is a system, consisting of transmitting HTTP headers, that determines whether browsers block frontend JavaScript code from accessing responses for cross-origin requests

https://developer.mozilla.org/en-US/docs/Glossary/CORS

preflight request

CORS preflight request is a CORS request that checks to see if the CORS protocol is understood and a server is aware using specific methods and headers

https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request

It is an OPTIONS request, using three HTTP request headers:

  1. Access-Control-Request-Method,
  2. Access-Control-Request-Headers,
  3. and the Origin header.

https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request

simple request

When providing the origin header, the server automatically returns the access-control-allow-XXXX headers and the browser won’t deal with the data in that case in the cors data is wrong.

is it run once for the whole site or once per requests?

from flask import Flask, request
from flask_cors import CORS

app = Flask(__name__)
CORS(app, resources={r"/*": {"origins": "*"}})


@app.route('/',
           defaults={'path': ''},
           methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'])
@app.route('/<path:path>',
           methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'])
def log_request(path):
    print(f"Request Path: {request.path}")
    print(f"Method: {request.method}")
    print("Headers:")
    for header, value in request.headers.items():
        print(f"  {header}: {value}")
        print(
            f"Body: {request.data.decode('utf-8') if request.data else 'No body'}")
        print("-" * 50)

    return "ok", 200


if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=9999)
clk python ~/bin/test.py

Then, go to https://konubinix.eu (or anywhere that has no CSP configured) and run fetch("http://127.0.0.1:9999/foobar"), then fetch("http://127.0.0.1:9999/barfoo")

You will see

--------------------------------------------------
127.0.0.1 - - [19/Dec/2024 14:29:39] "GET /truc HTTP/1.1" 200 -
Request Path: /foobar
Method: OPTIONS
Headers:
  Host: 127.0.0.1:9999
  Connection: keep-alive
  Accept: */*
  Access-Control-Request-Method: GET
  Access-Control-Request-Private-Network: true
  Origin: https://konubinix.eu
  User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36
  Sec-Fetch-Mode: cors
  Sec-Fetch-Site: cross-site
  Sec-Fetch-Dest: empty
  Accept-Encoding: gzip, deflate, br
  Accept-Language: en-US,en;q=0.9
Body: No body
--------------------------------------------------
127.0.0.1 - - [19/Dec/2024 14:30:55] "OPTIONS /foobar HTTP/1.1" 200 -
Request Path: /foobar
Method: GET
Headers:
  Host: 127.0.0.1:9999
  Connection: keep-alive
  Sec-Ch-Ua: "Not=A?Brand";v="99", "Chromium";v="118"
  Sec-Ch-Ua-Mobile: ?0
  User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36
  Sec-Ch-Ua-Platform: "Linux"
  Accept: */*
  Accept-Language: en-US,en;q=0.9
  Dnt: 1
  Origin: https://konubinix.eu
  Sec-Fetch-Site: cross-site
  Sec-Fetch-Mode: cors
  Sec-Fetch-Dest: empty
  Accept-Encoding: gzip, deflate, br
Body: No body
--------------------------------------------------
127.0.0.1 - - [19/Dec/2024 14:30:55] "GET /foobar HTTP/1.1" 200 -
Request Path: /barfoo
Method: OPTIONS
Headers:
  Host: 127.0.0.1:9999
  Connection: keep-alive
  Accept: */*
  Access-Control-Request-Method: GET
  Access-Control-Request-Private-Network: true
  Origin: https://konubinix.eu
  User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36
  Sec-Fetch-Mode: cors
  Sec-Fetch-Site: cross-site
  Sec-Fetch-Dest: empty
  Accept-Encoding: gzip, deflate, br
  Accept-Language: en-US,en;q=0.9
Body: No body
--------------------------------------------------
127.0.0.1 - - [19/Dec/2024 14:31:23] "OPTIONS /barfoo HTTP/1.1" 200 -
Request Path: /barfoo
Method: GET
Headers:
  Host: 127.0.0.1:9999
  Connection: keep-alive
  Sec-Ch-Ua: "Not=A?Brand";v="99", "Chromium";v="118"
  Sec-Ch-Ua-Mobile: ?0
  User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36
  Sec-Ch-Ua-Platform: "Linux"
  Accept: */*
  Accept-Language: en-US,en;q=0.9
  Dnt: 1
  Origin: https://konubinix.eu
  Sec-Fetch-Site: cross-site
  Sec-Fetch-Mode: cors
  Sec-Fetch-Dest: empty
  Accept-Encoding: gzip, deflate, br
Body: No body
--------------------------------------------------
127.0.0.1 - - [19/Dec/2024 14:31:23] "GET /barfoo HTTP/1.1" 200 -

Showing that it is indeed run once for every request.

Notes linking here