这是我的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";
}
&GT;
答案 0 :(得分:3)
数据库的危险:SQL注入
使用来自用户的输入数据来操作数据库时存在危险。某些输入可能会导致sql语法中断,数据库将获得格式错误的语句并运行错误(如果是无意的),甚至执行不应该执行的语句(sql注入)。
意外语法破坏的可能性是询问用户他的名字,并插入像O'Connor这样的东西。
对待他们的方式:How can I prevent SQL injection in PHP? tldr:准备好的陈述是王道。
(+)我猜你的应用程序和你的数据库之间的大多数ORM或抽象层都可以自己解决这个问题,应该告诉自己这个问题 - 比抱歉更安全。
前端的危险:XSS攻击
用户使用您的表单输入一些JavaScript。当您在网站上显示它时,它将被解析并执行。
对待它们的方法:在显示userdata时使用htmlentities()。
(+)有像htmlpurifier这样的库,它们只允许您清理特定元素。因此,如果你想让你的用户使用HTML作为博客帖子或其他任何东西,你可以使用这样的库来允许某些元素并化解危险的东西。
文件系统的危险:shell-injections(?)
当你出于某种原因使用用户输入在你的文件系统上做某事时(创建一个与用户名或其他名称相同的目录),有人可以像在sql中那样做 - 破坏你的语法并注入一些命令
对待它们的方法:escapeshellcmd +不要在服务器上使用用户输入来代替目录或文件名!将用户名放入数据库,使用id或哈希或生成的文件名作为文件名。
跨网站请求伪造:
不直接涉及提供给您的数据,但我添加它是因为您应该了解它:Understanding CSRF
记住:根据您使用它的上下文处理数据!
攻击有不同的地方,每个地方都有其他弱点。因此,没有一种方法可以解决所有问题。
您只需要考虑处理数据的上下文 - 保存或显示数据。
在显示它时,你想要处理可能隐藏在数据中的JavaScript,这样你就可以逃避html中特有的字符串。
保存数据时,您只担心可能会破坏sql语法的字符。您的数据库最清楚哪些字符串可以逃脱以及如何处理哪些数据,因此只需使用数据库提供的转义和引用功能-api 或更好:准备好的语句(只需在与数据库+ userdata交互时使用它们) ,因为它们与普通查询的工作方式不同,您不必考虑转义和引用。
答案 1 :(得分:0)
我会使用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
}
?>
没有对它进行测试,但应该可以正常工作。
我也会对您的密码进行加密和加密。
此外,我会生成一个用于公开识别用户的代码。