The term “Business Logic” can be misleading, but in the context of web application security and bug bounties, a Business Logic Vulnerability is when an attacker is able to make a website or application perform an action that was never intended by the developers. For example, a eCommerce website may allow you to perform a transaction, without actually going through the intended shopping cart sequence. This could potentially lead to invalided input supplied during the transaction process and cause unwanted outcomes.
Another term for these vulnerabilities is “Logic Flaws”. Since logic flaws typically require a human element for thinking about what the web application can do, and how we can make it do things that aren’t intended, they make for a great vulnerability category to hunt for, since vulnerability scanners typically won’t find these type of bugs.
Table of Contents:
- Example A: Excessive trust in client-side controls:
- Example B: 2FA Broken Logic
- Example C: High-Level Logic Vulnerability
- Example D: Low-Level Logic Flaw
- Example E: Inconsistent Handling of Exceptional Input
- Example F: Inconsistent Security Controls
- Example G: Weak Isolation on Dual-Use Endpoint
- Example H: Password Reset Broken Logic
- Example I: 2FA Simple Bypass
- Example J: Insufficient Workflow Validation
- Example K: Authentication Bypass via Flawed State Machine
- Example L: Flawed Enforcement of Business Rules
- Example M: Infinite Money Logic Flaw
Example A: Excessive Trust in Client-Side Controls
In this example, we have a eCommerce website that sells a jacket for over $1,000. When the item is added to the cart, the price is also sent in the request. We can intercept this request and adjust the price of the item ourselves using Burp Suite.
Example B: 2FA Broken Logic
In this example, we have a web application that utilizes 2FA. We notice by observing the requests after signing in that in addition to sending our username/password, a 2nd request is sent that will request a 2FA code to be generated for whatever user is supplied in the “verify” parameter.
If we sign in with our own account (since we know valid credentials to it), we can then modify the request so that the verification code is generated for a different account by replacing “wiener” with our target, “carlos”.
With a verification code generated for Carlos, let’s enter an invalid 2FA code that is pending for our login and capture the request in Burp Suite. With the request captured, let’s send it to Repeater where we will modify the “verify” parameter to “carlos” and then set the “mfa-code” parameter to our payload.
Using a simple wordlist that contains four digit numbers, we’re able to brute force Carlos’ MFA code.
And then show the response in the browser to get logged in as Carlos.
Example C: High-Level Logic Vulnerability
In this example, we have another eCommerce site with multiple products for sale. This time however, the price is hardcoded with the ProductID in the request. Adding the expensive jacket will make the total in our cart over $1,000.
However, we can also intercept a request that adds another item in the cart. Since this item costs $80, we can use Burp to add -15 items, which cuts the price down for us.
Now our cart total is only $48.50.
Example D: Low-Level Logic Flaw
In this example, we’re working with the same eCommerce website. However, our previous attacks don’t work. This time, we’re going to attempt to add so many items to the cart that the “Total Price” overflows. Most programming languages can’t hold integers over 2.147b in value. In this particular case, adding enough items to the cart will cause the Total Price to overflow and start incrementing in negative values instead.
Burp Suite can easily perform this for us. If we intercept a request that is adding 99 items to the cart, we can then send it to Intruder. Instead of specify a payload, we’ll clear the payloads and set our payload type to a “Null payload”. This will essentially allow us to repeat our same request in bulk a certain, or infinite, number of times.
We can see by doing so, we have now added a ton of items to the cart, and cause the Total Price to return a negative value.
Now we just need to modify the cart in the right way so that the total price fits to a value between $0-100 since we have store credit of that amount. At that point, we can place the order.
Example E: Inconsistent Handling of Exceptional Input
In this example, we have a login page as well as the ability to register an account. Any account registered with the @dontwannacry.com domain will automatically be assigned administrator rights. However, since we do not have access to a valid @dontwannacry.com email account, we must exploit a misconfiguration.
We find that while we’re able to insert more than 256 characters when creating an email account, the application will truncate the remaining characters when signing up for an account. For example, we could enter the following email address when registering: ONHknIt7C0NCfRqaybvtktQpiS2BflyVTzAiGeC0yfOyIVN4wBGHFc9LXCsMIKGj7LfV2pmFbLyj73orVyWnSQcQKJHPG8zl2STXKoSLjccYVWf5rVB64aVkMlYlOppQBG8svfEE1nb3bOnenhF2fECssVypADOlJGQIuUUvrGCINMUY0agnw8tegZqDxep2XszBk501BgBdkY8om7jpXIERAoPvKHqs9aq5bFattacker@dontwannacry.com.ac9a1f1f1e15a857801bf5e2013f00e5.web-security-academy.net
As long as we own the domain dontwannacry.com.ac9a1f1f1e15a857801bf5e2013f00e5.web-security-academy.net, we should be able to receive the email message to verify the account. However, logging in reveals that only the first 256 characters are kept. This changes our email address to an @dontwannacry.com address, therefor tricking the system into giving us admin rights.
Example F: Inconsistent Security Controls
This one is simple. We have a login page and the ability to register an account. Any account registered with an @dontwannacry.com address will be assigned admin rights. We can’t register an account directly with this email because there is an email verification step upon initial registration, however, the web app does not require email verification to update your email address afterwards.
Once logged in using an email you do control, you can simply change your email to an @dontwannacry.com address using the “My Account” page.
Example G: Weak Isolation on Dual-Use Endpoint
In this example, we have a web app that allows for user accounts. When we’re logged in as a low level user, there is a feature for updating our password, but the client requires that we provide our current password before the new one will take. However, we notice that intercepting the request and deleting the “¤t-password” parameter will allow us to change the password without knowing the current with.
We also notice that we can reset the password for any given user by providing the username of the desired account within the &username parameter.
Example H: Password Reset Broken Logic
In this example, we’re able to request a password reset for our own account to generate a valid reset token. However, the web app does not appear to perform checks against the token to ensure its validity. We find that when the token is removed, we’re able to reset a password for any user account by updating the “username” parameter.
With the token values removed, we can then adjust the username parameter to reflect the account we wish to reset. This now allows us to sign in using carlos:password as our credentials.
Example I: 2FA Simple Bypass
In this example, we know the password to two accounts both of which are secured with 2FA.
- Our account: wiener:peter
- Vitim account: carlos:montoya
Since we have access to Wiener’s mailbox, we can sign in from start to finish, receive the 2FA code, and see that we’re redirected to /my-account upon successful login.
With this knowledge, we can bypass the 2FA prompt by signing into Carlo’s account with the password and then browsing straight to /my-account when asked to enter the 2FA code.
Example J: Insufficient Workflow Validation
In this example, we want to purchase a super expensive item that costs $1,000, but only have $100 in store credit to use. We notice that ordering an item that we can afford (meaning less than $100) will issue a GET request that looks like this.
GET /cart/order-confirmation?order-confirmed=true HTTP/1.1
Armed with this knowledge, we can simply add the more expensive item to the cart and then use Burp Repeater to reissue that GET request. Doing so allows us to successfully place an order with bypassing the checkout process that collects payment.
Example K: Authentication Bypass via Flawed State Machine
In this example, we have valid login credentials for a non-admin user. However, the login process sends the user through a couple of pages. It looks like this.
- The user logs in by issuing a POST request to /login. We will forward this request.
2) Next, the web application will issue a GET request to /role-selector. This is a page that allows the user to select which role they want to interact with the web application with, based on which roles they’re allowed to use. However, we want to bypass this test to see what role is supplied by default, so we’ll drop this request.
3. At this point, we’ll manually browse back to the home page of the application, which shows us that we now have access to the admin panel! This proves that the default role is administrator.
Example L: Flawed Enforcement of Business Rules
In this example, we have an eCommerce site with discount codes. There are two codes that we can use on the page, but the intention of the developers was to only allow each code to be used a single time.
- SIGNUP30 – Takes 30% off your order.
- NEWCUST5 – Takes $5 off your order.
When trying to use the same discount code multiple times, the site will return an error.
However, we found that alternating between the two codes will bypass this control and allow us to use each coupon an unlimited number of times. Using Repeater, it is easy to send multiple requests and modify the coupon code being used for each.
Eventually the price is reduced to $0 as we’ve applied so many discounts.
Example M: Infinite Money Logic Flaw
In this example, we find that we’re able to utilize a 30% off coupon code to purchase a giftcard worth $10. Because there are no limits to the number of times we can place an order with this code, we can place multiple orders and make $3 off of each transaction.
To do this, we’ll configure a Burp Suite macro that will add the gift card to our cart, apply the coupon, check out, retrieve the gift card code, apply it to our account, and then use that money to repeat the process.
Since Portswigger does a better job at explaining how to set up the Macro than I could, the below is copied directly from their website. The process will create a Macro that runs each time we submit any request to the site. Once that is configured, we’ll utilize Repeater to automate the process of sending multiple null requests to the site to trigger the macro.
- Go to “Project options” > “Sessions”. In the “Session handling rules” panel, click “Add”. The “Session handling rule editor” dialog opens.
- In the dialog, go to the “Scope” tab. Under “URL Scope”, select “Include all URLs”.
- Go back to the “Details” tab. Under “Rule actions”, click “Add” > “Run a macro”. Under “Select macro”, click “Add” again to open the Macro Recorder.
- Select the following sequence of requests. Then, click “OK”. The Macro Editor opens.
- In the list of requests, select
GET /cart/order-confirmation?order-confirmed=true. Click “Configure item”. In the dialog that opens, click “Add” to create a custom parameter. Name the parameter
gift-cardand highlight the gift card code at the bottom of the response. Click “OK” twice to go back to the Macro Editor.
- Select the
POST /gift-cardrequest and click “Configure item” again. In the “Parameter handling” section, use the drop-down menus to specify that the
gift-cardparameter should be derived from the prior response (response 4). Click “OK”.
- In the Macro Editor, click “Test macro”. Look at the response to
GET /cart/order-confirmation?order-confirmation=trueand note the gift card code that was generated. Look at the
POST /gift-cardrequest. Make sure that the
gift-cardparameter matches and confirm that it received a
302response. Keep clicking “OK” until you get back to the main Burp window.
- Send the
GET /my-accountrequest to Burp Intruder. Use the “Sniper” attack type and clear the default payload positions.
- On the “Payloads” tab, select the payload type “Null payloads”. Under “Payload options”, choose to generate
412payloads. On the “Options” tab, set the thread count to
1. Start the attack.
- When the attack finishes, you will have enough store credit to buy the jacket and solve the lab.