此PHP代码易受SQL注入攻击吗?
我有一个网站,我在服务器端使用PHP,数据库使用mysql。我使用以下脚本从数据库检索数据。有人能告诉我这个代码是否容易受到注入攻击吗?如果是的话,你能给出一个解决方案吗此PHP代码易受SQL注入攻击吗?,php,mysql,Php,Mysql,我有一个网站,我在服务器端使用PHP,数据库使用mysql。我使用以下脚本从数据库检索数据。有人能告诉我这个代码是否容易受到注入攻击吗?如果是的话,你能给出一个解决方案吗 <?php // PHP script $usrname=$_POST['usrname']; $_SESSION['usremail']=$usrname; $usrpassword=$_POST['passwd']; $db=mysql_select_db('mydb',$connection); $resul
<?php
// PHP script
$usrname=$_POST['usrname'];
$_SESSION['usremail']=$usrname;
$usrpassword=$_POST['passwd'];
$db=mysql_select_db('mydb',$connection);
$result=mysql_query("select usrfname,usrlname from userinformation where usremail='$usrname' and usrpassword='$usrpassword'") or die('failed to login');
当然它很脆弱。您从未对输入进行消毒。尽管mysql_*函数已被弃用,但您仍然可以使用mysql_real\u escape\u string
函数。只需将其应用于变量
$usrname = mysql_real_escape_string($_POST['usrname']);
$usrpassword = mysql_real_escape_string($_POST['passwd']);
是的,它很脆弱。您直接从用户输入中谈论值,并将其放入查询中
您应该查看mysql\u real\u escape\u string
,或者(最好)使用提供参数化查询的MySQLi。SQL注入是由用户数据作为SQL代码而不是数据注入引起的。确保查询安全的唯一真正方法是使用参数化查询,它在协议级别分离数据和查询文本
此外,您的密码以明文形式存储。您应该使用salted散列函数作为绝对最小值
你还应该看看这些可怕的问题:
是的,是的
改为这样做:
$usrname=$_POST['usrname'];
$_SESSION['usremail']=$usrname;
$usrname=mysql_real_escape_string($usrname);
$usrpassword=mysql_real_escape_string($_POST['passwd']);
$db=mysql_select_db('mydb',$connection);
$result=mysql_query("select usrfname,usrlname from userinformation where usremail='$usrname' and usrpassword='$usrpassword'") or die('failed to login');`
您还应该查看准备好的语句。对要在查询中使用的用户生成字符串使用mysql\u real\u escape\u string()
$usrname = mysql_real_escape_string($_POST['usrname']);
$usrpassword = mysql_real_escape_string($_POST['passwd']);
$db=mysql_select_db('mydb',$connection);
$result = mysql_query("SELECT usrfname, usrlname FROM userinformation WHERE usremail='$usrname' AND usrpassword='$usrpassword'") or die('failed to login');
// Set session data only if login is successful
$_SESSION['usremail']=$usrname;
是的,您不应该接受用户输入(来自表单(POST数据),作为url(获取数据)的一部分甚至一个cookie没有首先检查它也是你所期望的。例如,你的用户名可能由a到z组成,可能有一个允许的点。因此,在你让输入文本靠近数据库之前,你要检查它包含的全部内容。Google preg_匹配
您需要在服务器端执行此操作,仅在浏览器中使用javascript是不够的
我还将密码存储为用户注册时输入的md5哈希值,因此您在注册时获得$password,检查它的字符范围是否有限,执行$hass_pw=md5($password),并将$hash_pw存储在d/b中。然后,当用户登录时,再次对其进行哈希,并在查询中使用它。(为了清楚起见,我省略了$hass_POST)
例如:
这是测验中的一个问题吗?$usrname
的值从何而来?如果有的话,它是如何被“保护”的?是的,这很容易被注入。而且,它看起来像是以明文形式存储密码;这不是一个好主意。当你否决一个问题时,给出一个理由。这是一个非常好的问题,绝对不是“太本地化”@pst:in$\u POST
它必须来自一个表单,我看不到任何(严肃地)保护它的方法。@nico因此引用。此外,还有多种类型的“保护”唯一适用于SQL注入的是确保语句结构不被更改的类型;但是,可能存在其他非SQL注入使用问题(占位符是解决此问题的通用解决方案)或者像现在一样使用参数化查询。一些mysql_uuu函数已经被弃用,但不是全部。当然,使用PDO或MySQLi将是一个更好的解决方案。请记住,mysql_ureal_uescape_ustring
并不是不可靠的。它只是对必须转义的字符执行黑名单筛选。它可以不将数据与查询语言分离。因此,我可以将1=1
传入,并使其完全破坏查询逻辑。如果您想真正防止SQL注入,我真的希望您这样做,那么您必须使用一种机制,将查询语言与输入数据完全分离—MySQLi和PDO中的参数化查询多项式:你能举个例子说明如何传递1=1吗?mysql\u real\u escape\u string
删除了所有单引号,所以你的1=1在查询中总是“1=1”,只是一个字符串,不是吗?请不要提倡使用不推荐使用的函数。准备好的语句是防止SQL注入的唯一方法攻击。mysql\u real\u escape\u string()
不是一个不推荐使用的函数,虽然预处理语句使生活更轻松,但它不是提供SQL注入安全性的唯一方法,它只允许您编写更草率的代码。;)是开始研究“预处理语句”的一个地方阅读30秒后,您就会明白为什么这会给您带来安全性上的巨大飞跃。@fhugas但是mysql\u query
不受欢迎,PHP开发人员建议不要使用老式的过程查询函数。mysql\u real\u escape\u string
函数对SQL注入也不是100%有效。例如,如果使用“从id=”的用户中选择*。mysql\u real\u escape\u string($\u GET['id'])
,我可以将1=1
注入id字段,并让查询返回所有值。潜在的安全问题:)呵呵,但它仍然没有被弃用;)看起来您忘记在查询中引用该输入了““从id=”的用户中选择*”。mysql_real_escape_字符串($_GET['id'])。“”;现在您无法注入任何内容:)正如我在其他答案中所说的,不要使用旧的不推荐使用的函数。如果您想要任何安全性的假象,准备好的语句是唯一的方法。+1对于“使用…参数化查询”,它讨论如何清理输入(这只是一个副作用,即特定匹配是有效防止SQL注入攻击的字符子集)。然而,它并没有谈到SQL注入。SQL注入是一种特定的漏洞,可在其中更改SQL查询的结构。可能还有其他漏洞和/或违反业务规则的方式需要解决,这就是本答案所涵盖的。MD5存储密码?不,这是不安全的,而且在很长一段时间内,甚至考虑到发布的日期。你真的不应该使用PHP来处理密码安全问题。确保你
if preg_match(/"[^a-z]/i", $_POST['usrname'])
print "bad username format)
else
{
// good format username, safe to use in query
}