Preventing SQL Injection in dynamical SQL [duplicate]

笑着哭i 提交于 2019-12-11 17:26:40

问题


I am forced to generate dynamic SQL. I realize it greatly complicates matters to do so, and the below example is silly and obviously does not require dynamic SQL, and is just used to illustrate this question.

Escaping user provided data is not enough, and the 3rd query in the below script is suspect to SQL Injection.

I have found that it is generally easiest to design the application so that all user inputs are integers, and simply typecast their input using (int)$_POST['user_input'].

I now have a need where the user_input needs to be text. What should I do to prevent SQL injection? One option is PHP's ctype_alpha(), however, I don't want "user,input" to result as FALSE, but should either remain as is or be converted to "userinput" (either scenerio is okay for me). I am thinking of something like $user_input= preg_replace('/[^a-z0-9,]/i', '', $_POST['user_input']);. Will this be 100% safe?

EDIT

Note that I am not executing the below query, but inserting it into a database, and as such, prepared statements are not appliable. You might believe that dynamic SQL generation should never be used, but telling me to use prepared statements is not right.

<?php
$id=123;
$query='SELECT * FROM someTable WHERE someColumn="'.$_POST['user_input'].'"';
$sql='INSERT INTO meta_table (id,sql) VALUES (?,?)';
$stmt=db::db()->prepare($sql);
$stmt->execute(array($id,$query));

$sql='SELECT sql FROM meta_table WHERE id=123';
$stmt = db::db()->exec($sql);
$query=$stmt->fetchColumn();

$stmt = db::db()->exec($query); //Prone to SQL Injection
$rs=$stmt->fetchColumn();
?>

回答1:


Ahahah, that's just fantastic!
Finally I managed to understand what does this fella mean under his "dynamical sql". No wonder as it's perfectly disguised and looks like ordinary SQL at both first and second glance!

Here goes the answer:

Don't do it. Ever.

Your idea of "dynamical" SQL is essentially wrong. Nobody does it this way.

I don't know your particular task but your solution is apparently wrong. And there is surely a sane way to do it. Just follow these simple rules:

  • get rid of meta_table
  • get rid of SQL queries stored in database
  • write (or build) all your queries in your application from two sources only:
    • hardcoded SQL, pre-written in your code
    • prepared statements for all the variable parts

and have all your SQL perfectly safe



来源:https://stackoverflow.com/questions/23563440/preventing-sql-injection-in-dynamical-sql

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!