我的PHP登录页面可以绕过吗?

时间:2014-07-23 01:20:58

标签: php security

这是我的登录页面。

include 'config.php';

if (($_POST['username']!=$user) || ($_POST['password']!=$pass))
{
// login deny.
// process usaully terminate at the end of block
}else{
// login grant.
}

在config.php中声明的$ user和$ pass值。

我是否有机会在不知道密码和用户名的情况下登录?

像将$ _POST []强制转换为int。

1 个答案:

答案 0 :(得分:1)

您的问题的答案是肯定的,用户可以在不知道密码的情况下完成登录。真正的问题是你有多难让他做到这一点,和/或他需要多长时间才能蛮力/猜测它。

防止暴力破解的一种可能方法是跟踪请求数量并采用许多API服务器用来阻止过多登录尝试的速率限制技术。这可以使用会话,或者更好的是通过客户端的IP地址来尝试请求的内部日志,并且在说出10个请求失败之后,您将该IP地址锁定24小时。


快速解决方案

您是否要为每个页面视图发布您的凭据?您应该只发布一次数据,验证数据并将结果保存到会话变量,然后检查该变量以确定用户是否已登录。

以下是基本的,严重安全的登录系统you should be hashing your passwords!!)的简短示例:

<强>的config.php

session_start(); // let's get this puppy rolling

$user = 'example';
$pass = 'anUnsafePasswordHere'; // hash me please!!!

<强> yourpage.php

include 'config.php';

if(!isset($_SESSION['is_logged_in']) || $_SESSION['is_logged_in'] !== true) {
    // strict comparison for your login check failed, redirect to login page
    header("Location: login.php");
    exit;
}

// display regular content here, they are logged in!

您的登录页面显然会有一个表格,并会在某处发布,所以让我们快速复制:

<强>的login.php

include 'config.php';

if(isset($_POST['login'])) {
    if(
        !empty($_POST['user'])      // check that the vars exist before trying to
        && !empty($_POST['pass'])   // use them in your comparison
        && $_POST['user'] === $user // strict check here, content and var type
        && $_POST['pass'] === $pass
    ) {
        // login succeeded! clear failed validation errors, set success and redirect
        unset($_SESSION['login_errors']);
        $_SESSION['is_logged_in'] = true;
        header("Location: yourpage.php");
        exit;
    }
    // login failed, let's save an error message to the session and redirect back 
    // to the login form
    $_SESSION['login_errors'] = 'Login failed, please try again!';
    header("Location: login.php");
    exit;    
}

?>
<form action="login.php" method="post">
    <?php if(!empty($_SESSION['login_errors'])) echo '<p>' . $_SESSION['login_errors'] . '</p>'; ?>
    <input type="text" name="user" placeholder="Username">
    <input type="password" name="pass" placeholder="Password">
    <button type="submit" name="login">Login!</button>
</form>

如果您为登录系统使用这样的基本结构,那么您不应该走得太远。我们的想法是,每当表示“登录”状态的会话变量不存在时,您就会强制重定向到登录页面。

登录页面发布到自身,其中检查凭据,如果一切正常,则设置登录状态会话变量,并且您将发送回主页 - 这次通过了页面顶部的验证检查。

显然要注销,您只需拨打unset($_SESSION['is_logged_in']);session_destroy(),然后重定向回登录页面。

安全说明

现在出于安全原因,你应该肯定实现一些散列。

如果您只想要一个帐户访问您的脚本并且您认为纯粹使用数据库有点过分,您可以将您的凭据存储在源代码中,但是您应始终存储您的密码作为散列表示它们是什么,以便任何碰巧看到你的人或以某种方式获取对你的源代码的访问权限的人都不会立即看到你的密码。

一些旧的经典(但现在由于更安全的替代方法而逐步淘汰)快速构建到PHP散列技术中的方法正在使用md5()sha1()来提供密码的散列表示。散列是一种单向加密,它需要一台机器很长时间来暴力破解哈希代表什么,所以任何安全性都比没有好。我建议你使用bcrypt,但是你的应用程序的基本安全级别(总比没有好!)会使用md5()将你的secretpassword变成像{{1}这样的哈希值然后在源代码中存储

您需要在登录文件中更改的是将您发布的密码与源代码中的密码进行比较的行:

2034f6e32958647fdff75d265b455ebf

要将哈希带到现代最佳实践级别,您应该考虑使用bcrypt之类的东西来安全地存储您的密码。