Fortinet white logo
Fortinet white logo

Administration Guide

Syntax-based SQL injection detection

Syntax-based SQL injection detection

Using regular expression-based signatures to detect SQL injection attacks is core to a WAF solution. However, due to the nature of the SQL language being similar to English grammar, false positives can occur together with false negatives as evasion techniques evolve. For example, one regex rule cannot completely cover all the variables of a SQL injection type, such as:

SELECT * FROM users WHERE id = 1 OR 1=1

SELECT * FROM users WHERE id = 1 OR abc=abc

SELECT * FROM users WHERE id = 1 OR 3<5

SELECT * FROM users WHERE id = 1 OR UTC_DATE()=UTC_DATE()

It is a continuous and tedious process to maintain and update the signatures to address new evasion techniques and to tune false positives.

To address this, FortiWeb's Syntax-based SQL injection detection detects a SQL injection attack by analyzing the lexeme and syntax of SQL language rather than using a pattern matching mechanism. It first turns the input statement into a sequence of tokens, and then turns the sequence of tokens into an abstract syntax tree (AST), which is a representation of the abstract syntactic structure of the input statement. The parser compares the produced AST with the AST of built-in standard SQL statements to check whether they have the same AST structure. If the syntactic structures are different, FortiWeb recognizes it as a SQL injection attempt and then triggers the violation action.

How syntax-based SQL injection detection works

When clients access web applications, they input values in fields rather than the entire SQL statement. The application inserts the values into an SQL statement and sends the query to the database.

For example, you may be asked to enter the employee ID on the web page when you want to check someone's profile. The employee ID is the condition value for the query, and it is sent to the web server by a request:

GET /employee_profile.asp?employee_id=20001 HTTP/1.1

Then the received value 2001 will be combined with a SQL template to generate a SQL statement for the query:

select * from employee where employee_no = 2001

However, if a client inputs the condition value with a snippet such as 1 or 1 = 1, it might be a SQL injection attempt.

When syntax-based SQL injection detection is enabled, the snippets in requests will be processed by SQL template combination, grammar parsing, and an AST comparison to validate whether it is a SQL injection. For example, the snippet 1 or 1 = 1 will be extracted from request

GET /employee_profile.asp?employee_id=1 or 1 = 1 HTTP/1.1

and combined with a FortiWeb built-in template

select * from t where v = [injection point]

to generate the SQL statement

select * from t where v = 1 or 1 = 1

FortiWeb runs the process to build an AST for the target SQL statement and compare it with the FortiWeb built-in standard AST to see if they have the same structure. Different but equivalent SQL statements yield the same AST structure, and nonequivalent SQL statements have different AST structures. For example, here is a built-in standard statement and two target statements:

  • Built-in standard statement: select * from t where v = 1
  • Target statement 1: select * from t where v = WAF products
  • Target statement 2: select * from t where v = 1 or 1 = 1

The first target statement is equivalent to the built-in standard statement. Each has the same AST structure as illustrated below:

The second target statement is not equivalent to the built-in standard statement:

They are different AST structures, and as a result FortiWeb will detect an SQL injection attempt.

Built-in SQL statement templates

To address all possible injection points FortiWeb needs to first understand the probable context of SQL statements. The common three options are:

select * from employee where employee_no = "2001"

select * from employee where employee_no = '2001'

select * from employee where employee_no = 2001

To cover all cases that an attacker might try, Syntax-based SQL Injection Detection employs the following three templates:

  • Double Quote Based SQL Injection: select * from t where v = "[injection point]"
  • Single Quote Based SQL Injection: select * from t where v = '[injection point]'
  • As-Is Based SQL Injection: select * from t where v = [injection point]

By default, FortiWeb enables all three templates. While you can disable each one, it is not recommended to do so unless you're absolutely certain that this query type is not supported by the database.

SQL injection types

Once a snippet is identified as an SQL injection, FortiWeb will describe the SQL injection types and show corresponding ASTs, such as:

SQL Injection types Snippet examples
Stacked queries SQL injection

1; delete from users

Embedded queries

1 union select username, password from users

1 /*! ; drop table admin */

Condition based boolean injection

1 /**/OR/**/1/**/=/**/1

1 OR ’abc’=’abc’

case 1 when 2 then 2 end

1 || user_id is not null

Arithmetic operation based boolean injection

a'+'b

A' DIV 'B

A' & 'B

Line comments

1”--

1 #abc

SQL function based boolean injection

ascii(substring(length(version()),1,1))

Enable Syntax Based SQL Injection detection

  1. Go to Web Protection > Known Attacks > Signatures, select existing signature policy or create a new one.
  2. Click the status button for SQL Injection (Syntax Based Detection) to enable it, and double-click to set the Action, Block Period, Severity and Trigger Action for the policy. For more information about these options, see To configure a signature rule.
  3. It is recommended to disable categories SQL Injection and SQL Injection (Extended) when SQL Injection (Syntax Based Detection) is enabled.

  4. While not recommended, enable/disable individual templates and signatures if necessary. For details, see Built-in SQL statement templates.

Syntax-based SQL injection detection

Syntax-based SQL injection detection

Using regular expression-based signatures to detect SQL injection attacks is core to a WAF solution. However, due to the nature of the SQL language being similar to English grammar, false positives can occur together with false negatives as evasion techniques evolve. For example, one regex rule cannot completely cover all the variables of a SQL injection type, such as:

SELECT * FROM users WHERE id = 1 OR 1=1

SELECT * FROM users WHERE id = 1 OR abc=abc

SELECT * FROM users WHERE id = 1 OR 3<5

SELECT * FROM users WHERE id = 1 OR UTC_DATE()=UTC_DATE()

It is a continuous and tedious process to maintain and update the signatures to address new evasion techniques and to tune false positives.

To address this, FortiWeb's Syntax-based SQL injection detection detects a SQL injection attack by analyzing the lexeme and syntax of SQL language rather than using a pattern matching mechanism. It first turns the input statement into a sequence of tokens, and then turns the sequence of tokens into an abstract syntax tree (AST), which is a representation of the abstract syntactic structure of the input statement. The parser compares the produced AST with the AST of built-in standard SQL statements to check whether they have the same AST structure. If the syntactic structures are different, FortiWeb recognizes it as a SQL injection attempt and then triggers the violation action.

How syntax-based SQL injection detection works

When clients access web applications, they input values in fields rather than the entire SQL statement. The application inserts the values into an SQL statement and sends the query to the database.

For example, you may be asked to enter the employee ID on the web page when you want to check someone's profile. The employee ID is the condition value for the query, and it is sent to the web server by a request:

GET /employee_profile.asp?employee_id=20001 HTTP/1.1

Then the received value 2001 will be combined with a SQL template to generate a SQL statement for the query:

select * from employee where employee_no = 2001

However, if a client inputs the condition value with a snippet such as 1 or 1 = 1, it might be a SQL injection attempt.

When syntax-based SQL injection detection is enabled, the snippets in requests will be processed by SQL template combination, grammar parsing, and an AST comparison to validate whether it is a SQL injection. For example, the snippet 1 or 1 = 1 will be extracted from request

GET /employee_profile.asp?employee_id=1 or 1 = 1 HTTP/1.1

and combined with a FortiWeb built-in template

select * from t where v = [injection point]

to generate the SQL statement

select * from t where v = 1 or 1 = 1

FortiWeb runs the process to build an AST for the target SQL statement and compare it with the FortiWeb built-in standard AST to see if they have the same structure. Different but equivalent SQL statements yield the same AST structure, and nonequivalent SQL statements have different AST structures. For example, here is a built-in standard statement and two target statements:

  • Built-in standard statement: select * from t where v = 1
  • Target statement 1: select * from t where v = WAF products
  • Target statement 2: select * from t where v = 1 or 1 = 1

The first target statement is equivalent to the built-in standard statement. Each has the same AST structure as illustrated below:

The second target statement is not equivalent to the built-in standard statement:

They are different AST structures, and as a result FortiWeb will detect an SQL injection attempt.

Built-in SQL statement templates

To address all possible injection points FortiWeb needs to first understand the probable context of SQL statements. The common three options are:

select * from employee where employee_no = "2001"

select * from employee where employee_no = '2001'

select * from employee where employee_no = 2001

To cover all cases that an attacker might try, Syntax-based SQL Injection Detection employs the following three templates:

  • Double Quote Based SQL Injection: select * from t where v = "[injection point]"
  • Single Quote Based SQL Injection: select * from t where v = '[injection point]'
  • As-Is Based SQL Injection: select * from t where v = [injection point]

By default, FortiWeb enables all three templates. While you can disable each one, it is not recommended to do so unless you're absolutely certain that this query type is not supported by the database.

SQL injection types

Once a snippet is identified as an SQL injection, FortiWeb will describe the SQL injection types and show corresponding ASTs, such as:

SQL Injection types Snippet examples
Stacked queries SQL injection

1; delete from users

Embedded queries

1 union select username, password from users

1 /*! ; drop table admin */

Condition based boolean injection

1 /**/OR/**/1/**/=/**/1

1 OR ’abc’=’abc’

case 1 when 2 then 2 end

1 || user_id is not null

Arithmetic operation based boolean injection

a'+'b

A' DIV 'B

A' & 'B

Line comments

1”--

1 #abc

SQL function based boolean injection

ascii(substring(length(version()),1,1))

Enable Syntax Based SQL Injection detection

  1. Go to Web Protection > Known Attacks > Signatures, select existing signature policy or create a new one.
  2. Click the status button for SQL Injection (Syntax Based Detection) to enable it, and double-click to set the Action, Block Period, Severity and Trigger Action for the policy. For more information about these options, see To configure a signature rule.
  3. It is recommended to disable categories SQL Injection and SQL Injection (Extended) when SQL Injection (Syntax Based Detection) is enabled.

  4. While not recommended, enable/disable individual templates and signatures if necessary. For details, see Built-in SQL statement templates.