Reputation: 3848
I want to create a Stored Procedure that takes the IDs as inputs, and depending on the list of IDs will behave accordingly.
Example:
DROP PROCEDURE IF EXISTS sp_G;
DELIMITER ;;
CREATE PROCEDURE sp_G (
IN IDs VARCHAR(20) -- Example: '1, 2, 3'
)
BEGIN
SET @Query='SELECT * FROM table_users as t';
IF IDs!=NULL
THEN
SET @Query=CONCAT(@Query, ' WHERE t.ID in(', IDs, ')'); -- SQL Injection problem
END IF;
PREPARE stmt FROM @Query;
EXECUTE stmt;
END ;;
DELIMITER ;
It happens that I have SQL injection in the ‘CONCAT’, because I can’t use the 'EXECUTE stmt USING' IDs as is indicated on the following link: http://dev.mysql.com/doc/refman/5.7/en/sql-syntax-prepared-statements.html
As the IDs parameter is optional, it will only influence the query when is not NULL. However, according to the documentation we assume that this ID parameter will always exist. If IDs parameter has SQL injection, will be executed. Can someone help me? Thanks in advance.
Upvotes: 0
Views: 1232
Reputation: 780974
You can use a regular expression match to check that the parameter only contains allowed characters.
IF IDs IS NOT NULL AND IDs RLIKE '^[0-9, ]+$'
THEN
SET @Query=CONCAT(@Query, ' WHERE t.ID in(', IDs, ')');
END IF
This works for a simple parameter like a list of IDs. It doesn't generalize to more complicated situations, though. The best solution is to design your application so you don't need to substitute user-provided input into the queries in the first place.
For instance, instead of a procedure that takes a comma-separated list of values to match against, the caller could put the information in a temporary table. Then the query would be
SELECT u.* FROM table_users AS u
JOIN temp_table AS t ON u.id = t.id
Upvotes: 1