Skip to content

Conversation

azurit
Copy link
Member

@azurit azurit commented May 27, 2024

I found TONS of ways how to bypass rule 942380 and some of them were extremely easy (for example using \s instead of \s+ in regex).

We are now able to catch these new ways of injection:

HAVING 2-1
HAVING 1 mod 2
HAVING 1 div 1
HAVING true = 1
HAVING false = 0
HAVING 1++++1
HAVING ''=''
HAVING '1'=1
HAVING ('1'=2)
HAVING 1%1
HAVING 1&1
HAVING 1*1
HAVING 1/1
HAVING 1|1
HAVING 1^2
HAVING 1!=2
HAVING 1<>1

Also, we are now catching these:

CREATE TABLE`test`
EXECUTE`test`

We are still NOT catching these:

HAVING 1
HAVING true

Copy link
Member

@fzipi fzipi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In your bypass example you mention for example using \s instead of \s+ in regex.

What is the difference on what you did? Does having work with no spacing?

@azurit
Copy link
Member Author

azurit commented Sep 4, 2024

In your bypass example you mention for example using \s instead of \s+ in regex.

What is the difference on what you did? Does having work with no spacing?

\s means exactly 1 space so it can be bypassed using 2 or more spaces. Any SQL server ignores excessive spaces in commands. For example order\sby can be bypassed using order by.

@theseion
Copy link
Contributor

theseion commented Sep 5, 2024

You could try removing all spaces with a transformation first.

@theseion theseion reopened this Dec 25, 2024
@theseion theseion removed the Stale label Dec 25, 2024
Copy link
Contributor

github-actions bot commented Dec 25, 2024

📊 Quantitative test results for language: eng, year: 2023, size: 10K, paranoia level: 1:
🚀 Quantitative testing did not detect new false positives

@azurit
Copy link
Member Author

azurit commented May 6, 2025

Ready to review again.

\bhaving\s*\(?\s*(?:['"]?\s*\d+\s*['"]?|['"]\s*[^\d]*\s*['"]|true|false)\s*(?:[=<>+\-*/%^&!|]+|div|mod)
\bexecute\s*\(
\bexecute\b\s*`?\s*[\w\.$]+\s*`?
\bcreate\b\s+\btable\b\s*`?\s*.+?\s*`?\s*\(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The \bs are redundant since \s+ implies non-word characters between the two strings.

Suggested change
\bcreate\b\s+\btable\b\s*`?\s*.+?\s*`?\s*\(
\bcreate\s+table\b\s*`?\s*.+?\s*`?\s*\(

\bhaving\s*\(?\s*(?:['"]?\s*\d+\s*['"]?|['"]\s*[^\d]*\s*['"]|true|false)\s*(?:[=<>+\-*/%^&!|]+|div|mod)
\bexecute\s*\(
\bexecute\b\s*`?\s*[\w\.$]+\s*`?
\bcreate\b\s+\btable\b\s*`?\s*.+?\s*`?\s*\(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Too complicated. Break it up into alternations, e.g.:

Suggested change
\bcreate\b\s+\btable\b\s*`?\s*.+?\s*`?\s*\(
\bcreate\b\s+\btable\b[^(]+\(
\bcreate\b\s+\btable\b\s*`\s*[^\s`]+\s*`\s*\(

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@theseion But it's not the same. Your version will match also this:
create table
Mine is matching, at least, this:
create table (

I don't think this one can be splitted into parts.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do my proposed expressions match create table? Both require \(. ? can always be written as an alternation (|), in this case

...(?:`|)...

And [^\(]+ is just a simplification of the wildcards in the original expression. So yes, I'm pretty sure that's correct :).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@theseion Hm, if i understand it correctly, you replaced this line:
\bcreate\b\s+\btable\b\s*`?\s*.+?\s*`?\s*\(

with these two?

\bcreate\b\s+\btable\b[^(]+\(
\bcreate\b\s+\btable\b\s*`\s*[^\s`]+\s*`\s*\(

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. The first doesn't have the backtick enclosed part, the second always has backticks. The result would be (spaces added for readability):

\bcreate\b\s+\btable\b[^(]+\(  |  \bcreate\b\s+\btable\b\s*`\s*[^\s`]+\s*`\s*\(

Shortened:

\bcreate\b\s+\btable\b(?:[^(]+\(  |  \s*`\s*[^\s`]+\s*`\s*\()

\bhaving\b ?\d{1,10} ?[=<>]+
\bhaving\b ?[\'\"][^=]{1,10}[\'\" ?[=<>]+
\bcreate\s+?table.{0,20}?\(
\bhaving\s*\(?\s*(?:['"]?\s*\d+\s*['"]?|['"]\s*[^\d]*\s*['"]|true|false)\s*(?:[=<>+\-*/%^&!|]+|div|mod)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Too complicated. Break it up.

exists\s\bhaving\b\s+\d{1,10}
exists\s'[^=]{1,10}'
\bexists\s*?\(\s*?select\b
\bselect\b.*?\bcase\b
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
\bselect\b.*?\bcase\b
\bselect\b.+?\bcase\b

\bexists\s*?\(\s*?select\b
\bselect\b.*?\bcase\b
\bfrom\b.*?\blimit\b
\bfrom\b.*?\bgroup\b\s+\bby\b
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
\bfrom\b.*?\bgroup\b\s+\bby\b
\bfrom\b.+?\bgroup\b\s+\bby\b

\bhaving\b ?\d{1,10} ?[=<>]+
\bhaving\b ?[\'\"][^=]{1,10}[\'\" ?[=<>]+
\bcreate\s+?table.{0,20}?\(
\bhaving\s*\(?\s*(?:['"]?\s*\d+\s*['"]?|['"]\s*[^\d]*\s*['"]|true|false)\s*(?:[=<>+\-*/%^&!|]+|div|mod)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
\bhaving\s*\(?\s*(?:['"]?\s*\d+\s*['"]?|['"]\s*[^\d]*\s*['"]|true|false)\s*(?:[=<>+\-*/%^&!|]+|div|mod)
\bhaving\s+\(?\s*(?:['"]?\s*\d+\s*['"]?|['"]\s*[^\d]*\s*['"]|true|false)\s*(?:[=<>+\-*/%^&!|]+|div|mod)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think * is correct here. The parser might accept ...having'..., for example.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The msg is SQL Injection Attack, atleast MySQL expects a space after HAVING, haven't checked others. Maybe @azurit has more info about this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it matters really in terms of the regex. As long as we assume that it can happen we should be fine either way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants