1

I'm working on a stored procedure that generates a query dynamically based on values of input parameters. The sp uses the CONCAT() function within mysql for building the query. One of the parameters allows a user to enter a search string as a varchar datatype.

Is there function within mysql similar to php's mysql_real_escape_string() that will prevent sql injection attacks?

Below is an example of what this sp is doing:

// trying to post code. keep getting denied. not telling me why. enter image description here

5
  • paste the code as clear text, then we can help you on formatting Commented Nov 1, 2017 at 20:01
  • 1
    mysql_real_escape_string() DOES NOT prevent sql injection attacks. Commented Nov 1, 2017 at 20:01
  • @Alfabravo I'm unable to add it as plain text either. When clicking submit button I'm met with message stating "An error occurred submitting the edit" no matter how it's formatted. Commented Nov 1, 2017 at 20:05
  • Try again below the "comment line"... make sure that it's not too large! :) Commented Nov 1, 2017 at 20:09
  • @Alfabravo Same response. However I was able to upload a screenshot. Any reason you know of why it's not letting this particular block of code upload? Commented Nov 1, 2017 at 20:14

2 Answers 2

3

Re your comment:

I agree with you, however how can you add specific parts to the prepared statement based on inputs. For example, if parameters _A and _B are available, then JOIN two additional tables and include a WHERE statement? Then know which version of the query the prepared statement is being run for to know which parameters need to be bound?

Sometimes you have to use conditional blocks of code:

CREATE PROCEDURE MyProc(IN _A INT, IN _B INT) BEGIN IF _A IS NOT NULL AND _B IS NOT NULL PREPARE stmt1 FROM 'SELECT * FROM MyTable WHERE A = ? AND B = ?'; SET @A = _A, @B = _B; EXECUTE stmt1 USING @A, @B; DEALLOCATE PREPARE stmt1; ELSEIF _A IS NOT NULL PREPARE stmt1 FROM 'SELECT * FROM MyTable WHERE A = ?'; SET @A = _A; EXECUTE stmt1 USING @A; DEALLOCATE PREPARE stmt1; ELSEIF _B IS NOT NULL PREPARE stmt1 FROM 'SELECT * FROM MyTable WHERE B = ?'; SET @B = _B; EXECUTE stmt1 USING @B; DEALLOCATE PREPARE stmt1; END END 

For your example with conditional LIMIT and OFFSET, you could do it more simply. There is no SQL injection risk from input parameters that are constrained to the INT data type. Then you can default the variables with some sensible value by using COALESCE().

CREATE PROCEDURE MyProc(INT _quick_search VARCHAR(50), IN _limit INT, IN _offset INT) BEGIN SET @LIMIT = COALESCE(_limit, 1); SET @OFFSET = COALESCE(_offset, 0); PREPARE stmt1 FROM 'SELECT ...blah blah... LIMIT ? OFFSET ?'; EXECUTE stmt1 USING @LIMIT, @OFFSET; DEALLOCATE PREPARE stmt1; END 

I agree with the statement from @YourCommonSense that stored procedures are not the best solution. MySQL's implementation of stored procedures is primitive and hard to use. I see many questions on Stack Overflow asking questions about how to do some task in stored procedures in MySQL, and it makes me cringe every time.

You'd be better off using virtually any other scripting language instead of using MySQL stored procedures.

Sign up to request clarification or add additional context in comments.

1 Comment

"You'd be better off using virtually any other scripting language instead of using MySQL stored procedures" <-- Thank you for confirming this!
3

Never use CONCAT() function for building the query.

Use. Prepared. Statements.

PREPARE stmt1 FROM 'SELECT * FROM whatever WHERE something LIKE ?'; EXECUTE stmt1 USING @search_parameter; DEALLOCATE PREPARE stmt1; 

4 Comments

Don't forget to deallocate it once you're done with it, otherwise it might hang around and you could eventually run into a limit
I agree with you, however how can you add specific parts to the prepared statement based on inputs. For example, if parameters _A and _B are available, then JOIN two additional tables and include a WHERE statement? Then know which version of the query the prepared statement is being run for to know which parameters need to be bound?
I have no idea. I would never do it using a stored procedure in the first place. But you can try to implement something like this
Given your picture, I don't see any problem using a placeholder for your search.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.