Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle ClickHouse queries with other statements being invalid #58

Open
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

hansott
Copy link
Member

@hansott hansott commented Jan 20, 2025

If the original query is

insert into cats (name) values (' + var + ');

And the user input is

foo'||version());

Then the query will be

insert into cats_table (id, petname) values (null, 'foo'||version());');

Which isn't a valid query. The second statement is ');

Clickhouse seems to ignore this because it does not allow multiple statements. It will still execute the first part so we need to detect this.

If the original query is

```
insert into cats (name) values (' + var + ');
```

And the user input is

```
foo'||version());
```

Then the query will be

```sql
insert into cats_table (id, petname) values (null, 'foo'||version());');
```

Which isn't a valid query. The second statement is `');`

Clickhouse seems to ignore this because it does not allow multiple
statements. It will still execute the first part so we need to detect
this.
@hansott hansott changed the title Handle Clickhouse queries with other statements being invalid Handle ClickHouse queries with other statements being invalid Jan 20, 2025
}
}

// If the query is invalid, we can't determine if it's an injection
return false;
}

// Remove leading and trailing spaces from userinput :
let trimmed_userinput = userinput.trim_matches(SPACE_CHAR);
Copy link
Member

Choose a reason for hiding this comment

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

trimmed userinput is now only used for length check? everything else moved to replace_user_input_with_safe_str

if dialect == 3 && has_multiple_statements(query, dialect) {
// Clickhouse does not support multiple statements
// The first statement will still be executed if the other statements are invalid
// We'll assume the original query is valid
Copy link
Member

Choose a reason for hiding this comment

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

This I still don't fully understand, where do we make the assumption?

@codecov-commenter
Copy link

codecov-commenter commented Jan 20, 2025

Codecov Report

Attention: Patch coverage is 81.73077% with 19 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/sql_injection/detect_sql_injection_test.rs 77.55% 11 Missing ⚠️
src/sql_injection/detect_sql_injection.rs 85.45% 8 Missing ⚠️

📢 Thoughts on this report? Let us know!

return true;
}

matches!(tokens.last(), Some(Token::SemiColon)) && has_semicolon
Copy link
Member

Choose a reason for hiding this comment

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

has_semicolon is not necessary

}

fn is_single_statement(tokens: &Vec<Token>) -> bool {
let has_semicolon = tokens.iter().any(|x| matches!(x, Token::SemiColon));
Copy link
Member Author

Choose a reason for hiding this comment

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

TODO: Count them

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

Successfully merging this pull request may close these issues.

4 participants