Prevent SQL injection¶
This page shows how you can prevent SQL injection attacks. In the following examples, the variable userInput is a string
with a value provided by the user.
Input values¶
All values are added as parameters so they are safe:
// Safe
IQuery query1 = sql.Query.Select(userInput);
// Safe
IAlias person2 = sql.Alias("person");
IQuery query2 = sql.Query.Where(person2["Name"].Eq(userInput));
// Safe
Person person3 = null;
IQuery query3 = sql.Query.Where(() => person3.Name == userInput);
Table, alias and column names¶
By default all names are escaped, and the escape character is removed from the name. Although this can prevent some attacks, they are still vulnerable:
// Unsafe
IQuery query1 = sql.Query
.From(userInput)
.Join(userInput);
// Unsafe
IQuery query2 = sql.Query
.From("person", userInput)
.Join("dept", userInput);
// Unsafe
IAlias alias3 = sql.Alias(userInput);
IAlias person3 = sql.Alias("person", userInput);
IAlias<Department> dept3 = sql.Alias<Department>(userInput);
// Unsafe
IAlias person4 = sql.Alias("person");
IQuery query4 = sql.Query
.Select(person4[userInput]);
Column names of the typed alias are safe because it only allows the registered columns:
// Safe
IAlias<Person> person = sql.Alias<Person>();
IQuery query = sql.Query
.Select(person[userInput]);
Warning
Always validate user input, do not allow the user to select any column.
Function names¶
Function names are vulnerable:
// Unsafe
IAlias person = sql.Alias("person");
IFunction func = sql.Function(userInput).Add(person["Name"]);
But they can be safe if you enable FunctionsOnlyRegistered in the engine options:
// Safe
engine.Options.FunctionsOnlyRegistered = true;
IAlias person = sql.Alias("person");
IFunction func = sql.Function(userInput).Add(person["Name"]);
Warning
Always validate user input, do not allow the user to execute any function.
Raw SQL¶
The SQL string is vulnerable, do not pass a concatenated or interpolated string:
// Unsafe
IRawSql raw1 = sql.Raw("WHERE person.Name = '" + userInput + "'");
// Unsafe
IRawSql raw2 = sql.Raw($"WHERE person.Name = '{userInput}'");
// Unsafe
IRawSql raw3 = sql.Raw(string.Format("WHERE person.Name = '{0}'", userInput));
Instead, use a composite format string to add the values as parameters:
// Safe
IRawSql raw = sql.Raw("WHERE person.Name = {0}", userInput);