In the absence of these considerations, systems can be retrofitted with ineffective security controls or lack them entirely. This can be attributed to teams rushing to meet a release deadline or those who are unaware of the security threats they may encounter.
This lack of threat modeling and adherence to best practices and principles is what we, as hackers, can capitalize on.
To understand what is considered an insecure design vulnerability, let’s evaluate some of the Common Weakness Enumerations (CWEs) mapped to this classification. You can view the full list here.
This design weakness arises when a server relies solely on client-side protections for enforcing security policies.
Many web applications implement input validation or sanitization to prevent malicious payloads from being processed by the server. These security measures also restrict the data end users are allowed to submit, such as rules governing the allowed data type, minimum/maximum length, format, or characters.
These protections often take place on the client side because it improves the speed of the checks and provides a better user experience, however, if user input is not also properly checked by the server, you can easily circumvent these defensive measures through the use of an HTTP proxy tool such as Caido. By intercepting a request after it is sent by the browser, you can bypass any client-side restrictions or checks, allowing you to modify the data being sent.
For example, consider a form that limits users to alphanumeric characters when supplying input to the fields. To accomplish this, the developers defined the following validation schema using the Zod library:
While this would block a payload such as
POST /comment HTTP/1.1 Host: example.com comment=%3Cimg%20src%3Dx%20onerror%3Dalert()%3E |
Similarly, if sanitization is being used to remove data containing script tags but is only performed in the frontend, you could bypass this check by embedding the tag within another:
As you can see, this vulnerability would allow you to send arbitrary data that will be handled by the backend – a design choice that was not intended. While this may be sufficient for a normal user, it would be inadequate against you as a bug bounty hunter.
When parameters that specify files are exposed, without the proper restrictions in place, you may be able to access, modify, or execute arbitrary files. This can be especially impactful when access to files and directories outside of the web root is possible, as these directories contain sensitive system files.
For example, if an application selects an image file to use as the banner of a webpage, you could use directory traversal techniques to access other files:
GET /image?filename=../../../etc/passwd |
Even if security checks are implemented, such as ensuring that the filename ends in an image extension, it may be possible to terminate the file path by using a null byte:
GET /image?filename=../../../etc/passwd%00.jpg |
If traversal sequences are being matched and removed, the same embedding technique mentioned earlier may bypass this sanitization:
GET /image?filename=….//….//….//etc/passwd |
If the web application offers file upload functionality, the presence of this insecure design capability can result in the ability to upload malicious files. For example, if a server was using PHP as its backend language, you could potentially achieve remote code execution by uploading your own PHP file with the following script:
By navigating to the uploaded file’s location and supplying the command parameter, you could run system commands on the server:
GET /uploads/command.php?command=whoami |
Certain insecure design vulnerabilities in a system’s architecture can be exploited via HTTP request smuggling attacks.
For web applications that are not well known and thus receive low levels of traffic, a single server is most likely sufficient enough to handle all the incoming requests. However, popular applications can receive levels of traffic that would overwhelm a solo server – resulting in latency issues or outages. To mitigate against system downtime, network engineers may place servers (load balancers or reverse proxies) in front of backend servers to alleviate the workload. These frontend servers will intercept multiple requests, group them, and distribute the bundled requests in a way that ensures no one backend server is overwhelmed. Each request in this bundle will enter a processing queue.
To delineate these bundled requests, HTTP/1.1 utilizes two request headers to specify where one request ends, and another begins: Content-Length and Transfer-Encoding.
The value of the Content-Length header is representative of the number of bytes in the body of a request. For example:
POST /comment HTTP/1.1 Host: example.com Content-Length: 28 Content-Type: application/x-www-form-urlencoded comment=X&username=ninjeeter |
If the value of the Transfer-Encoding header is set to chunked, the request body data is divided into one or more portions referred to as “chunks”. The data is also measured in bytes but is represented in hexadecimal encoding. With this header, the end of a request is marked with a chunk size of 0. For example:
POST /comment HTTP/1.1 Host: example.com Transfer-Encoding: chunked Content-Type: application/x-www-form-urlencoded 1c |
The vulnerability arises when there is a mismatch between the frontend and backend server on which the header is to be used. By sending a request with both headers, the frontend is tricked into thinking multiple requests are a single request. However, once the backend receives this “single” request, it processes each one separately.
For example, if the frontend server uses the value of the Content-Length header to determine the end of a request, but the backend uses Transfer-Encoding: chunked – you could potentially “smuggle” a request to a restricted endpoint with:
POST /comment HTTP/1.1 Host: example.com Cookie: session=123ABC Content-Length: 138 Content-Type: application/x-www-form-urlencoded Transfer-Encoding: chunked 0 GET /admin/delete?name=otheruser HTTP/1.1 x= |
This request will be seen as one by the frontend but as two by the backend. When the backend gets to the GET /admin/delete?name=otheruser HTTP/1.1 request, it will be held in the processing queue awaiting the missing 49 bytes. The empty parameter x= will catch the subsequent request and take the first 49 bytes from it.
It is critical to note that the value of Content-Length header includes the CRLF characters. Each r and n is considered to be one byte:
Here are some disclosed HTTP request smuggling reports that have been submitted by security researchers on the HackerOne platform:
Business logic vulnerabilities allow malicious attackers to exploit an application’s legitimate processing flow to achieve unintended results. These issues arise from unforeseen user behavior and design choices based on assumptions made by developers that do not account for edge cases.
In processing flows that are multistep, developers may not envision scenarios in which certain parameters are removed, reused, or modified. These parameters can be critical to the proper outcome of an operation. Data flows that should be tested for business logic vulnerabilities include:
Certain crucial parameters may even be inherently insecure as their values are widely known. For example, if developers require a security question to be answered before allowing a password reset, but the question is too general, such as: “What city did you grow up in?” – you could simply use this wordlist to brute force the correct answer.
Since these vulnerabilities arise in the specific context of the functionality a web application offers, these insecure design weaknesses can go undetected without in-depth code review. When you are navigating an application, make sure you become familiar with the intended flow of user actions, and then you can brainstorm how the process can be exploited.
Insecure design vulnerabilities are often tied to the specific technologies powering an application. Because of this, it is crucial to first identify and understand the technologies in use before looking for potential weaknesses. This can be accomplished by using tools such as WhatRuns or Wappalyzer. It is also important to gain a deep understanding of how the application operates, so invest ample time into a single target. Ultimately, securing an application from the ground up requires careful attention to detail, and any oversight can result in a bounty payout for you.
As 2024 comes to a close and we reach the midpoint of a decade that… Read More
Fortinet warns about Critical flaw in Wireless LAN Manager FortiWLM Pierluigi Paganini December 19, 2024… Read More
A critical security configuration in Azure Key Vault has been discovered, potentially allowing users with… Read More
BADBOX is a cybercriminal operation infecting Android devices like TV boxes and smartphones with malware… Read More
KEY SUMMARY POINTS Google Calendar Targeted: Hackers are exploiting Google Calendar’s features to send phishing… Read More
Joseph Cox, author of the 2024 book “Dark Wire: The Incredible True Story of the… Read More