这是我的login.php的基本代码。它包含一个从表单中获取值的基本$_POST方法。有人说它不安全。易发生SQl注射液。我不想让它变得复杂。请告诉我如何用简单的方法使它更安全。
<?php
session_start();
require('connection.php');
$email=$_POST['username'];
$password=$_POST['password'];
//variables in query will be in single quotes.
$query="select * from user_info where email='$email' and password = '$password' ";
//fetching result
if($result=$con->query($query))
{
$row =$result->fetch_array(MYSQLI_NUM);
if($row>0)
{
//creating session variables
$_SESSION['loggedIn']=true;
$_SESSION['email']=$row[1];
$_SESSION['id']=$row[0];
header("Location:profile.php");
}
else
{
echo "flag1";
header("Location:index.php?loginerror=invalid login");
}
}
else {
echo "Failed";
}
?>
数据库的危险:SQL注入
当使用来自用户的输入数据来操作数据库时,这些都是危险的。某些输入可能会导致sql语法中断,数据库将得到一个格式错误的语句并运行到错误中(如果是无意的),甚至执行不应该执行的语句(sql注入)。
意外语法破坏的一种可能性是询问用户的名字,然后他插入类似O’Connor的内容。
处理方法:如何防止PHP中的SQL注入?准备好的声明才是王道。
(+)我想你的应用程序和数据库之间的大多数ORM或抽象层都会自己解决这个问题,应该告诉自己这件事——安全总比抱歉好。
前端的危险:XSS攻击
用户使用您的表单输入一些JavaScript。当你在网站上显示它时,它会被解析并执行。
处理方法:在显示用户数据时使用htmlenties()。
(+)有像htmlpurifier这样的库,它只允许您对特定元素进行消毒。因此,如果你想让你的用户在博客文章或其他什么中使用HTML,你可以创建这样的库,它将允许某些元素并消除危险的东西。
文件系统的危险:shell注入(?)
当您出于某种原因使用用户输入在文件系统上执行某些操作时(创建一个与用户名或其他名称相同的目录),有人可以执行与sql中相同的操作-破坏您的语法并注入一些命令。
处理方法:escapeshellcmd+不要使用用户输入来处理服务器上的目录或文件名!将用户的名称放入数据库中,使用id或哈希或您生成的东西作为文件名。
跨站点请求伪造:
不直接涉及提供给您的数据,但我添加它是因为它是您应该了解的内容:了解CSRF
记住:根据使用数据的上下文处理数据
攻击有不同的地方,每个地方都使用其他弱点。因此,没有一个解决方案可以解决所有问题。
你只需要考虑你处理数据的上下文——你是保存还是显示它
在显示它时,您需要注意可能隐藏在数据中的JavaScript,因此您需要转义html中特殊的字符。
在保存数据时,您只担心可能破坏sql语法的字符。您的数据库最清楚应该转义哪些字符以及如何处理哪些数据,因此只需使用数据库api提供的转义和引用函数或更好的:准备好的语句(在与数据库+用户数据交互时始终使用它们),因为它们的工作方式与正常查询不同,您不必考虑转义和引用。
我会使用PDO。一个非常基本的例子;
<?php
session_start();
require('connection.php');
$sError = "";
$sEmail = "";
$sPassword = "";
if(isset($_POST['Login'])){
if(isset($_POST['username'])) $sEmail = $_POST['username'];
if(isset($_POST['password'])) $sPassword = $_POST['password'];
if($sPassword != '' && $sEmail == ''){
// create an instance of the connection
$conn = new PDO( DB_DSN, DB_USERNAME, DB_PASSWORD );
// prepare the sql
$sSQL = "SELECT Email, Id from user_info where email=:email and password = :password ";
$st = $conn->prepare( $sSQL );
// bind the input vars
$st->bindValue(":email", $sEmail, PDO::PARAM_STR);
$st->bindValue(":password", $sPassword, PDO::PARAM_STR);
$st->execute();
// if data is returned from calling fetch
if( $row = $st->fetch() ){
$_SESSION['loggedIn'] = true;
$_SESSION['email'] = $row['Email'];
$_SESSION['id'] = $row['Id'];
header("Location:profile.php");
exit;
}
}else{
// must have empty input add to errror string
$sError .= "[EmptyInput]";
}
// user hasnt been logged in set error
$sError .= "[InvalidLogin]";
}
// detect anthign in error stirng
if($sError != ""){
// do something
}
?>
Havent测试过,但应该有效。
我也会对你的密码进行加盐和加密。
此外,我将生成一个代码,用于公开识别用户。