Modern applications tend to have complex logic that may be difficult to understand and maintain. This complexity can lead to logic bugs that attackers can exploit to bypass specific security controls and gain unauthorized access to sensitive data or functionality. In this module, we will learn how to identify and exploit logic bugs in web applications, mainly ones linked to user input.
Parameter Logic Bugs module will cover the following types of Logic Bugs:
Validation Logic Disparity
The module will do so by teaching the following:
- Different types of logic bugs
- Performing code reviews to identify logic bugs
- Setting up a local testing environment
- Performing a Proof of Concept (PoC)
- Patching the code and re-testing it
- Tips on avoiding logic bugs and writing secure code
In addition to teaching the above topics, this module will also cover:
- What are Logic Bugs?
- Different examples of real-world Logic Bugs
- The impact of Logic Bugs
- General causes of Logic Bugs
- Client-Side Logic vs Server-Side Logic
- Identifying Dynamic Validation Tests
- Types of Validation Logic Disparity Bugs
- Strongly-typed vs Loosely-typed Languages
- Types of Unexpected Input Bugs
- Identifying Functions with User Input
- Reviewing Schema Models
- Null-safe code vs Null-unsafe code
- Flawed Null Checks
- Identifying Null Variables
- Required vs Optional Parameters
- Common Effects of Null Safety Issues
Throughout the module, we will work with a replica of the Hack The Box Academy web application, built from scratch. This will allow us to demonstrate the different types of Logic Bugs in a realistic web application and allow you to follow along with the exercises and practice the various techniques we will cover.
The module is packed with exercises, challenges, extra questions, further reading, and hands-on labs to help you practice the different techniques we will cover. It also includes a practical hands-on skills assessment to gauge your understanding of the various topic areas.
To know more about this module before starting it, we recommend watching this talk from the module author at the HackTheBox Business CTF 2023 titled
Finding Logic Bugs in Your Code. It introduces the first few sections of this module and explains the importance of logic bugs and how to find them.
CREST CPSA/CRT-related Sections:
- All sections
As a "Hard"
The module relies on VSCode and Docker to run and debug the accompanying demo, so it is highly recommended to have them installed on your machine and follow along the instructions found within the module.
The following modules are also considered as pre-requisites before starting this module:
- Web Requests
- Introduction to Web Applications
- Linux Fundamentals
- Intro to Whitebox Pentesting
Introduction to Logic Bugs
In web application testing, we usually follow rules and techniques when testing and identifying vulnerabilities or bugs. However, some bugs fall into the 'logic bugs' category, which can be notoriously difficult to identify because they are primarily caused by logic flaws.
Despite their complexity, a thorough understanding of logic bugs enables us to create guidelines for their identification. Additionally, adhering to a secure coding methodology during web application development can help eliminate or reduce logic bugs, ensuring the creation of robust applications without logic flaws.
Because this may sound confusing and overwhelming, let us start by explaining logic bugs and go through some examples to understand them better.
What are Logic Bugs?
Logic Bugs are unintentional flaws in how an application processes user input or interactions. Unlike common bugs that can cause crashes or common vulnerabilities that lead to code execution, logic bugs alter how an application behaves under normal conditions.
For instance, consider an application with paid features. A logic bug in the application's code might inadvertently allow access to these features without payment. Logic bugs in the application's flow can often be exploited through normal usage of the application (e.g. front-end only), while parameter-related logic bugs usually require specialized tools for exploitation.
Such flaws would not constitute direct vulnerabilities, nor would they be clear bugs that crash the application or cause a malfunction, but rather cause an
unintended behavior that we can take advantage of. These bugs can remain hidden during normal application usage, causing no apparent issues. The application may function perfectly, revealing its flaws only under specific conditions that the developer might not have considered during the initial design. This inherent subtlety makes logic bugs particularly challenging to detect. Moreover, it is crucial to understand that logic bugs impact an application's flow and behavior, distinguishing them from issues that cause crashes or malfunctions.
While automated tools have their merits, identifying logic bugs poses a unique challenge, as they often struggle to fully comprehend, parse, and interconnect the intricate logic within an application's codebase and design. However, the landscape may soon change with recent Artificial Intelligence (AI) advancements.
The most reliable approach to identifying logic bugs remains rooted in human expertise and logic. These skills, combined with the guidance and practices we will explore throughout this module, including codebase reviews and static tests, are pivotal in our pursuit of identifying and addressing logic bugs effectively.
A Trivial Example
The above is a basic example of a Logic Bug, albeit quite comical. It was likely caused by a single line of code written without a proper understanding of its impact, leading to this bug. The developers may have used the
unique() keyword for the
password database parameter, which entails that every user's password must be unique from everyone else's! This keyword is usually used for emails and usernames, as such parameters need to be unique. However, in this case, whether it was a mishap or intentional, it caused this logic bug.
Furthermore, the application must have been configured with verbose logging, as it appears to show the direct database error to the front-end users, instead of showing a more generic error (e.g. The password is not unique). This basic example shows us the essence of logic bugs, how they occur due to minor mishaps, and how impactful they may be when they are found in sensitive functions "revealing another user's password, in this case".
A Real World Example (Unreleased iPhones)
Note: I will modify some facts and vulnerable components to protect the website's identity; however, the idea and concept should be identical.
One of the earliest instances of a web logic bug I faced was in an online e-shop selling electronics (e.g., Amazon, Walmart, or Target). The iPhone 4 was a day away from release in our region (back then, they spread releases over a longer period), and the product page only showed 'coming soon' instead of the 'add to cart' button. Personally, whenever I try to test a web application for logic bugs, I always start with 'I wonder what would happen if...', and so I wondered whether I would be able to complete the purchase if I somehow managed to add this 'unreleased' item to the shopping cart.
Adding the 'unreleased' iPhone to the shopping cart was a straightforward client-side bypass. I modified the
productId in the GET request when adding any other item and replaced it with the unreleased iPhone's product ID. Once added to the cart, instead of displaying "coming soon," the cart revealed the available quantities for each iPhone option. Consequently, I selected the iPhone configuration I desired and chose the option 'pick up from store' because the "delivery" options appeared incorrect, likely due to the web application's inability to handle an "unreleased item." Below is a diagram showcasing the general flow of the attack:
When clicking the checkout button, I was confident that the back-end server would handle this error and inform me that the product was 'out of stock' or 'unavailable.' However, to my surprise, I was directed to the payment details page and completed the purchase. I still thought that they would automatically cancel the order. However, to my amazement, after the iPhone was released to the public the next day, I received a pickup appointment and a purchase confirmation. Thus, this bug made the iPhone 4 (in my region) available for purchase before its release date.
I mentioned this incident before picking up the product, but they informed me it was rightfully mine since it had been paid for. As a result, I bypassed the waiting line and placed the order before the release. I promptly reported this bug and suggested a fix. However, as is often the case, no action was taken to address it. My intention had always been to identify and report potential logic bugs rather than exploit them for personal gain.
Logic Bugs CVEs
The iPhone 4 example only illustrates one aspect of logic bugs: they can encompass much more and have a more substantial impact. For instance, macOS systems are recognized for their robust Code Execution protection, which only allows code execution with the user's consent. Nevertheless, in 2021, a security researcher identified a basic logic bug that enables attackers to easily circumvent these protections by starting their script with (
#!) and not defining an interpreter (e.g.,
Apple did not program the System Policy to handle scripts without an interpreter and considered them safe. This logic bug allowed for the bypass of Code Execution protection on Apple devices. However,
CVE-2021-30853 was not the only logic bug to achieve such bypasses. Another logic bug, disclosed in this 2014 post, resulted in the same kind of bypass.
Because they all depend on logic, web applications, mobile apps, operating systems, games, or any computer program ever developed can contain limitless examples of logic bugs because their logic can always be flawed.
Impact of Logic Bugs
As we will see throughout the module, the impact of logic bugs can vary from minor inconveniences to
denial of service,
privilege escalation, and even
remote code execution.
Many logic bugs may not be exploitable, due to a certain 'usually unintended' security measure in place. For such cases, there won't be a significant impact other than user inconvenience. However, as a general rule of thumb, the impact of a logic bug is directly related to the sensitivity and importance of the flawed function and its related data. We are always interested in logic bugs in sensitive functions or sensitive data, like item purchases or code execution.
By the end of this module, we will deduce that flawed logic design often stems from insecure coding practices, which frequently lead to critical logic bugs.