I’m attempting to write a stored procedure in MySql that will take a single parameter, and then check that parameter for any text that contains ‘DROP’,’INSERT’,’UPDATE’,’TRUNCATE’, etc., pretty much anything that isn’t a SELECT statement. I know it’s not ideal, but, unfortunately the SELECT statement is being built client-side, and to prevent some kind of man-in-the-middle change, it’s just an added level of security from the server.
I’ve tried doing several means of accomplishing it, but, it’s not working for me. I’ve come up with things similar to this:
CREATE PROCEDURE `myDatabase`.`execQuery` (in INC_query text)
BEGIN
#check to see if the incoming SQL query contains INSERT, DROP, TRUNCATE,
#or UPDATE as an added measure of security
IF (
SELECT LOCATE(LOWER(INC_query),'drop') OR
SELECT LOCATE(LOWER(INC_query),'truncate') OR
SELECT LOCATE(LOWER(INC_query),'insert') OR
SELECT LOCATE(LOWER(INC_query),'update') OR
SELECT LOCATE(LOWER(INC_query),'set')
>= 1)
THEN
SET @command = INC_query;
PREPARE statement FROM @command;
EXECUTE statement;
ELSE
SELECT * FROM database.otherTable; #just a generic output to know the procedure executed correctly, and will be removed later. Purely testing.
END IF;
END
Even if it contains any of my “filterable” words, it still executes the query. Any help would be appreciated, or if there’s a better way of doing something, I’m all ears.
What if you have a column called
updated_atorsettings? You can’t possibly expect this to work as you intend. This kind of technique is the reason there’s so many references to clbuttic on the web.You’re really going to make a mess of things if you go down this road.
The only reasonable way to approach this is to send in the parameters for the kind of query you want to construct, then construct the query in your application using a vetted white list of allowed terms. An example expressed in JSON:
You just need to create a query constructor that emits this kind of thing, and another that converts it back into a valid query. You might want to list only particular columns for querying, as certain columns might be secret or internal only, not to be disclosed, like
password_hashin this example.You could also allow for patterns like
(SUM|MIN|MAX|AVG)\((\w+)\)to capture specific grouping operations orJOINconditions. It depends on how far you want to take this.