hacktricks/pentesting/pentesting-web/special-http-headers.md

237 lines
13 KiB
Markdown
Raw Normal View History

2021-09-19 15:19:00 +00:00
# Special HTTP headers
2021-09-20 13:06:32 +00:00
## Wordlists
2021-09-19 15:52:48 +00:00
* [https://github.com/danielmiessler/SecLists/tree/master/Miscellaneous/web/http-request-headers](https://github.com/danielmiessler/SecLists/tree/master/Miscellaneous/web/http-request-headers)
2021-09-19 15:19:00 +00:00
## Headers to Change Location
Rewrite **IP source**:
* `X-Originating-IP: 127.0.0.1` 
2021-09-19 15:52:48 +00:00
* `X-Forwarded-For: 127.0.0.1`
* `X-Forwarded: 127.0.0.1`
* `Forwarded-For: 127.0.0.1`
2021-09-27 10:58:30 +00:00
* `X-Forwarded-Host: 127.0.0.1`
* `X-Remote-IP: 127.0.0.1` 
2021-09-19 15:19:00 +00:00
* `X-Remote-Addr: 127.0.0.1`
* `X-ProxyUser-Ip: 127.0.0.1`
* `X-Original-URL: 127.0.0.1`
2021-09-19 15:52:48 +00:00
* `Client-IP: 127.0.0.1`
2021-09-27 10:58:30 +00:00
* `X-Client-IP: 127.0.0.1`
* `X-Host: 127.0.0.1`
2021-09-19 15:52:48 +00:00
* `True-Client-IP: 127.0.0.1`
* `Cluster-Client-IP: 127.0.0.1`
* `X-ProxyUser-Ip: 127.0.0.1`
2021-09-20 13:06:32 +00:00
* `Via: 1.0 fred, 1.1 127.0.0.1`
* `Connection: close, X-Forwarded-For` (Check hop-by-hop headers)
2021-09-19 15:19:00 +00:00
Rewrite **location**:
* `X-Original-URL: /admin/console`
* `X-Rewrite-URL: /admin/console`
## Hop-by-Hop headers
A hop-by-hop header is a header which is designed to be processed and consumed by the proxy currently handling the request, as opposed to an end-to-end header.
* `Connection: close, X-Forwarded-For`
{% content-ref url="../../pentesting-web/abusing-hop-by-hop-headers.md" %}
[abusing-hop-by-hop-headers.md](../../pentesting-web/abusing-hop-by-hop-headers.md)
{% endcontent-ref %}
2021-09-19 15:19:00 +00:00
## HTTP Request Smuggling
* `Content-Length: 30`
* `Transfer-Encoding: chunked`
2021-11-05 20:59:42 +00:00
{% content-ref url="../../pentesting-web/http-request-smuggling/" %}
[http-request-smuggling](../../pentesting-web/http-request-smuggling/)
{% endcontent-ref %}
2021-09-19 15:19:00 +00:00
2021-09-19 15:52:48 +00:00
## Cache Headers
2021-09-20 13:06:32 +00:00
**Server Cache Headers**:
2021-09-19 15:52:48 +00:00
* **`X-Cache`** in the response may have the value **`miss`** when the request wasn't cached and the value **`hit`** when it is cached
* **`Cache-Control`** indicates if a resource is being cached and when will be the next time the resource will be cached again: `Cache-Control: public, max-age=1800`
2021-11-30 13:50:20 +00:00
*  **`Vary`** is often used in the response to **indicate additional headers** that are treated as **part of the cache key** even if they are normally unkeyed.
2021-09-19 15:52:48 +00:00
* **`Age`** defines the times in seconds the object has been in the proxy cache.
{% content-ref url="../../pentesting-web/cache-deception.md" %}
[cache-deception.md](../../pentesting-web/cache-deception.md)
{% endcontent-ref %}
2021-09-19 15:52:48 +00:00
2021-09-20 13:06:32 +00:00
**Local Cache headers**:
* `Clear-Site-Data`: Header to indicate the cache that should be removed: `Clear-Site-Data: "cache", "cookies"`
* `Expires`: Contains date/time when the response should expire: `Expires: Wed, 21 Oct 2015 07:28:00 GMT`
* `Pragma: no-cache` same as `Cache-Control: no-cache`
* `Warning`: The **`Warning`** general HTTP header contains information about possible problems with the status of the message. More than one `Warning` header may appear in a response. `Warning: 110 anderson/1.3.37 "Response is stale"`
2021-09-19 19:55:40 +00:00
## Conditionals
2021-09-19 15:19:00 +00:00
2021-09-20 13:06:32 +00:00
* Requests using these headers: **`If-Modified-Since`** and **`If-Unmodified-Since`** will be responded with data only if the response header**`Last-Modified`** contains a different time.
* Conditional requests using **`If-Match`** and **`If-None-Match`** use an Etag value so the web server will send the content of the response if the data (Etag) has changed. The `Etag` is taken from the HTTP response.
2021-11-30 13:50:20 +00:00
* The **Etag** value is usually **calculated based** on the **content** of the response. For example, `ETag: W/"37-eL2g8DEyqntYlaLp5XLInBWsjWI"` indicates that the `Etag` is the **Sha1** of **37 bytes**.
2021-09-19 19:55:40 +00:00
## Range requests
2021-09-20 13:06:32 +00:00
* **`Accept-Ranges`**: Indicates if the server supports range requests, and if so in which unit the range can be expressed. `Accept-Ranges: <range-unit>`
* **`Range`**: Indicates the part of a document that the server should return.
* **`If-Range`**: Creates a conditional range request that is only fulfilled if the given etag or date matches the remote resource. Used to prevent downloading two ranges from incompatible version of the resource.
* **`Content-Range`**: Indicates where in a full body message a partial message belongs.
2021-09-19 19:55:40 +00:00
## Message body information
2021-11-30 13:50:20 +00:00
* **`Content-Length`:** The size of the resource, in decimal number of bytes.
2021-09-20 13:06:32 +00:00
* **`Content-Type`**: Indicates the media type of the resource
* **`Content-Encoding`**: Used to specify the compression algorithm.
* **`Content-Language`**: Describes the human language(s) intended for the audience, so that it allows a user to differentiate according to the users' own preferred language.
2021-09-20 13:06:32 +00:00
* **`Content-Location`**: Indicates an alternate location for the returned data.
2021-09-19 19:55:40 +00:00
2021-11-30 13:50:20 +00:00
From a pentest point of view this information is usually "useless", but if the resource is **protected** by a 401 or 403 and you can find some **way** to **get** this **info**, this could be **interesting.** \
****For example a combination of **`Range`** and **`Etag`** in a HEAD request can leak the content of the page via HEAD requests:
2021-09-19 19:55:40 +00:00
* A request with the header `Range: bytes=20-20` and with a response containing `ETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y"` is leaking that the SHA1 of the byte 20 is `ETag: eoGvPlkaxxP4HqHv6T3PNhV9g3Y`
2021-09-20 13:06:32 +00:00
## Server Info
* `Server: Apache/2.4.1 (Unix)`
* `X-Powered-By: PHP/5.3.3`
## Controls
2021-11-30 13:50:20 +00:00
* **`Allow`:** Lists the set of methods supported by a resource. `Allow: GET, POST, HEAD`
2021-09-20 13:06:32 +00:00
* **`Expect`**: The **`Expect`** HTTP request header indicates expectations that need to be fulfilled by the server in order to properly handle the request.
* No other expectations except `Expect: 100-continue` are specified currently. Informs recipients that the client is about to send a (presumably large) message body in this request and wishes to receive a [`100`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/100) (Continue) interim response.
2021-09-20 13:06:32 +00:00
## Downloads
* **`Content-Disposition`**: In a regular HTTP response, the **`Content-Disposition`** response header is a header indicating if the content is expected to be displayed _inline_ in the browser, that is, as a Web page or as part of a Web page, or as an _attachment_, that is downloaded and saved locally.
* `Content-Disposition: attachment; filename="filename.jpg"`
## Security Headers
2021-11-30 13:50:20 +00:00
### Content Security Policy (CSP) <a href="#csp" id="csp"></a>
{% content-ref url="../../pentesting-web/content-security-policy-csp-bypass.md" %}
[content-security-policy-csp-bypass.md](../../pentesting-web/content-security-policy-csp-bypass.md)
{% endcontent-ref %}
2021-11-30 13:50:20 +00:00
### Trusted Types <a href="#tt" id="tt"></a>
Trusted Types provide the tools to write, security review, and maintain applications free of DOM XSS. They can be enabled via [CSP](https://web.dev/security-headers/#csp) and make JavaScript code secure by default by limiting dangerous web APIs to only accept a special object—a Trusted Type.
To create these objects you can define security policies in which you can ensure that security rules (such as escaping or sanitization) are consistently applied before the data is written to the DOM. These policies are then the only places in code that could potentially introduce DOM XSS.
```http
Content-Security-Policy: require-trusted-types-for 'script'
```
```javascript
2021-10-19 22:49:43 +00:00
// Feature detection
if (window.trustedTypes && trustedTypes.createPolicy) {
// Name and create a policy
const policy = trustedTypes.createPolicy('escapePolicy', {
createHTML: str => {
return str.replace(/\</g, '&lt;').replace(/>/g, '&gt;');
}
});
}
```
```javascript
2021-10-19 22:49:43 +00:00
// Assignment of raw strings is blocked by Trusted Types.
el.innerHTML = 'some string'; // This throws an exception.
// Assignment of Trusted Types is accepted safely.
const escaped = policy.createHTML('<img src=x onerror=alert(1)>');
el.innerHTML = escaped; // '&lt;img src=x onerror=alert(1)&gt;'
```
2021-11-30 13:50:20 +00:00
### X-Content-Type-Options <a href="#xcto" id="xcto"></a>
2021-10-19 22:49:43 +00:00
When a malicious HTML document is served from your domain (for example, if an image uploaded to a photo service contains valid HTML markup), some browsers will treat it as an active document and allow it to execute scripts in the context of the application, leading to a [cross-site scripting bug](https://www.google.com/about/appsecurity/learning/xss/).
`X-Content-Type-Options: nosniff` prevents it by instructing the browser that the [MIME type](https://mimesniff.spec.whatwg.org/#introduction) set in the `Content-Type` header for a given response is correct. This header is recommended for **all of your resources**.
```http
X-Content-Type-Options: nosniff
```
2021-11-30 13:50:20 +00:00
### X-Frame-Options <a href="#xfo" id="xfo"></a>
2021-10-19 22:49:43 +00:00
If a malicious website can embed your site as an iframe, this may allow attackers to invoke unintended actions by the user with [clickjacking](https://portswigger.net/web-security/clickjacking). Also, in some cases [Spectre-type attacks](https://en.wikipedia.org/wiki/Spectre\_\(security\_vulnerability\)) give malicious websites a chance to learn about the contents of an embedded document.
`X-Frame-Options` indicates whether or not a browser should be allowed to render a page in a `<frame>`, `<iframe>`, `<embed>`, or `<object>`. **All documents** are recommended to send this header to indicate whether they allow being embedded by other documents.
If you need more granular control such as allowing only a specific origin to embed the document, use the [CSP](https://web.dev/security-headers/#csp) [`frame-ancestors`](https://developer.mozilla.org/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors) directive.
```http
X-Frame-Options: DENY
```
2021-11-30 13:50:20 +00:00
### Cross-Origin Resource Policy (CORP) <a href="#corp" id="corp"></a>
2021-10-19 22:49:43 +00:00
An attacker can embed resources from another origin, for example from your site, to learn information about them by exploiting web-based [cross-site leaks](https://xsleaks.dev).
`Cross-Origin-Resource-Policy` mitigates this risk by indicating the set of websites it can be loaded by. The header takes one of three values: `same-origin`, `same-site`, and `cross-origin`. **All resources** are recommended to send this header to indicate whether they allow being loaded by other websites.
```
Cross-Origin-Resource-Policy: same-origin
```
2021-11-30 13:50:20 +00:00
### Cross-Origin Opener Policy (COOP) <a href="#coop" id="coop"></a>
2021-10-19 22:49:43 +00:00
An attacker's website can open another site in a popup window to learn information about it by exploiting web-based [cross-site leaks](https://xsleaks.dev). In some cases, this may also allow the exploitation of side-channel attacks based on [Spectre](https://en.wikipedia.org/wiki/Spectre\_\(security\_vulnerability\)).
The `Cross-Origin-Opener-Policy` header provides a way for a document to isolate itself from cross-origin windows opened through `window.open()` or a link with `target="_blank"` without `rel="noopener"`. As a result, any cross-origin opener of the document will have no reference to it and will not be able to interact with it.
```http
Cross-Origin-Opener-Policy: same-origin-allow-popups
```
2021-11-30 13:50:20 +00:00
### Cross-Origin Resource Sharing (CORS) <a href="#cors" id="cors"></a>
2021-10-19 22:49:43 +00:00
Unlike other items in this article, Cross-Origin Resource Sharing (CORS) is not a header, but a browser mechanism that requests and permits access to cross-origin resources.
By default, browsers enforce [the same-origin policy](https://web.dev/same-origin-policy/) to prevent a web page from accessing cross-origin resources. For example, when a cross-origin image is loaded, even though it's displayed on the web page visually, the JavaScript on the page doesn't have access to the image's data. The resource provider can relax restrictions and allow other websites to read the resource by opting-in with CORS.
```http
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true
```
2021-10-19 22:49:43 +00:00
{% content-ref url="../../pentesting-web/cors-bypass.md" %}
[cors-bypass.md](../../pentesting-web/cors-bypass.md)
{% endcontent-ref %}
2021-11-30 13:50:20 +00:00
### Cross-Origin Embedder Policy (COEP) <a href="#coep" id="coep"></a>
2021-10-19 22:49:43 +00:00
To reduce the ability of [Spectre-based attacks](https://en.wikipedia.org/wiki/Spectre\_\(security\_vulnerability\)) to steal cross-origin resources, features such as `SharedArrayBuffer` or `performance.measureUserAgentSpecificMemory()` are disabled by default.
`Cross-Origin-Embedder-Policy: require-corp` prevents documents and workers from loading cross-origin resources such as images, scripts, stylesheets, iframes and others unless these resources explicitly opt into being loaded via [CORS](https://web.dev/security-headers/#cors) or [CORP](https://web.dev/security-headers/#corp) headers. COEP can be combined with`Cross-Origin-Opener-Policy` to opt a document into [cross-origin isolation](https://web.dev/cross-origin-isolation-guide/).
Use `Cross-Origin-Embedder-Policy: require-corp` when you want to enable [cross-origin isolation](https://web.dev/coop-coep/) for your document.
```http
Cross-Origin-Embedder-Policy: require-corp
```
2021-11-30 13:50:20 +00:00
### HTTP Strict Transport Security (HSTS) <a href="#hsts" id="hsts"></a>
2021-10-19 22:49:43 +00:00
Communication over a plain HTTP connection is not encrypted, making the transferred data accessible to network-level eavesdroppers.
`Strict-Transport-Security` header informs the browser that it should never load the site using HTTP and use HTTPS instead. Once it's set, the browser will use HTTPS instead of HTTP to access the domain without a redirect for a duration defined in the header.
```http
Strict-Transport-Security: max-age=3153600
```
2021-09-19 19:55:40 +00:00
## Resources
* [https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers)
2021-10-19 22:49:43 +00:00
* [https://web.dev/security-headers/](https://web.dev/security-headers/)