最近发现我有很多页面都是直接对接数据库的,但是没有加密,虽然我在robots.txt中设置了不被搜索引擎爬取的逻辑,但是还是难免会被扫到,这里的安全问题值得考虑。没有经过数据库的验证,我暂时使用本地验证的方式对页面进行验证,可以满足一些普通页面的加密工作。
代码语言:php复制<?php
session_start(); // 启动会话
$secret_password = '123456'; // 定义密码
// 检查是否提交了密码且密码是否正确
if(isset($_POST['password']) && $_POST['password'] === $secret_password) {
$_SESSION['authenticated'] = true; // 认证成功,设置会话变量
}
// 如果未通过认证,显示密码输入表单
if(!isset($_SESSION['authenticated'])) {
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>请输入密码</title>
<style>
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #f0f0f0;
}
.container {
background: white;
padding: 20px;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
form {
display: flex;
flex-direction: column;
}
label {
margin-bottom: 5px;
}
input[type="password"], input[type="submit"] {
padding: 10px;
margin-bottom: 10px;
border: 1px solid #ccc;
border-radius: 5px;
}
input[type="submit"] {
cursor: pointer;
background-color: #007bff;
color: white;
border: none;
}
input[type="submit"]:hover {
background-color: #0056b3;
}
</style>
</head>
<body>
<div class="container">
<form method="post">
<label for="password">密码:</label>
<input type="password" name="password" id="password" required>
<input type="submit" value="提交">
</form>
</div>
</body>
</html>
<?php
exit; // 停止进一步执行脚本
}
// 放置认证通过后的页面内容
echo "欢迎,你已通过认证!";
?>
但是需要注意的是,这种方法的安全性有限,适用于非常基础的用途,例如一个小型、非公开的项目或临时页面,但不建议用于任何包含敏感数据或需要高安全性的场景。这里有几个原因:
- 硬编码的密码:密码直接硬编码在PHP文件中,这意味着任何能够访问源代码的人都可以看到密码。如果这个文件不小心被泄露或者是在一个共享的服务器环境中,密码就很容易被发现。
- 明文密码:密码以明文形式存储和比对,没有进行加密或哈希处理。这意味着如果有人能够看到这个密码,他们就可以直接使用。理想情况下,应该对密码进行哈希处理,并在验证时比对哈希值。
- 会话安全性:虽然使用了会话来记住用户的认证状态,但没有进一步的措施来确保会话的安全性,例如限制会话的有效期、使用HTTPS来防止会话被截获等。
- 没有保护措施:没有实现任何针对密码猜测攻击(如暴力攻击或字典攻击)的保护措施。理想情况下,应该有一定的限制来防止频繁的密码尝试,例如通过延迟响应、账户锁定或验证码来减缓攻击。
为了提高安全性,可以考虑以下几个改进措施:
- 使用HTTPS:确保所有的数据传输都是加密的,防止中间人攻击。
- 哈希密码:存储和验证密码时,应该使用安全的哈希算法(如PHP中的
password_hash
和password_verify
函数)。 - 限制尝试次数:实现一些逻辑来限制密码尝试次数,减少暴力破解的风险。
- 多因素认证:如果可能,加入多因素认证可以显著提高安全性。
所以我对代码进行了一定的升级:
代码语言:php复制<?php
session_start(); // 启动会话
// 假设你已经将密码哈希存储在环境变量或配置文件中
$passwordHash = '$2y$12$7fu2Y6wgJ3AtuX5COqum7eud5cZ3RmCsMrPlMSPQBOOF0OQj/iN1O';
// 初始化尝试次数
if (!isset($_SESSION['attempt'])) {
$_SESSION['attempt'] = 0;
}
// 检查尝试次数是否超过限制
$max_attempts = 5;
if ($_SESSION['attempt'] >= $max_attempts) {
echo "您已达到尝试次数上限,请稍后再试。";
exit; // 停止脚本执行
}
// 检查是否提交了密码且密码是否正确
if(isset($_POST['password'])) {
if (password_verify($_POST['password'], $passwordHash)) {
$_SESSION['authenticated'] = true; // 认证成功,设置会话变量
$_SESSION['attempt'] = 0; // 重置尝试次数
} else {
// 密码不正确
$_SESSION['attempt'] = 1; // 增加尝试次数
echo "<p>密码错误,请重试。</p>";
}
}
// 如果未通过认证,显示密码输入表单
if(!isset($_SESSION['authenticated'])) {
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>请输入密码</title>
<style>
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #f0f0f0;
}
.container {
background: white;
padding: 20px;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
form {
display: flex;
flex-direction: column;
}
label {
margin-bottom: 5px;
}
input[type="password"], input[type="submit"] {
padding: 10px;
margin-bottom: 10px;
border: 1px solid #ccc;
border-radius: 5px;
}
input[type="submit"] {
cursor: pointer;
background-color: #007bff;
color: white;
border: none;
}
input[type="submit"]:hover {
background-color: #0056b3;
}
</style>
</head>
<body>
<div class="container">
<form method="post">
<label for="password">密码:</label>
<input type="password" name="password" id="password" required>
<input type="submit" value="提交">
</form>
</div>
</body>
</html>
<?php
exit; // 停止进一步执行脚本
}
// 放置认证通过后的页面内容
echo "欢迎,你已通过认证!";
?>
其中密码是哈希加密的,所以我们需要对想要设置的密码进行hash加密,简单代码就能生成这个哈希值:
代码语言:php复制<?php
$password = "123456"; // 你想设置的密码
$options = [
'cost' => 12, // 成本因子,可以调整计算哈希所需的时间和内存,数值越大越安全但也越慢
];
$passwordHash = password_hash($password, PASSWORD_DEFAULT, $options);
echo $passwordHash;
?>
将上述代码中设置密码的地方修改成自己想修改的,然后把这个保存为hash.php文件,服务器访问后会加载一会儿,接着就会出现长串的哈希值,如上述代码运行后得出的就是我在例子中设置的“$2y$12$7fu2Y6wgJ3AtuX5COqum7eud5cZ3RmCsMrPlMSPQBOOF0OQj/iN1O”。
此时我们的加密工作就完成了,接下来可以测试下输入你设置的密码,如“123456”看看会不会弹出你要的页面。
我正在参与2024腾讯技术创作特训营第五期有奖征文,快来和我瓜分大奖!