Tips on Preventing SQL Injection Attacks
To sanitize form input for sending to a database, always be sure to escape the single quote by searching and replacing it with two single quotes. This will cause the database to send the quote string as a literal character rather than interpreting it as the closing of a string. Be aware, however, that since numeric input does not require quotes, this technique will not be effective. In the case of numeric input, simply check that the form input is indeed numeric.
One method of preventing SQL injection is to avoid the use of dynamically generated SQL in your code. By using parameterized queries and stored procedures, you then make it impossible for SQL injection to occur against your application.
- Escape single quotation marks. Include code within your Web applications that replaces single apostrophes with double apostrophes. This will force the database server to recognize the apostrophe as a literal character rather than a string delimiter.
- Filter user input. Filtering user input before it is passed into a SQL query will prevent the possibility of executing SQL commands. (ex. Strip input strings of all characters that are not alphanumeric (a-z, A-Z or 0-9))
- Limit the privileges available to the account that executes Web application code. For example, if an account only had permission to perform the intended action (retrieving records from a table), then delete, insert or create queries would not be possible.
- Reduce or eliminate debugging information. When an error condition occurs on your server, the Web user should not see technical details of the error. This type of information could aid an intruder seeking to explore the structure of your database.
- Note to PHP users connecting to MySQL databases
There are at least two ways to make MySQL queries safe using PHP. The first, and often simplest, method is to use mysql_real_escape_string on each variable used in a MySQL query. Please see the <a href="http://php.net/mysql_real_escape_string">PHP documentation</a> for more information.
The second method is to use prepared statements. You can do this using the MySQL Improved Extension in PHP 5. For more information, please refer to the <a href="http://php.net/manual/en/book.mysqli.php">PHP documentation</a> for more information.
ColdFusion - Prevent SQL Injection with cfqueryparam
By using cfqueryparam you can prevent SQL injection into your database via un-sanitized input.
Here is some sample code that is not safe:
<cfquery name="myQueryName" DATASOURCE="#Application.MyDSN#"> INSERT INTO myTable(customer_fname) VALUES ('#form.customer_fname#') </cfquery>
The example above clearly just takes input from a form and inserts it into the database. That is VERY dangerous.
Instead, here is a the proper way to do this, by sanitizing the form input with cfqueryparam:
<cfquery name="myQueryName" DATASOURCE="#Application.MyDSN#"> INSERT INTO myTable(customer_fname) VALUES (<cfqueryparam value='#form.customer_fname#' cfsqltype="cf_sql_varchar">) </cfquery>
NOTE: It is important to match the cfsqltype value with the proper data type for that field.
Cleaning your MS SQL Database after a SQL Injection Attack
To clean a MSSQL Database from SQL Injection, a Stored Procedure can be used.
1. Using SQL Server Management Studio, copy and paste the code below into the SQL tool and execute. This will create the SearchAndReplace stored procedure that will allow you to clean your MSSQL Database.
CREATE PROC SearchAndReplace ( @SearchStr nvarchar(100), @ReplaceStr nvarchar(100) ) AS BEGIN -- Copyright c 2002 Narayana Vyas Kondreddi. All rights reserved. -- Purpose: To search all columns of all tables for a given search string and replace it with another string -- Written by: Narayana Vyas Kondreddi -- Site: http://vyaskn.tripod.com -- Tested on: SQL Server 7.0 and SQL Server 2000 -- Date modified: 2nd November 2002 13:50 GMT SET NOCOUNT ON DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128), @SearchStr2 nvarchar(110), @SQL nvarchar(4000), @RCTR int SET @TableName = '' SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''') SET @RCTR = 0 WHILE @TableName IS NOT NULL BEGIN SET @ColumnName = '' SET @TableName = ( SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName AND OBJECTPROPERTY( OBJECT_ID( QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) ), 'IsMSShipped' ) = 0 ) WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL) BEGIN SET @ColumnName = ( SELECT MIN(QUOTENAME(COLUMN_NAME)) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = PARSENAME(@TableName, 2) AND TABLE_NAME = PARSENAME(@TableName, 1) AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar') AND QUOTENAME(COLUMN_NAME) > @ColumnName ) IF @ColumnName IS NOT NULL BEGIN SET @SQL= 'UPDATE ' + @TableName + ' SET ' + @ColumnName + ' = REPLACE(' + @ColumnName + ', ' + QUOTENAME(@SearchStr, '''') + ', ' + QUOTENAME(@ReplaceStr, '''') + ') WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2 EXEC (@SQL) SET @RCTR = @RCTR + @@ROWCOUNT END END END SELECT 'Replaced ' + CAST(@RCTR AS varchar) + ' occurence(s)' AS 'Outcome' END GO
2. Within Management Studio type or copy/paste the following to replace all occurrences of '<script>badurl.com<script>' with :
EXEC SearchAndReplace '<script>badurl.com<script>', ''
3. Execute the command above, note for smaller databases this will run quickly but for larger databases it could take a long time to complete.