我认为之前没有发布过 - 因为这是一个非常具体的问题。
我有一个脚本,可以生成一个“创建表”脚本,其中包含自定义类型和名称的自定义列数。
这是一个应该为您提供足够工作的示例 -
$cols = array();
$count = 1;
$numcols = $_POST['cols'];
while ($numcols > 0) {
$cols[] = mysql_real_escape_string($_POST[$count."_name"])." ".mysql_real_escape_string($_POST[$count."_type"]);
$count ++;
$numcols --;
}
$allcols = null;
$newcounter = $_POST['cols'];
foreach ($cols as $col) {
if ($newcounter > 1)
$allcols = $allcols.$col.",\n";
else
$allcols = $allcols.$col."\n";
$newcounter --;
};
$fullname = $_SESSION['user_id']."_".mysql_real_escape_string($_POST['name']);
$dbname = mysql_real_escape_string($_POST['name']);
$query = "CREATE TABLE ".$fullname." (\n".$allcols." )";
mysql_query($query);
echo create_table($query, $fullname, $dbname, $actualcols);
但由于某种原因,当我运行此查询时,它会在MySQL中返回语法错误。这可能与换行符有关,但我无法弄明白。帮助!
答案 0 :(得分:3)
您有多个SQL注入漏洞
mysql_real_escape_string()
仅适用于价值观,而不适用于任何其他内容
你也错了,你需要引用你的值,也就是单引号中的参数。
$normal_query = "SELECT col1 FROM table1 WHERE col2 = '$escaped_var' ";
如果你不mysql_real_escape_string()
将不起作用,你会得到语法错误作为奖励
在CREATE
语句中没有参数,因此转义没有意义,没有任何意义。
您需要将列名列入白名单,因为此代码绝对没有来保护您。
编码恐怖
$dbname = mysql_real_escape_string($_POST['name']); //unsafe
看到这个问题的答案:
How to prevent SQL injection with dynamic tablenames?
切勿在查询中使用\n
使用空格分隔元素。 MySQL非常乐意接受您的查询作为一个长字符串
如果要打印查询,请使用两个空格代替\n
,并在屏幕上显示查询的代码中用换行符替换双空格。
更多SQL注入
$SESSION['user_id']
不安全,建议您将其转换为整数,然后将其提供给查询。因为你无法对白名单进行检查,并且转义表名是没有意义的。
$safesession_id = intval($SESSION['user_id']);
将反引号`
中的所有表名和列名括起来
手写代码不需要这样,但对于自动生成的代码,它是必不可少的。
示例:
CREATE TABLE `table_18993` (`id` INTEGER .....
向大师学习
您可以使用以下MySQL查询在MySQL中生成表的create语句:
SHOW CREATE TABLE tblname;
您的代码需要完全复制此语句的输出。