How the SQL Injection Analyzer handles your SQL
SQL injection has one cause: a value that came from outside the program ends up inside the statement's text, where the database reads it as syntax rather than as data. The analyser looks for exactly that. It reads your code as text, but not naively — it walks the source the way a tokeniser does, so string literals are understood and anything inside a comment is skipped rather than reported.
A string is only treated as SQL when it reads like SQL: it opens with a verb such as SELECT or UPDATE, or it
pairs clauses the way a real statement does. Once a string qualifies, the analyser checks how it is being
assembled — an interpolation hole ($"... {id} ...", f"...{id}...",
`...${id}...`), concatenation with a non-literal operand, or a format call such as
string.Format. It also flags escaping used as a defence, because doubling quotes fails in numeric
and identifier contexts and misses multi-byte encodings entirely.
Just as important is what it does not report. Entity Framework Core's
FromSqlInterpolated and ExecuteSqlInterpolated turn their holes into bound
parameters, so an interpolated string handed to either is recognised as safe. Concatenating two ordinary
strings is not a finding. Where a file clearly binds parameters, a raw command API is listed for review rather
than as a defect.
The honest limit is scope. The analyser sees one file at a time and reads it as text, so it cannot follow a value from a controller through a repository into a query. A clean result means none of the known unsafe shapes appear in what you pasted — not that the application is safe.
Using it, step by step
- Paste the method, class or file that builds your SQL, or open a .cs, .java, .php, .py or .js file.
- Leave Language on Detect automatically, or pick one if the guess is wrong.
- Select Analyse code, or press Ctrl + Enter (Cmd + Enter on a Mac).
- Read each issue: it names the untrusted input, the line, why it is exploitable and the impact.
- Copy the fixed code from an issue, or copy the whole report to paste into a ticket or a pull request.
A worked example
This repository method looks ordinary:
var sql = $"SELECT id, name FROM users WHERE name LIKE '%{name}%'";
sql += " ORDER BY " + sortColumn;
and produces two findings:
Issue 1: sql-interpolation [CRITICAL] line 1
The value of name is pasted into the SQL text before the database sees it.
Issue 2: dynamic-identifier [HIGH] line 2
A column name is being built from sortColumn. Identifiers cannot be passed
as parameters, which is why this case is so often left unfixed.
With name set to ' OR '1'='1 the first statement stops filtering: the condition is true for every row, so the method returns the whole table instead of one person's matches. The fix is to bind the value rather than paste it:
using (var command = new NpgsqlCommand(
"SELECT id, name FROM users WHERE name LIKE @name", connection))
{
command.Parameters.Add(new NpgsqlParameter("name", "%" + name + "%"));
}
The second needs a different fix, and the analyser says so: a column name cannot be a parameter, so the incoming value has to be mapped through a whitelist to a name you wrote yourself.
Where this fits in day-to-day work
- Checking a repository or data-access class before it goes into a pull request.
- Triaging an old codebase to find which queries are built by concatenation and need rewriting first.
- Settling whether an interpolated query is actually unsafe, since Entity Framework Core's FromSqlInterpolated is not.
- Showing a team why doubling quotes is not a fix, with the parameterised version beside it.
- Reviewing code you were sent without pasting a client's source into a hosted service.
When the output is not what you expected
- An interpolated query is reported that you believe is safe
- Check which API receives it. FromSqlInterpolated and ExecuteSqlInterpolated bind their holes and are recognised as safe, but a string built with interpolation and then passed to FromSqlRaw or a command constructor is not: the interpolation has already happened by then.
- A raw SQL API is listed even though the code binds parameters
- Raw command APIs are reported at low severity for review rather than as defects when the file clearly binds parameters. It is a prompt to confirm that every value in the statement is bound, not a claim that something is wrong.
- No issues are found in code you know is unsafe
- The analyser reads one file as text and cannot follow a value across methods or files. If the query is assembled in a helper and executed elsewhere, paste the helper. Check too that the string really reads as SQL; a fragment with no keywords is not recognised.
- The language was detected wrongly
- Detection uses markers such as using statements, $" strings and -> operators, so a short snippet can be ambiguous. Choose the language explicitly; it changes which comment syntax and concatenation operator are understood.
Questions about the SQL Injection Analyzer
Is my code uploaded anywhere?
No. The analysis runs in your browser with JavaScript, and nothing you paste or open is sent to our server. That is the point of running a security tool this way: reviewing a client's source should not mean handing it to a third party.
Does a clean result mean my application is safe?
No, and the tool says so rather than implying otherwise. It reads one file as text and checks for known unsafe shapes. It cannot follow a value from a controller through a repository into a query, so a clean result means none of those shapes appear in what you pasted.
Why is escaping quotes not an acceptable fix?
Because it only works in one context. Doubling quotes does nothing for a value spliced into a numeric comparison, nothing for a column or table name, and it can be defeated in multi-byte encodings where the escape character is absorbed into a valid character. Binding the value removes the problem instead of papering over it.
How do I fix a dynamic ORDER BY?
Not with a parameter, because identifiers cannot be bound. Map the incoming value through a whitelist to a column name written in your own code, and reject anything that is not in it. The analyser produces that whitelist for you.
Which languages are supported?
C#, Java, PHP, Python and JavaScript or TypeScript. Each one's comment syntax, string literals and concatenation operator are handled, including C# verbatim and interpolated strings and Python f-strings.
Does it replace a real security review?
No. It finds one class of bug by pattern, which is a useful first pass and a good pull request gate. It knows nothing about authorisation, stored procedures it cannot see, or how the data is used afterwards.