MySQL注入解决方案
我被MySQL注入困扰了很长时间,一直在想一种方法来完全消除这个问题。我提出了下面的一些内容,希望很多人会发现这很有用。
我能想到的唯一缺点是部分搜索: Jo => 通过使用 like %% 语句返回“John”。
这是一个 php 解决方案:
<?php
function safeQ(){
$search= array('delete','select');//and every keyword...
$replace= array(base64_encode('delete'),base64_encode('select'));
foreach($_REQUEST as $k=>$v){
str_replace($search, $replace, $v);
}
}
safeQ();
function html($str){
$search= array(base64_encode('delete'),base64_encode('select'));
$replace= array('delete','select');//and every keyword...
str_replace($search, $replace, $str);
}
//example 1
...
...
$result = mysql_fetch_array($query);
echo html($result[0]['field_name']);
//example 2
$select = 'SELECT * FROM $_GET['query'] ';
//example 3
$insert = 'INSERT INTO .... value( $_GET['query'] )';
?>
我知道,我知道您仍然可以使用 1=1
或任何其他类型的注入进行注入... 但我认为这可以解决你一半的问题,因此执行正确的 mysql 查询。
所以我的问题是,如果有人能发现这方面的任何缺点,请随时在这里发表评论。
仅当您认为这是一个非常有用的解决方案并且没有发现重大缺点或者您认为这是一个坏主意时,请给出答案...
I have been bothered for so long by the MySQL injections and was thinking of a way to eliminate this problem all together. I have came up with something below hope that many people will find this useful.
The only Draw back I can think of this is the partial search:
Jo =>returns "John" by using the like %% statement.
Here is a php solution:
<?php
function safeQ(){
$search= array('delete','select');//and every keyword...
$replace= array(base64_encode('delete'),base64_encode('select'));
foreach($_REQUEST as $k=>$v){
str_replace($search, $replace, $v);
}
}
safeQ();
function html($str){
$search= array(base64_encode('delete'),base64_encode('select'));
$replace= array('delete','select');//and every keyword...
str_replace($search, $replace, $str);
}
//example 1
...
...
$result = mysql_fetch_array($query);
echo html($result[0]['field_name']);
//example 2
$select = 'SELECT * FROM $_GET['query'] ';
//example 3
$insert = 'INSERT INTO .... value( $_GET['query'] )';
?>
I know, I know that you still could inject using 1=1
or any other type of injections...
but this I think could solve half of your problem so the right mysql query is executed.
So my question is if anyone can find any draw backs on this then please feel free to comment here.
PLEASE GIVE AN ANSWER only if you think that this is a very useful solution and no major drawbacks are found OR you think is a bad idea all together...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这已经在 PHP 中正确实现了:
但是,您应该首先阅读 PHP手动录入关于SQL注入。
为了回答您的实际问题,您的方法的主要缺点是:
如果您要重新发明轮子,我建议您查看现有的轮子。
This has already been implemented correctly in PHP:
However, you should start by reading the PHP manual entry on SQL injection.
To answer your actual question, the primary drawbacks of your approach are:
If you're going to reinvent the wheel, I would recommend looking at pre-existing wheels.
重新发明轮子并以错误的方式重新发明它(TM)。
'SELECT * FROM ' 的内容。 safeQ($_GET['query'])
编辑:要解决您在评论中给出的示例:
Reinventing the wheel and reinventing it the Wrong Way (TM).
'SELECT * FROM ' . safeQ($_GET['query'])
Edit: To address the example you're giving in comments:
这是一个坏主意。
对于每种语言、平台、运行时、引擎、库,无论你可能拥有什么,都已经有一个适当的、正确的、有效的 SQL 注入解决方案。
这就是所谓的参数。
您无需将值作为文字常量放入 SQL 中,而是添加参数占位符,然后在查询旁边提供参数值,并且也不使用任何格式化技巧将其返回到 SQL 中。
所有其他试图通过查看 SQL 或其片段并尝试确定它是否正确来“修复”问题的解决方案都是低于标准的,并且其中大多数都有其他您看不到的错误和问题,不要这样做不知道,也不想真正拥有。
因此,不要再拐弯抹角了,从一开始就以正确的方式去做。切换到使用参数。
在 PHP 中,与 MySQL 对话有多种方法,但使用 mysqli 库:
如果这里的 $id 变量包含不安全代码,则会导致 SQL 执行崩溃,因为如果 id 是整数,则无法与除此之外的任何内容进行比较另一个整数,如果它是字符串,它将与您提供的字符串进行比较,而不是尝试将该字符串作为 SQL 的一部分执行。
现在,评论指出了一点,有时你无论如何都必须更改 SQL,因为你将提供动态排序(即用户选择的排序)或动态过滤(即要应用的过滤器由用户选择) 。
在这种情况下,解决方案很简单:不要获取任何用户提供的文本并将其放入 SQL。相反,您可以将要添加到 SQL 的常量硬编码到代码中,并让用户选择指导代码添加哪些常量、添加顺序以及添加位置。
It is a bad idea.
There is already a proper, correct, and working, solution to SQL injection in every language, platform, runtime, engine, library, whateveryoumighthave.
It's called parameters.
Instead of placing the value into the SQL as a literal constant, you add a parameter placeholder, and then provide the paramter value alongside the query, and not using any formatting tricks to get it back into the SQL either.
Every other solution which tries to "fix" the problem by looking at the SQL or pieces of it and attempting to determine if it is correct is sub-par and most of them has other bugs and problems that you can't see, don't know about, and don't really want to have.
So stop beating around the bush, and do it the right way to begin with. Switch to using parameters.
In PHP, talking to MySQL, there are multiple ways, but using the mysqli library:
If the $id variable here contains unsafe code, it will make the SQL Execution crash, because if id is an integer, it cannot be compared to anything but another integer, and if it is a string, it will be compared against the string you provide, not trying to execute the string as part of the SQL.
Now, the comment brings out a point, sometimes you have to change the SQL anyway, because you will provide dynamic ordering (ie. ordering picked by the user), or dynamic filtering (ie. which filters to apply are picked by the user).
In this case, the solution is simple: Do not take any user-provided text and place it into the SQL. Instead, you hard-code the constants to add to your SQL into your code, and let the users choices guide the code in which of those constants to add, in which order, and where.