method to prepare string for a sql command - c#

I need to create a string method that takes in a string and
escapes it so that it can be used in a database SQL query, for example:
"This is john's dog" ==> "This is john''s dog"
"This is a 'quoted' string" ==> "This is a ''quoted'' string"
I want my method to look something like this:
string PrepareForSQLCommand(string text)
{
...
}
Anyway, I don't know all of the characters that need to be escaped in SQL query.
I am not sure what the best approach is to do this, or if there is some
existing robust built-in stuff to do this in C#.
Apologies for not mentioning this earlier: I DO NOT HAVE THE OPTION TO USE PARAMETRIZED QUERIES.
Ted

The usual way to do this would be to use a parametrised query as part of a SqlCommand.
SqlCommand command = new SqlCommand("SELECT * FROM MyTable WHERE MyCol = #param", connection);
command.Parameters.AddWithValue("#param", "This is john's dog");
The framework then ensures safety for you, which is less error-prone than trying to work out all of the possible injection attacks for yourself.

Trigger Warning. This answer is in response to the following statement:
I do not have the option to use parametrized queries.
Please do not up-vote this answer and please don't accept this as the correct way of doing things. I don't know why the OP cannot use parametrized queries, so I am answering that specific question and not recommending this is how you should do this. If you are not the OP, please read the other answer I have given. Also, please bear in mind the above constraint before down-voting. Thanks.
End of trigger warning!
For Microsoft SQL Server (the answer is different depending on the server) you will need to escape the single quote characters.
'
But before you escape these characters, you should reject any character not on your white-list. This is because there are lots of very clever tricks out there and white-list validation is more secure than simply escaping characters you know are bad.
Regex whiteList = new Regex("[^'a-zA-Z0-9 -]");
query = whiteList.Replace(query, "");
For example, this would remove [ and ] characters, and ';' characters. You may need to adjust the regex to match your expectations as this is a very restrictive white-list - but you know what kind of data you are expecting to see in your application.
I hope this helps. Feel free to check out the OWASP website for more details on security and if you can find a way of using parametrized queries you'll sleep all the better for it.

Related

SQL Like Operator (single quotation) [duplicate]

The MySQL documentation says that it should be \'. However, both scite and mysql shows that '' works. I saw that and it works. What should I do?
The MySQL documentation you cite actually says a little bit more than you mention. It also says,
A “'” inside a string quoted with “'” may be written as “''”.
(Also, you linked to the MySQL 5.0 version of Table 8.1. Special Character Escape Sequences, and the current version is 5.6 — but the current Table 8.1. Special Character Escape Sequences looks pretty similar.)
I think the Postgres note on the backslash_quote (string) parameter is informative:
This controls whether a quote mark can be represented by \' in a string literal. The preferred, SQL-standard way to represent a quote mark is by doubling it ('') but PostgreSQL has historically also accepted \'. However, use of \' creates security risks...
That says to me that using a doubled single-quote character is a better overall and long-term choice than using a backslash to escape the single-quote.
Now if you also want to add choice of language, choice of SQL database and its non-standard quirks, and choice of query framework to the equation, then you might end up with a different choice. You don't give much information about your constraints.
Standard SQL uses doubled-up quotes; MySQL has to accept that to be reasonably compliant.
'He said, "Don''t!"'
What I believe user2087510 meant was:
name = 'something'
name = name.replace("'", "\\'")
I have also used this with success.
There are three ways I am aware of. The first not being the prettiest and the second being the common way in most programming languages:
Use another single quote: 'I mustn''t sin!'
Use the escape character \ before the single quote': 'I mustn\'t sin!'
Use double quotes to enclose string instead of single quotes: "I mustn't sin!"
just write '' in place of ' i mean two times '
Here's an example:
SELECT * FROM pubs WHERE name LIKE "%John's%"
Just use double quotes to enclose the single quote.
If you insist in using single quotes (and the need to escape the character):
SELECT * FROM pubs WHERE name LIKE '%John\'s%'
Possibly off-topic, but maybe you came here looking for a way to sanitise text input from an HTML form, so that when a user inputs the apostrophe character, it doesn't throw an error when you try to write the text to an SQL-based table in a DB. There are a couple of ways to do this, and you might want to read about SQL injection too.
Here's an example of using prepared statements and bound parameters in PHP:
$input_str = "Here's a string with some apostrophes (')";
// sanitise it before writing to the DB (assumes PDO)
$sql = "INSERT INTO `table` (`note`) VALUES (:note)";
try {
$stmt = $dbh->prepare($sql);
$stmt->bindParam(':note', $input_str, PDO::PARAM_STR);
$stmt->execute();
} catch (PDOException $e) {
return $dbh->errorInfo();
}
return "success";
In the special case where you may want to store your apostrophes using their HTML entity references, PHP has the htmlspecialchars() function which will convert them to '. As the comments indicate, this should not be used as a substitute for proper sanitisation, as per the example given.
Replace the string
value = value.replace(/'/g, "\\'");
where value is your string which is going to store in your Database.
Further,
NPM package for this, you can have look into it
https://www.npmjs.com/package/mysql-apostrophe
I think if you have any data point with apostrophe you can add one apostrophe before the apostrophe
eg. 'This is John's place'
Here MYSQL assumes two sentence 'This is John' 's place'
You can put 'This is John''s place'. I think it should work that way.
In PHP I like using mysqli_real_escape_string() which escapes special characters in a string for use in an SQL statement.
see https://www.php.net/manual/en/mysqli.real-escape-string.php

Regex expression to validate a user input

I am building a system where the user builds a query by selecting his operands from a combobox(names of operands are then put between $ sign).
eg. $TotalPresent$+56
eg. $Total$*100
eg 100*($TotalRegistered$-$NumberPresent$)
Things like that,
However since the user is allowed to enter brackets and the +,-,* and /.
Thus he can also make mistakes like
eg. $Total$+1a
eg. 78iu+$NumberPresent$
ETC...
I need a way to validate the query built by the user.
How can I do that ?
A regex will never be able to properly validate a query like that. Either your validation would be incomplete, or you would reject valid input.
As you're building a query, you must already have a way parse and execute it. Why not use your parsing code to validate the user input? If you want to have client-side validation you could use an ajax call to the server.
I need a way to validate the query built by the user.
Personally, I don't think it is a good idea to use regex here. It can be possible with help of some extensions (see here, for example), but original Kleene expressions aren't fit for checking whether unlimited number of parentheses is balanced. Even worse, too difficult expression may result in significant time and memory spent, opening doors to denial-of-service attacks (if your service is public).
You can make use of a weak expression, though: one which is easy to write and match with and forbids most obvious mistakes. Some inputs will still be illegal, but you will discover that on parsing, as Menno van den Heuvel offered. Something like this should do:
^(?:[-]?\(*)?(?:\$[A-Za-z][A-Za-z0-9_]*\$|\d+)(?:\)*[+/*-]\(*(?:\$[A-Za-z][A-Za-z0-9_]*\$|\d+))*(?:\)*)$
Hey guys I managed to get to my ends(Thanks to Anirudh(Validating a String using regex))
I am posting my answer as it may help further visitors.
string UserFedData = ttextBox1.Text.Trim().ToString();
//this is a regex to detect conflicting user built queries.
var troublePattern = new Regex(#"^(\(?\d+\)?|\(?[$][^$]+[$]\)?)([+*/-](\(?\d+\)?|\(?[$][^$]+[$]\)?))*$");
//var troublePattern = new Regex(#"var troublePattern = new Regex(#"^(?:[-]?\(*)?(?:\$[A-Za-z][A-Za-z0-9_]*\$|\d+)(?:\)*[+/*-]\(*(?:\$[A-Za-z][A-Za-z0-9_]*\$|\d+))*(?:\)*)$");
string TroublePattern = troublePattern.ToString();
//readyToGo is the boolean that indicates if further processing of data is safe or not
bool readyToGo = Regex.IsMatch(UserFedData, TroublePattern, RegexOptions.None);

Using regex to find single quoted strings and what is in between them

Currently I'm writing a really simple textbox-to-query parser for SQL queries. One of the things that needs to be done is strings that are placed in single quotes need to be found and properly parameterized. I've Googled it and look page after page for answers, however nothing I can find will help.
Given the query
INSERT INTO PracticeTable
VALUES ('Hello 'World')
or for example,
WHERE users.UserProfiles = 'John's Profile'
I need to figure out a way to
Find the string in single quotes
Extract the string from the inside
I can use a loop to do the parameterization myself.
So to complete the example in the query segment
WHERE users.UserProfiles = 'John's Profile'
I should get a match for 'John's Profile' and then be able to remove the entire string John's Profile from the inside of them.
Can anyone help me? Also, can anyone suggest a better way to receive a query from the user and run it? I'm always looking for suggestions.
Thank you!
Test the following. It will catch the quoted string.
[^']*'(.+)'
=>
WHERE users.UserProfiles = 'John's Profile'
extracted group
John's Profile
I want to mention that your WHERE clause is wrong SQL as your inside ' is not escaped.
As you asked, the quoted string can be captured fairly easy by:
[^']*('.+')

Regex Replace different kinds of single quotes

Those nasty single quotes that love to cause havoc in MySQL, seem to have cousins!!! We have a system where users will to job updates from clients, either pasting in content from emails, or copy and paste from almost anywhere, and every time we cater for one single quote, another pops up. Here are the different ones : ’ ´ ' ` <--
As my regex is pretty weak, my fellow developer said I should just remove them using:
return Regex.Replace(oldText, #"[’´'`""]", #"");
I don't like this, its unprofessional, removing all single quotes. What I want to do, as many forums suggest, is just double up the single quotes. Would this be correct?
return Regex.Replace(oldText, #"[’´'`""]", #"''");
this though is done, because in his DAL, he constructs his insert statements with single quotes:
sql.Append(",`to_complete_by`='" + obj.toCompleteBy + "'");
Would I be able to avoid this error by changing ^^ to this?
sql.Append(",`to_complete_by`=\"" + obj.toCompleteBy + "\"");
or regex replace a preferred method?
If you're working with an old version of MySQL that doesn't support prepared statements, you should at least take advantage of the fact that modern database interfaces can emulate such features of they aren't supported by the database itself. In your case it's not so much the potential performance gain, but the added security though separation of statement syntax and value representations.

Concerns about SQL Server 2008 Full Text Search

I have built a T-SQL query like this:
DECLARE #search nvarchar(1000) = 'FORMSOF(INFLECTIONAL,hills) AND FORMSOF(INFLECTIONAL,print) AND FORMSOF(INFLECTIONAL,emergency)'
SELECT * FROM Tickets
WHERE ID IN (
-- unioned subqueries using CONTAINSTABLE
...
)
The GUI for this search will be an aspx page with a single textbox where the user can search.
I plan to somehow construct the search term to be like the example above (#search).
I have some concerns, though:
Is the example search term above the best or only way to include the inflections of all words in the search?
Should I separate the words and construct the search term in C# or T-SQL. I tend to lean toward C# for decisions/looping/construction, but I want your opinion.
I hate building SQL dynamically because of the risk of injection. How can I guard against this?
Should I use FREETEXTTABLE instead? Is there a way to make FREETEXT look for ALL words instead of ANY?
In general, how else would you do this?
I recently used Full-Text Search, so I'll try to answer some of your questions.
• "I hate building sql dynamically because of the risk of injection. How can I guard against this?"
I used a sanitize method like this:
static string SanitizeInput(string searchPhrase)
{
if (searchPhrase.Length > 200)
searchPhrase = searchPhrase.Substring(0, 200);
searchPhrase = searchPhrase.Replace(";", " ");
searchPhrase = searchPhrase.Replace("'", " ");
searchPhrase = searchPhrase.Replace("--", " ");
searchPhrase = searchPhrase.Replace("/*", " ");
searchPhrase = searchPhrase.Replace("*/", " ");
searchPhrase = searchPhrase.Replace("xp_", " ");
return searchPhrase;
}
• Should I use FREETEXTTABLE instead? Is there a way to make FREETEXT look for ALL words instead of ANY?
I did use FREETEXTTABLE, but I needed any of the words. As much as I've read about it (and I've read quite a bit), you have to use CONTAINSTABLE to search for ALL words, or different combinations. FREETEXTTABLE seems to be the lighter solution, but not the one to pick when you want deeper customizations.
Dan, I like your SanitizeInput method. I refactored it to make it more compact and enhance performance a little.
static string SanitizeInput(string searchPhrase, int maxLength)
{
Regex r = new Regex(#";|'|--|xp_|/\*|\*/", RegexOptions.Compiled);
return r.Replace(searchPhrase.Substring(0, searchPhrase.Length > maxLength ? maxLength : searchPhrase.Length), " ");
}
static string SanitizeInput(string searchPhrase)
{
const int MAX_SEARCH_PHRASE_LENGTH = 200;
return SanitizeInput(searchPhrase, MAX_SEARCH_PHRASE_LENGTH);
}
I agree that FreeTextTable is too lightweight of a solution.
In your example, you have the #search variable already defined. As a rule of thumb, you shouldn't include dynamically concatenated text into raw SQL, due to the risk of injection. However, you can of course set the value of #search in the calling command object from your application. This completely negates the risk of injection attacks.
I would recommend construction of the search term in C#; passing the final search term in as a parameter like already mentioned.
As far as I recall, FREETEXTTABLE uses word breakers to completely decompose the search terms into their individual components. However, the FREETEXTTABLE operator automatically decomposes words into inflectional equivalents also, so you won't have to construct a complex CONTAINSTABLE operator if you decide to use it.
You could INNER JOIN the results of multiple FREETEXTTABLE queries to produce an equivalent AND result.
All of our searches are on columns in the database that have predefined valid characters.
Our search algorithm incorporates this with a regex that only allows these predefined characters. Because of this escaping in the search string is not needed. Our regex weeds out any injection attempts in the web code (asp & aspx). For standard comments from the users, we use escaping that changes all characters that may be used for harm in SQL, ASP, ASPX, & Javascript.
The TransStar site http://latranstar.tann.com/ is using an extended form of Soundex to search for street names, addresses and cities anywhere in Southern California. The Soundex by itself eliminates any need for anti-injection code since it operates only on alpha characters.

Categories

Resources