Skip to content

Latest commit

 

History

History
executable file
·
123 lines (99 loc) · 7.14 KB

Browsers.md

File metadata and controls

executable file
·
123 lines (99 loc) · 7.14 KB
  • In 2020 EdgeHTML was rebuilt as a Chromium-based browser Edge and now has the same results as Chrome

Content-Type in cross origin requests

Browsers can send a cross origin request without OPTIONS preflight only for safe requests.
CORS-safelisted methods: GET, HEAD, POST
CORS-safelisted request-headers: Accept, Accept-Language, Content-Language, Content-Type
CORS-safelisted content-types: application/x-www-form-urlencoded, multipart/form-data, text/plain

Request Content-Type Tricks

HTTP Request Content-Type separators (without preflight request)

Separators Browsers Example
; Chrome Firefox EdgeHTML Safari Content-Type: text/plain;xxx
, EdgeHTML Content-Type: text/plain,xxx

Allowed symbols in Content-Type options (without preflight request)

Symbol Browsers Example
Fetch Spec: CORS-unsafe request-header byte
0x01-0x08 0x0E-0x1F : < > ? @ [ \ ] { } 0x7F
EdgeHTML Content-Type: text/plain;<xxx
0x09 0x20 ! # $ % & ' * + - . / 0-9 ; = A-Z ^ _ ` a-z | ~ Chrome Firefox EdgeHTML Safari Content-Type: text/plain;#xxx
, 0x80-0xFF Chrome EdgeHTML Safari Content-Type: text/plain;,xxx

fetch, XMLHttpRequest headers

fetch("http://localhost/", {
  method: "POST", 
  headers: {
    "Content-Type": "$Content-Type$"
  }
  credentials: "include",
  body: "test"
});
xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost/", true);
xhr.setRequestHeader("Content-Type", "$Content-Type$");
xhr.withCredentials = true;
xhr.send("test");

➖ - CORS preflight request

Content-Type Chrome Firefox EdgeHTML Safari
text/plain text/plain text/plain text/plain text/plain
TEXT/PLAIN TEXT/PLAIN TEXT/PLAIN TEXT/PLAIN TEXT/PLAIN
text/plain; x=x text/plain; x=x text/plain; x=x text/plain; x=x text/plain; x=x
text/plain; x="x" text/plain; x="x"
text/plain; application/json text/plain; application/json text/plain; application/json text/plain; application/json text/plain; application/json
text/plain;, application/json text/plain;, application/json text/plain;, application/json text/plain;, application/json
text/plain;, application/json, text/plain text/plain;, application/json, text/plain text/plain;, application/json, text/plain text/plain;, application/json, text/plain
application/json;, text/plain
CVE-2015-7193

sendBeacon, fetch, XMLHttpRequest blob

ct = '$Content-Type$';
blob = new Blob(["test"], {type: ct});

fetch("http://localhost/", { 
  method: 'POST', 
  credentials: "include",
  body: blob 
});

navigator.sendBeacon("http://localhost/", blob);

xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost/", true);;
xhr.withCredentials = true;
xhr.send(blob);

➖ - CORS preflight request

Content-Type Chrome Firefox EdgeHTML Safari
text/plain text/plain text/plain text/plain text/plain
TEXT/PLAIN text/plain text/plain text/plain text/plain
text/plain; x=x text/plain; x=x text/plain; x=x text/plain; x=x text/plain; x=x
text/plain; x="x" text/plain; x="x"
text/plain; application/json fetch: text/plain; application/json
sendBeacon: without CT
xhr: without CT
text/plain; application/json text/plain; application/json text/plain; application/json
text/plain;, application/json fetch: text/plain;, application/json
sendBeacon: without CT
xhr: without CT
text/plain;, application/json text/plain;, application/json
text/plain;, application/json, text/plain fetch: text/plain;, application/json, text/plain
sendBeacon: without CT
xhr: without CT
text/plain;, application/json, text/plain text/plain;, application/json, text/plain
application/json;, text/plain fetch: ➖
sendBeacon: without CT
xhr: without CT

fetch, XMLHttpRequest multiple Content-Type

fetch("https://localhost/", {
  method: "POST",
  headers: [
    ["Content-Type", "text/plain"],
    ["Content-Type", "application/json"]
  ],
  credentials: "include",
  body: "test"
});
xhr = new XMLHttpRequest();
xhr.open("POST", "https://localhost/", true);
xhr.setRequestHeader("Content-Type", "text/plain");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.withCredentials = true;
xhr.send("test");

➖ - CORS preflight request

Content-Type Chrome Firefox EdgeHTML Safari
text/plain
multipart/form-data
fetch: multipart/form-data
xhr: ➖
text/plain, multipart/form-data
text/plain
application/json
text/plain, application/json
application/json
text/plain