https://blog.sicuranext.com/response-filter-denial-of-service-a-new-way-to-shutdown-a-website/ Sicuranext Blog * Home * SOC * WAAP * PWNPress Sign in Subscribe WAAP Response Filter Denial of Service (RFDoS): shut down a website by triggering WAF rule * Andrea Menin Andrea Menin May 14, 2024 * 22 min read Response Filter Denial of Service (RFDoS): shut down a website by triggering WAF rule TL;DR: Basically, if a target website is protected by a WAF using the OWASP Core Rule Set or Comodo Rule Set or Atomicorp Rule Set, you can send the string ORA-1234 or OracleDrive or ASL-CONFIG-FILE in a comment, product review, registration form, e-commerce order details, etc... to prevent the website from showing its content to any users like a Denial of Service with a minimal effort. This happens because the overly inclusive response rules of the WAF try to prevent SQL error leakage or web shells. By checking all target websites on the most popular bug bounty platforms, I've earned 1,200$ of bounty for a single company having this RFDoS problem on their portal. Why showing debug errors isn't good for security? One of the information-gathering technique used by attackers is based on the extraction of valuable insights from error or debug messages inadvertently exposed by target web applications. Imagine a scenario where a database throw an error, or a server-side script like PHP or ASP accidentally reveals a full path or a snippet of its inner workings. These unintentional leaks, often overlooked, can provide valuable information for an attacker, collecting information for more significant vulnerabilities to be exploited. [php_error]Example of a PHP error Also, showing SQL error messages in a web application can be a security problem if the website inadvertently expose sensitive information about the underlying database. When these error messages are displayed, they often include specific details such as the type and name of the database, table names, and portions of the SQL query that triggered the error. As you might know, by understanding the database schema, an attacker can craft more effective SQL injection attacks, which can lead to unauthorized data access, data loss, or even complete system compromise. [image-23] For that reason, many Web Application Firewalls implement rules and response validation methods to prevent the leakage of sensitive information, such as SQL errors or errors related to scripting languages. The same happens, for example, to prevent Web Shell response body. This prevention often occurs by blocking the response body before it reaches the user, typically returning a 403 Forbidden status instead of the page containing the leakage. More modern WAFs often replace the leaked information with a series of asterisk characters ****. This method is commonly used to prevent leaks of credit card numbers or US Social Security numbers. However, both prevention methods (blocking the response or replacing the leaked content) are often completely ineffective. An attacker can usually bypass these preventions by sending a Range HTTP Request, which requests only portions of the response that do not trigger the WAF. We'll explore in more detail how this is done later in this post. Preventing leakages with a WAF is good, right? Once I read a statement attributed to Ivan Ristic that went something like, "When you create a new WAF Rule, you are also creating many ways to bypass it." Similarly, we can say that every time you create a response body WAF rule, you're also exposing websites or applications to RFDoS. Let's say you are trying to prevent the leakage of credit card numbers on your e-commerce site. To do this, you create a WAF rule that checks for four groups of digits separated by a - in the response body, using a regex like [0-9]+\-[0-9]+\-[0-9]+\-[0-9]+. [image-21]An example of Regular Expression matching CC numbers While this might seem like a sensible approach, it is actually quite risky because it's very easy for someone to exploit this rule to shut down parts of the website where user input is displayed. For example, if a user posts a comment or a review on a product with the string 4111-1111-1111-1111, the WAF will block the page response for everyone. Imagine if a user sends this type of comment or review to ALL products on the e-commerce site... it could trigger a sort of Denial of Service, preventing everyone from viewing any products on the protected e-commerce site. That's why I've started referring to this scenario as "Response Filter Denial of Service" or RFDoS. Additionally, apart from RFDoS, an attacker could always obtain data leakage from the target website using a Range Request. We'll explore why and how in the section titled "Prevent leakage in HTTP response body is often useless because of Byte Range HTTP request". To get the website up and running again after a Response Filter Denial of Service attack, the website owner has several options. These options include removing the rules that triggered the block, creating new exclusion rules to bypass these triggers, or disabling the response body access feature in the WAF. Each of these solutions requires a good understanding of how the WAF and its rules work, which can be challenging for someone without technical expertise in this area. Sometimes, less experienced users may not understand what is happening with the WAF and could decide to disable it, leaving the website without any protection or monitoring. For example, a user who simply activated ModSecurity v2 and the Core Rule Set via their hosting control panel like Plesk might find it difficult to diagnose and resolve the issue. The time required to identify and fix the problem could result in significant downtime. This downtime is particularly critical for e-commerce sites, where prolonged unavailability can directly translate into financial losses due to missed sales opportunities. ModSecurity and community Rule Set ModSecurity is an open-source Web Application Firewall that provides a variety of security features for web applications. It operates as a module in the web server environment, where it can perform real-time HTTP traffic monitoring, logging, and access control. ModSecurity supports flexible rule configuration, that can inspect both HTTP request and HTTP response. ModSecurity it's just the engine, and it requires rules to protect a web application. There're more than one free rule set, but the most well-known and widely used is the OWASP Core Rule Set (CRS) that is used by Google Cloud Armor, Azure Application Gateway, CloudFlare, and many other vendors (no... AWS WAF has a "Core Rule Set" managed rule, but it is not the OWASP Core Rule Set). However, there are also other rule sets available, created and distributed by different security organizations or companies, each with their unique features and focus. For instance, Comodo and Atomicorp are two such providers. Comodo offers its own set of ModSecurity rules focusing on a broad range of web security threats, while Atomicorp develops rules that are often integrated into their broader security products and services. These company-specific rule sets can provide alternative or supplementary protection strategies to the OWASP CRS, giving users more options depending on their specific security needs and the nature of the threats they are most concerned about. And what you've just read is ChatGPT's take on rule set alternatives to the OWASP Core Rule Set. The truth that few are willing to say publicly is that there are no good alternatives to the OWASP Core Rule Set. Other rule sets are often a jumble of poorly crafted rules that target very specific payloads and are easily bypassed. Most of the time, they end up being a waste of CPU resources. The OWASP Core Rule Set The OWASP Core Rule Set is a set of generic attack detection rules for use with ModSecurity or compatible WAFs. CRS aims to protect web applications from a wide range of attacks, including the OWASP Top Ten vulnerabilities, with minimal false positives. The CRS is designed as a plug-and-play solution, providing a basic security layer for any web application out of the box. Like many other WAF rule sets, the OWASP Core Rule Set includes some rules that inspect the response body, which you can find here. [image] All those rule sets pose problems in terms of RFDoS, but the most problematic one is the RESPONSE-951-DATA-LEAKAGES-SQL.conf configuration file/rule set. The main issue with detecting SQL errors in the HTTP response body is that you cannot avoid using a list of regexes that match simple strings without special characters. This is due to how some SQL errors are output by the engine. Consider blocking all HTTP response bodies containing the string "You have an error in your SQL syntax". While this might seem like a good practice, it's actually a risky approach that can not only cause false positives but also gives any attacker the ability to shut down any page that stores user input and displays it on the website. The fact that the statement "You have an error in your SQL syntax" contains no special characters makes it nearly impossible to validate or sanitize before storing it. Another example is a SQL error leakage rule that uses a regular expression to match ORA- followed by four digits, such as: ORA-1234 [image-12] As you can see, this rule runs at phase 4, which includes the response body, and blocks the response if the regex matches the RESPONSE_BODY variable. Another really simple string is dynamic sql error [image-13] Imagine how easy could be to trigger those rules, just by sending ORA-1234 inside a comment, or used as username or e-mail address. Update 14th May 2024 While I was completing this article, the OWASP Core Rule Set team committed a change to the rule I used to demonstrate RFDoS. They modified the regex that matched ORA-1234 to something like ORA-12345:. However, this change doesn't impact the RFDoS issue, and you'll still find the old regex in all of the OWASP Core Rule Sets deployed in production environments. Comodo Free Rules The "Comodo Free ModSecurity Rules" project, on this topic is even worse. It provides a set of free (but not open-source) rules for ModSecurity. These rules are maintained and updated by Comodo, after days trying to download the latest version (the website was always down) I finally managed to get my copy of cwaf_rules-1.241. Comodo distributes a series of OutgoingFilter rule sets that also include prevention of SQL error leakages. [image-11]from Comodo https://waf.comodo.com/user/cwaf_revisions As you can imagine, inside the 17_Outgoing_FilterSQL.conf file we can found our magic string ORA-1234: [image-8] But also other really simple string like Dynamic SQL Error or JET Database Engine or Access Database Engine [image-9][image-10] Atomicorp Free ModSecurity Rules Atomicorp offers a free-to-use set of ModSecurity rules that you can download by registering on their portal. One of these rules aims to prevent the leakage of the rules or configurations themselves by blocking any response body that includes the string: ---ASL-CONFIG-FILE---. So, in an attempt to prevent a self-configuration leakage, they inadvertently allow anyone to shut down a website by reflecting user input made up solely of A-Z characters and -. [image-3]From the latest Atomicorp modsec-202405080003.tar.bz2 Why response WAF rules are dangerous? If you can store user input on a target website (protected by a WAF), such as a comment or a product review, you can easily shut down the page where the user input is displayed by simply sending something like: ORA-1234 Imagine an e-commerce protected by WAF. To generate a Denial of Service attack on it, an attacker could simply submit a product review containing a message like, "Really useful product, I tried it with ORA-1234, and it works really well" effectively preventing any user from accessing the page where the review is published. The same applies to the "User Account Details" page: by registering an account with an email address like andrea+ORA-1234@gmail.com, it would stop any administrator from viewing the user list or editing the account details. The magic string ORA-1234 ORA-1234 isn't the only string that triggers this issue. Here's a list of very simple strings (without any special characters) that anyone can use to generate a Response Filter Denial of Service on a website that meets the conditions we mentioned earlier. Each one of the following strings will be blocked by one or more Response Body rule enabled on ModSecurity v2 + OWASP Core Rule Set: ET Database Engine Access Database Engine ORA-1234 Oracle error OracleDriver CLI DriverDB2 DB2 SQL error Dynamic SQL Error An illegal character has been found in the statement ExceptionInformix Ingres SQLSTATE Unexpected end of command in statement SQL errorPOS1 Warningmaxdb Unclosed quotation mark after the character string Microsoft OLE DB Provider for ODBC Drivers Microsoft OLE DB Provider for SQL Server Incorrect syntax near Sintaxis incorrecta cerca de Syntax error in string in query expression Procedure or function foo expects parameter Unclosed quotation mark before the character string Syntax error foo in query expression the used select statements have different number of columns OLE DBSQL Server DriverSQL Server SQL ServerDriverS QL Server12345678 supplied argument is not a valid MySQL on MySQL result index You have an error in your SQL syntax near MySQL server version for the right syntax to use SQL syntaxMySQL valid MySQL result PostgreSQLERROR valid PostgreSQL result Supplied argument is not a valid PostgreSQL foo resource Unable to connect to PostgreSQL server Warningsybase SybaseServer message An Error Has Occurred The Core Problem The main issue here is that all these strings can pass through any type of input validation or sanitization module. The lack of special characters, HTML tags, and terms included in bad-word dictionaries (like eval or exec) makes them the perfect choice for any attacker who wants to prevent a website from being displayed to users. RFDoS demo on a vanilla WordPress website Prevent leakage in HTTP response body is often useless because of Byte Range HTTP request Let's say I'm triggering a visible error-based SQL Injection on a target protected by a WAF. This WAF blocks all response bodies containing a SQL error. To bypass this and see the SQL error, I can send an Byte Range HTTP request. By requesting only a portion of the response body, it's quite easy to avoid triggering the WAF rule that is designed to prevent data leakage. The Range request header in the HTTP protocol is a feature that allows clients to request a specific part of a resource, rather than downloading the entire file or content at once. This header indicates which part of the resource the client wants to receive, specified as one or more data ranges. For example, a client can request the first 500 bytes of a file or a specific segment in the middle of a large video or document. The syntax for a Range request is typically like this: Range: bytes= 0-499, which requests the first 500 bytes of the resource. Let test it. In the following test, I'm attempting to exploit a SQL Injection using the query string parameter 'a', but an error occurs and the WAF blocks the response body to prevent the error from being leaked: [image-5] Typically, MySQL errors display a message like: "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'foo bar' at line xyz ". Knowing that the WAF rule likely matches the initial part of this message, You have an error in your SQL syntax, I can avoid triggering the WAF by "cutting off" the beginning of the response. I do this by sending a byte range HTTP request from 90 to 140. For example: [image-6] So, as you can see, bypassing any response body filter becomes quite easy using the Range request header. This applies not only to SQL error leakage but also to rules designed to prevent web shell or backdoor responses in the response body. [?][?] Requesting a byte range HTTP request is not always possible, as it depends on the webserver's decision to accept it or not. For example, if a SQL Injection payload leads the application to an error resulting in a 500 internal server error, the webserver might choose not to accept the byte range request and instead send the entire error page to the user. The OWASP Core Rule Set includes a set of rules aimed at preventing "Web Shells" or, in other words, backdoors. These rules attempt to match the HTML body of the most common online backdoors by, for example, triggering on the title tag of the page. [image-15] One of the most common objections I've encountered when explaining the RFDoS problem goes something like this: "Okay, RFDoS could be a problem, but preventing backdoors or PHP shells from being sent to an attacker is more important and worth the risk of RFDoS." Initially, this seemed like a valid point. However, I then remembered the Byte Range request, and I realized that attackers are often in a position to circumvent the response filter by requesting portions of the response body. I say often because this really depends on the configuration of the webserver and the server side modules. Let's do a test. I'm going to simulate a web shell, with a title tag that matches one of the Web Shells rules, and include a leak of the WordPress config file (which often contains the username and password for the MySQL database) that will trigger the PHP code leakage rule. [image-16] If I attempt to access the content of the web shell, the WAF will block my request because of one of the rules mentioned above. [image-17] ModSecurity logs: ModSecurity: Warning. Match of "rx ..." against "RESPONSE_BODY" required. [file "/etc/modsecurity.d/owasp-crs/rules/RESPONSE-953-DATA-LEAKAGES-PHP.conf"] [line "102"] [id "953120"] [msg "PHP source code leakage"] [severity "ERROR"] ... ModSecurity: Warning. Matched phrase "