I have a web-form with a Name field which I want to be able to accept single apostrophes, such as in the name O'Leary, but when trying to push this record to the SQL 2005 server, I get an error. My question is not this. It's that when I attempt to insert the record into the db using this statement...
Dim acctName As String = Replace(txtName.Text, "'", "''")
I get O''Leary in the database instead of O'Leary. Thought SQL was supposed to treat these double single apostrophes as one apostrophe???
You'd be better off using parameterized queries. These will automatically handle the single quotes, and protect you better from SQL Injection.
Inserting the double single quotes (did I say that right?) is a way of escaping the data. It should work, but it's not a best practice.
See this article for a much fuller answer:
http://msdn.microsoft.com/en-us/library/ff648339.aspx
What I'm proposing is step 3.
Edit - I should read the question better
If you're already using parameterized queries, or a stored procedure, and you're setting the value of acctName to the value of a parameter, then you do not need to escape the quotes yourself. That's handled automatically.
It's also handled by several tools, including the Mirosoft Patterns and Practices Database library. That has several commands where you can pass in a statement and array of objects that are used as parameter values -that handles the escaping as well.
If either of those are the case, you can completely eliminate the line of code where you're replacing the values.
Depends how you're INSERTing the data into the database.
If you're using dynamic SQL and building the SQL string yourself, you are responsible for doubling the quotes yourself. But if you're using a parameterized query (as you should be, and probably are) then the engine will take care of that for you and, if you double the quotes yourself, you'll get doubled quotes in the database.
Note, if you started with dynamic SQL and switched to paramterized queries, this issue would suddenly appear at the time you made the change.
Off-the-cuff, without knowing too much detail I'd recommend checking the SET QUOTED_IDENTIFIER setting on the SQL Server. More information can be found here. Let me know if this helps.
It highly depends what query you actually submit. If you submit '' then this is what will be saved. You do need to double the ' but for other reasons (mainly security, but of course also syntax validity).
Please submit the code that you use to submit the query.
Related
I'm using this code (python using sqlite3) to add data to the table:
''' INSERT INTO TABLE (USERNAME) VALUES ("''' + data + '''")'''
If I block ", then (to the best of my knowledge) it should be impossible to exit the string, subsequently making it impossible to SQL inject.
My questions are these:
Does this stop users from being able to inject SQL?
If no, should I add more to the blacklist or create a whitelist?
All help is greatly appreciated.
If you sterilize data before letting it hit the insert statement, making sure that single quotes do not appear anywhere, then in theory SQL injection is not possible. Whatever data gets injected should just be treated a string literal, rendering any injected SQL commands ineffective. However, there may still be ways for an attacker to work around this.
Your best best here would be to just rely on using prepared statements to avoid SQL injection. Attackers keep getting smarter, and there might still be a way to inject your current insert statement from some other means.
It appears that SQLite, apparently as a "compatibility feature", parses double quoted identifiers as string literals if no matching column is found.
I understand that it does so for people who write improper sql, and for backwards compatibility with legacy projects created by such people, but it makes debugging very difficult for those of us writing proper sql on brand new projects.
For example,
SELECT * FROM "users" WHERE "usernme" = 'joe';
returns a query with 0 rows, since the string 'usernme' does not equal the string 'joe'.
This leaves me scratching my head wondering why i'm not getting joe's row even when i know there's a user by that name until I painstakingly backtrack my code and realize that I left out an a.
Is there any "strict mode" PRAGMA or API option to enforce quoting rules and treat all double-quoted strings as identifiers so that it will inform me immediately if one is misspelled?
(And please, no answers telling me not to quote identifiers if I don't need to, because any such answer is basically telling me that in order to get proper debugging, you have to write bad code in the first place.)
This is hardcoded in the SQLite parser and cannot be changed from the outside.
I also asked in the SQLite channel and someone there was kind enough to look through the source code and create a patch, and even started a thread on the mailing list describing the patch:
http://www.mail-archive.com/sqlite-users#sqlite.org/msg73832.html
It's not an answer that works for the official builds, but it may be someday. For the moment, I'm just going to recompile it myself with this patch.
Ten years later, and this doesn't completely meet your criteria about "strict mode" kinds of things, but here's a trick I used to make some queries safer, if you can remember to use it. It's to give your table an alias and reference it:
SELECT t."nosuch_column" FROM some_table t;
I suppose in this form, it's clear to SQLite that a literal isn't desired.
I have used parameterized query number of times I know it helps in preventing SQL injection.
But, I was wondering if I can know what is basic logic working inside a parameterized query
to prevent SQL injection may be it is very simple but I don't know about it. I tried to search google what are the basic of it but every time I found an example that how to use parameterized query in Asp.net.
I know about making a special class which stops those special characters like (',-- etc) which are used in SQL injection, but does stopping only special characters totally prevent SQL injection?
And one last thing does .net parameterized query can fully stop SQL injection?
I think parametrized queries are not dependent on prepared queries database support. Database driver itself passing values the safe way, and how is it done depends on driver itself.
The PostgreSQL manual explains basics about parametrized queries on database level.
On the other hand, parametrized queries simplifies you passing locale sensitive data.
For example, user enters 100,00 decimal, but your server expects 100.00 value.
In every database engine I know, using "prepared" (aka "parametrized", or "static") queries prevents SQL injection. You don't need to filter any characters if they're being passed to parameters. If you ever write SQL that is concatenated together in code rather than prepared with parameters, you are probably at risk for SQL injection. You should the security manual for the database you're using, it will very likely have a section on SQL injection, but just read all of it. I bet it will take under an hour and will give you solid instruction and confidence that you're following best the practices that apply to your database.
I'm currently looking at a terrible legacy ColdFusion app written with very few stored procedures and lots of nasty inline SQL statements (it has a similarly bad database too).
Does anyone know of any app which could be used to search the files of the app picking out any SQL statements and listing the tables/stored procedures which are referenced?
Dreamweaver will allow you to search the code of the entire site. If the site is setup properly including the RDS password and provide a data source it can tell you a lot of information. I've only set it up once so I can't remember exactly what information it gives you, I think maybe just the DB structure. Application window > databases. Even if it isn't set up properly just searching for "cfquery" will quickly find all your queries.
You could also write a CF script using CFDirectory/CFFile to loop the .cfm files and parse everything between cfquery and /cfquery tags.
CFBuilder may have some features like that but I'm not to familiar with it yet.
edit I've heard that CFBuilder can't natively find all your cfqueries that don't have cfqueryparam but you can use CF to extend CFB to do so. I imagine you could find/write something for CFB to help you with your problem.
another edit
I know it isn't indexing the contents of the query, but you can use regex to search using the editor as well. searching for <cfquery.+(select|insert|update|delete) checking the regex box should find the queries that aren't using cfstoredProc (be sure to uncheck the match case option if there is one). I know Dreamweaver and Eclipse can both search for Regex.
HTH
As mentioned above I would try a grep with a regex looking for
"<cfquery*" "</cfquery>" and "<cfstoredproc*" "</cfstoredproc>"
In addition if you have tests that have good code coverage or even just feel like the app is fully exercised in production you could try turning on "Log Database Calls" in Admin - > Datasources or maybe even at the JDBC driver level, just monitor performance to make sure it does not slow the site down unacceptably.
In short: no. You'd have to do alot of tricky parsing to make sure you get all the SQL. And because you can glob SQL together from lots of strings, you'll almost always miss some of it.
The best you're likely to do will be a case insensitive grep for "SELECT|INSERT|UPDATE|DELETE" and then manually pulling out the table names.
Depending on how the code is structured, you might be able to get the table names by regexing the SQL from clause. But that's not foolproof. Alot of people use string concatenation to build SQL statements. This is bad because it can introduce SQL injection attacks, and it also make this particular problem harder.
Regardless of the sql database collation being used is there any way to replace the special characters when displayed in the interface. At least is there any way to implement that for the "Turkish I" so discussed here :-) I want to eliminate small dotless 'i'.
What about a simple String.Replace for the characters you dont want?
You can either keep the original data in the database and do this when the page renders or you can do this before saving the data to the database.