ModSecurity False Positive SQL Injection - sql-injection

So I was able to wrangle several other ModSecurity rules giving false positives for other situations but I'm having issues with this specific ruleset. When customers submit a form with a double quotation the ruleset is activated and an access denied code 403 is spit out.
The last entry that was denied was Need a price on cabinet style 42”
The rule set that was triggered was SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/| !REQUEST_COOKIES:/_pk_ref/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "(^[\"'`´’‘;]+|[\"'`´’‘;]+$)"
The error in the logs showed up as ModSecurity: Access denied with code 403 (phase 2). Pattern match "(^[\\"'`\\xb4\\x92\\x91;]+|[\\"'`\\xb4\\x92\\x91;]+$)"
With such a simple phrase I'm not sure why the rule set is being triggered. I was reading in some places that it could be due to the encoding utilized. Any suggestions or help would be appreciated.

It's about SQL Injection.
SQL injection occurs when strings can be manipulated in a database query.
The attacker often introduces it using a single quote because this would close a string like
SELECT * from products WHERE name='$variable'
to
SELECT * from products WHERE name='->' OR '1'='1' -- <-'
(->...<- indicating the introduced input)
This attack works also with double quotes if the query is using it (cf https://chartio.com/learn/sql-tips/single-double-quote-and-backticks-in-mysql-queries/).
To test if SQL Injection is possible. The attacker often tries different characters. And this is why this rule pops up.
That means the general file of ModSecuriy what's of interest for you is:
https://github.com/SpiderLabs/owasp-modsecurity-crs/blob/master/base_rules/modsecurity_crs_41_sql_injection_attacks.conf
And the rule is:
SQL Injection Attack: Common Injection Testing Detected id:'981318'
The process you can do can be similar than in ModSecurity: Access denied with code 403:
First determine which requests are false positives and then
switch them off, for example using SecRuleRemoveByID.
In this case for example
<Directory /var/www/yourpath>
SecRuleRemoveById 981318
</Directory>

Related

SlashDB: Is it possible to to return HTTP error code from SQL Pass-thru?

In SlashDB, whenever a pass-through query can be executed, the HTTP code returned is always in the 200-class (OK, Created, etc.). Unfortunately, this doesn't account for cases when an error should be returned, such as: item doesn't exist in a table, etc.
Is it possible to force an error code from a pass-through query?
UPDATE:
I understand it is a an interminable debate whether a valid query should return an error code if it returns an empty set. There are valid arguments on both sides. I happen to think that if we think, say, a serial number is a resource and it doesn't exist, the call should return an error. Some details can then be placed in the response body as to how to further process the problem.
This question is not an attempt to seek answer to the aforementioned debate, but merely trying to discover whether there is a way in SlashDB to affect the HTTP error codes when using the SQL Pass-thru feature.
It's debatable if a query returning no rows is an error condition that would warrant a 404 Not Found. SlashDB behaved that way in earlier versions, but many developers complained.
Now, as long as the query is valid and executes without issues you will get a result and a 200 OK. It can be an empty list i.e. [], if there are no rows matching your query conditions.
Other error codes can be returned too. For example you will get a 403 if you don't have permissions.
Generally HTTP codes in the 4xx series indicate there's something wrong with a client's request. Codes in the 5xx series indicate some unexpected condition with the server i.e. database is down or time out from heavy traffic.
If this explanation does not address your particular query, please update your question with the query example and pertinent information about your database schema.
There doesn't seem to be a way to handle this in SlashDB. My solution to this is to declare an error on the MySQL side and a message_text to describe the problem. Because of this error, SlashDB returns an ambiguous 500 code.
It's a brute force solution, but it eliminates the ambiguity for now.

Unable to practice Sql Injection (blind) on DVWA 1.10

I am practicing for Security Testing. I came across DVWA and I started practicing for Sql Injection. I was doing fine till I started with SQL Injection (blind). No matter which query I try I am not getting the desired result.
For eg :
1' and 1=0 union select null,table_name from information_schema.tables#
simply returns User ID exists in the database.
I have set the DVWA Security to Low. Also made sure there are no errors on setup page of the application under Setup Check section.
Following are environment details:
Operating system: Windows
Backend database: MySQL
PHP version: 5.6.16
I think the answer is here and the behavior is expected
https://github.com/ethicalhack3r/DVWA/issues/12
Someone complained of the opposite behavior and the developer agreed, and a contributor named g0tm1lk fixed it. He made the exercise really "blind" and we have to use blind injection methods to test the vulnerability.
Showing the SQL error messages to the user is just: a SQL injection vuln + a misconfiguration issue.
A blind SQL injection might occur when the columns of the results returned by a query are not shown to the user. However, the user can tell somehow if the query returned any records or none.
E.g.: Suppose the url "http://www.example.com/user?id=USER_ID" returns:
200 if USER_ID exists
404 if USER_ID not exists
But it won't show any information from the query results (e.g. username, address, phone, etc)
If the page is vulnerable to SQLi [blind], an attacker won't be able get info from the DB printed in the result page, but he might be able to infer it by asking yes/no questions.

Handling an SQL Injection attack

What should an Incident Handler do (or) follow when an SQL injection attack is reported?
Initial Response
Analysis
Action
Aiming to make a Procedure guide to follow for myself and my team.
Brief or detail, anything would help.
Not a full process, but it should get you started:
Initial Response
Verify that the reported vulnerability is legitimate, preferably in a production-safe manner
See the OWASP SQL Injection Testing guide for more information on how to do this
Analysis
Determine the cause of the SQL Injection
This is probably a location where user input is directly concatenated into a SQL query
Action
The best defense against SQL Injection is to utilize parameterized/prepared statements instead of direct string concatenation when building a query based on user input.
These statements provide a clear divide between data and syntax, so that user input is never treated as SQL syntax but instead treated as data
How you do this will depend on the language and framework used in your application
See the OWASP SQL Injection Prevention Cheat Sheet for more information on preventing SQL injection

Avoid sql injection on checkbox in gridview

<asp:CheckBox ID="chkIsHidden" runat="server" Enabled="false"
Checked='<%# Convert.IsDBNull(Eval("Is_Hidden")) ? false : Convert.ToBoolean(Eval("Is_Hidden")) %>'
/>
Above code, Security program scan and alert that "Blind SQL Injection", I'm so confuse
Why it has SQL injection?
How to fix to avoid sql injection?
As you can see, even if your Web application does not return error messages, it may still be susceptible to blind SQL injection attacks. However, you can protect your organization's applications against attacks with the following best practices:
Create a policy that enforces secure coding practices to ensure vulnerability detection and assessments are performed during any application development or deployment.
Have your developers identify where data enters or exits the application and ensure that validation occurs for every part of the HTTP request before letting it anywhere near scripts, data access routines and SQL queries. This will prevent user-supplied data from being able to modify the syntax of SQL statements.
Completely isolate your Web applications from SQL using stored procedures, which the application should execute using a safe interface, such as JDBC's CallableStatement or ADO's Command Object. If SQL statements must be generated on the fly, use PreparedStatements, as both PreparedStatements and stored procedures compile the SQL statement before the user input is added, making it impossible for user input to modify the actual SQL statement.
Consider using a vulnerability assessment tool to automate the discovery of SQL injection and other security vulnerabilities.
Develop an incident response plan. Having a detailed and well-rehearsed plan will help you handle any attack that occurs in an orderly and effective manner, and minimize the impact to your organization.

How to determine the encoding of request query string

Suppose I have a .NET HttpModule that analyzes incoming requests to check for possible attacks like Sql Injection.
Now suppose that a user of my application enters the following in a form field and submits it:
&#039&#032&#079&#082&#032&#049&#061&#049
That is Unicode for ' OR 1=1. So in the request I get something like:
http://example.com/?q=%26%23039%26%23032%26%23079%26%23082%26%23032%26%23049%26%23061%26%23049
Which in my HttpModule looks fine (no Sql Injection), but the server will correctly decode it to q=' OR 1=1 and my filter will fail.
So, my question is: Is there any way to know at that point what is the encoding used by the request query string, so I can decode it and detect the attack?
I guess the browser has to tell the server which encoding the request is in, so it can be correctly decoded. Or am I wrong?
the server will correctly decode it to q=' OR 1=1
It shouldn't. There is no valid reason(*) an application would HTML-decode the &#039... string before using it in an SQL query. HTML-decoding is a client-side occurrence.
(* there's the invalid reason: that the application author doesn't have the foggiest idea what they're doing, tries to write an input-HTML-escaping function - a misguided idea in the first place - and due to incompetence writes an input-de-escaping function instead... but that would be an unlikely case. Hopefully.)
Is there any way to know at that point what is the encoding used by the request query string
No. Some Web Application Firewalls attempt to get around this by applying every decoding scheme they can think of to the incoming data, and triggering if any of them match something suspicious, just in case the application happens to have an arbitrary decoder of that type sitting between the input and a vulnerable system.
This can result in a performance hit as well as increased false positives, and doubly so for the WAFs that try all possible combinations of two or more decoders. (eg is T1IrMQ a base-64-encoded, URL-encoded OR 1 SQL attack, or just a car numberplate?)
Quite how far you take this idea is a trade-off between how many potential attacks you catch and how much negative impact you have on real users of the app. There's no one 'correct' solution because ultimately you can never provide complete protection against app vulnerabilities in a layer outside the app (aka "WAFs don't work").
What you are seeing is URL Encoded, where a percent sign followed by 2 hex digits represents a single encoded byte octet. In HTML, an entity starting with an ampersand and ending with a semicolon contains an entity name or an explicit Unicode codepoint value.
What gets sent over the wire between the browser and server is http://example.com/?q=%26%23039%26%23032%26%23079%26%23082%26%23032%26%23049%26%23061%26%23049, but logically is actually represents http://example.com/?q=&#039&#032&#079&#082&#032&#049&#061&#049 when decoded by the server upon receiving it. When your code reads the query string, it should be receiving &#039&#032&#079&#082&#032&#049&#061&#049. The server should not be decoding that any further to ' OR 1=1, you would have to do that in your own code.
If you are allowing a URL query string to specify an SQL query filter as-is, then that is a mistake on your part to begin with. That suggests you are building SQL queries dynamically instead of using parameterized SQL queries or stored procedures, so you are leaving yourself open to SQL Injection attacks. You should not be using that. Parameterized SQL queries and stored procedure are not subject to injection attacks, so your clients should only be allowed to submit the indiviudal parameter values in the URL. Your server code can then extract the individual values from the URL query and pass them to the SQL parameters as needed. The SQL Engine will make sure the values are santitized and formatted to avoid attacks. You should not be handling that manually.