一、为什么要学习系统的登录和注册
系统的登录和注册可能存在多种漏洞,这些漏洞可能被恶意攻击者利用,从而对用户的安全和隐私构成威胁。通过学习系统的登录和注册理解整个登录和注册的逻辑方便后续更好站在开发的角度思考问题发现漏洞。以下是一些常见登录和注册可能出现的漏洞:
- 逻辑漏洞:
- 返回凭证泄露:在找回密码等功能中,验证码或其他敏感信息可能直接显示在URL、页面源码或网络请求中,攻击者可以通过这些方式获取并利用这些信息。
- 暴力破解:如果登录系统没有有效的验证机制,如验证码、错误次数限制等,攻击者可以使用暴力破解方法尝试登录,并通过不断的尝试猜解用户密码。
- 验证码绕过:某些系统中,验证码的验证逻辑可能存在缺陷,使得攻击者可以在不知道验证码的情况下绕过验证,直接进行登录尝试。
- 短信轰炸:如果系统在发送短信验证码时未对发送数量进行限制,攻击者可以利用这一漏洞对目标手机号进行短信轰炸,导致用户骚扰和经济损失。
- Session覆盖:攻击者可能通过伪造请求来覆盖用户Session,从而获取其他用户的会话和权限。
- Cookie伪造:通过修改Cookie中的参数,攻击者可以尝试冒充其他用户登录系统。
- 任意用户注册:
- 未验证邮箱/手机号:攻击者可以填写未验证的邮箱或手机号进行注册,可能导致一个邮箱或手机号对应多个账户,增加用户混淆和安全风险。
- 批量注册:缺乏有效的验证机制可能导致攻击者批量注册账号,用于发送垃圾邮件、进行DOS攻击等恶意行为。
- 个人信息虚假伪造:在一些需要填写身份证信息的注册环节中,攻击者可以伪造身份证信息进行注册,绕过防沉迷系统等安全措施。
- 前端验证审核绕过:通过篡改服务器响应或利用验证码机制的缺陷,攻击者可以绕过前端验证进行注册。
- 用户名覆盖:如果系统允许新用户注册已被其他用户使用的用户名,可能导致老用户的用户名被覆盖,从而泄露或篡改用户信息。
- 密码重置漏洞:
- 短信验证码爆破:攻击者可以尝试爆破短信验证码,从而重置其他用户的密码。
- 验证码和手机号不匹配:攻击者可以使用自己的手机号接收的验证码重置其他用户的密码,这是因为系统没有严格验证手机号和验证码的匹配性。
- 平行越权:在某些系统中,用户登录后可以更改自己的密码,但如果没有严格验证用户身份,攻击者可以通过修改请求参数来重置其他用户的密码。
二、使用表单的方式进行登录
1.前端页面代码
文件名称:login.html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>登录页面</title>
<script type="text/javascript" src="./jquery-3.7.1.min.js"></script>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f0f2f5;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.login-container {
background-color: #fff;
border-radius: 5px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
width: 400px;
padding: 30px;
}
.login-container h1 {
text-align: center;
margin-bottom: 30px;
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
}
.form-group input {
width: 100%;
padding: 10px;
border: 1px solid #ccc;
border-radius: 3px;
}
.submit-btn {
width: 100%;
padding: 10px;
background-color: #007bff;
color: #fff;
border: none;
border-radius: 3px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="login-container">
<h1>登录</h1>
<form action="login.php" method="post" >
<div class="form-group">
<label for="username">用户名</label>
<input type="text" id="username" placeholder="请输入用户名" name="username">
</div>
<div class="form-group">
<label for="password">密码</label>
<input type="password" id="password" placeholder="请输入密码" name="password">
</div>
<input type="submit" value="登录" class="submit-btn">
</form>
</div>
</body>
</html>
2.构造数据库
- 创建数据库learn
create database learn;
- 创建user表
create table user(id int,name varchar(30),password varchar(30));
- 构造数据
insert into user values(1,'zs','123456');
insert into user values(2,'ls','123123');
insert into user values(3,'ww','456456');
3.后端代码
文件名称:login.php
<?php
$username = $_POST['username'];
$password = $_POST['password'];
$conn = mysqli_connect('127.0.0.1','root','root','learn') or die('数据库连接失败');
$sql = "select * from user where name='$username' and password='$password'";
$result = mysqli_query($conn,$sql);
if (mysqli_num_rows($result) == 1){
echo 'login-sucess';
}else{
echo 'login-fail';
}
?>
三、使用ajax的方式进行登录
1.前端代码
文件名称:login_ajax.html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>登录页面</title>
<script type="text/javascript" src="./jquery-3.7.1.min.js"></script>
<script>
function do_post(){
var username = $("#username").val();
var password = $("#password").val();
var param = "username=" + username +"&password=" + password;
$.post('login_ajax.php',param,function(data){
//window.alert(data);
if (data == 'login_success'){
window.alert('登录成功');
}else{
window.alert('登录失败');
}
});
}
</script>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f0f2f5;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.login-container {
background-color: #fff;
border-radius: 5px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
width: 400px;
padding: 30px;
}
.login-container h1 {
text-align: center;
margin-bottom: 30px;
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
}
.form-group input {
width: 100%;
padding: 10px;
border: 1px solid #ccc;
border-radius: 3px;
}
.submit-btn {
width: 100%;
padding: 10px;
background-color: #007bff;
color: #fff;
border: none;
border-radius: 3px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="login-container">
<h1>登录</h1>
<div class="form-group">
<label for="username">用户名</label>
<input type="text" id="username" placeholder="请输入用户名" name="username">
</div>
<div class="form-group">
<label for="password">密码</label>
<input type="password" id="password" placeholder="请输入密码" name="password">
</div>
<input type="submit" value="登录" class="submit-btn" onclick="do_post()">
</div>
</body>
</html>
2.后端代码
文件名称:login_ajax.php
<?php
$username = $_POST['username'];
$password = $_POST['password'];
$conn = mysqli_connect('127.0.0.1','root','root','learn') or die('数据库连接失败');
$sql = "select * from user where name='$username' and password='$password'";
$result = mysqli_query($conn,$sql);
if (mysqli_num_rows($result) == 1){
echo 'login_success';
}else{
echo 'login_fail';
}
?>
四、使用表单的方式提交注册
构造数据库,数据库名为learn,有一个user表,表里有name、password、user_head、create_time字段。
1.前端代码
文件名称:reg.html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>注册</title>
<script type="text/javascript" src="./jquery-3.7.1.min.js"></script>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f0f2f5;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.login-container {
background-color: #fff;
border-radius: 5px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
width: 400px;
padding: 30px;
}
.login-container h1 {
text-align: center;
margin-bottom: 30px;
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
}
.form-group input {
width: 100%;
padding: 10px;
border: 1px solid #ccc;
border-radius: 3px;
}
.submit-btn {
width: 100%;
padding: 10px;
background-color: #007bff;
color: #fff;
border: none;
border-radius: 3px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="login-container">
<h1>注册</h1>
<form action="reg.php" method="post" enctype="multipart/form-data">
<div class="form-group">
<label for="username">用户名</label>
<input type="text" id="username" placeholder="请输入用户名" name="username">
</div>
<div class="form-group">
<label for="password">密码</label>
<input type="password" id="password" placeholder="请输入密码" name="password">
</div>
<div class="form-group">
<label for="again_password">再次输入密码</label>
<input type="password" id="again_password" placeholder="重新输入密码" name="again_password">
</div>
<div class="form-group">
<label for="user_head"> </label>
<input type="file" name="user_head" >
</div>
<input type="submit" value="提交" class="submit-btn">
</form>
</div>
</body>
</html>
2.后端代码
文件名称:reg.php
<?php
error_reporting(E_ALL & ~E_NOTICE); //屏蔽notic报告
//设置北京时间作为时区
date_default_timezone_set("PRC");
$username = $_POST['username'];
$password = $_POST['password'];
$again_password = $_POST['again_password'];
$tmp_path = $_FILES['user_head']['tmp_name']; //获取文件临时路径
$file_name = $_FILES['user_head']['name']; //获取文件的原始文件名
#echo $tmp_path;
#echo $file_name;
if ($password == $again_password){
$conn = mysqli_connect('127.0.0.1','root','root','learn') or die('数据库连接失败');
$sql = "select * from user where name='$username' ";
$result = mysqli_query($conn,$sql);
if (mysqli_num_rows($result) == 1){
echo 'user-esxit';
}else{
//echo end(explode(".",$file_name));
$new_name = date('Ymd_His.') . end(explode(".",$file_name));
// echo $new_name;
move_uploaded_file($tmp_path,'./upload/'.$new_name) or die('upload_fail');
$now = date('Y-m-d H:i:s');
#echo $now;
$sql = "insert into user (name,password,user_head,create_time) values('$username','$password','$new_name','$now')";
#echo $sql;
mysqli_query($conn,$sql) or die('reg_fail');
echo 'reg_success';
mysqli_close($conn);
}
}else{
die('two secret is no same');
}
?>
五、使用ajax的方式提交注册
1.前端代码
文件名称:reg_ajax.html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>注册</title>
<script type="text/javascript" src="./jquery-3.7.1.min.js"></script>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f0f2f5;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.login-container {
background-color: #fff;
border-radius: 5px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
width: 400px;
padding: 30px;
}
.login-container h1 {
text-align: center;
margin-bottom: 30px;
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
}
.form-group input {
width: 100%;
padding: 10px;
border: 1px solid #ccc;
border-radius: 3px;
}
.submit-btn {
width: 100%;
padding: 10px;
background-color: #007bff;
color: #fff;
border: none;
border-radius: 3px;
cursor: pointer;
}
</style>
<script>
function do_reg(){
var username = $("#username").val();
var password = $("#password").val();
var again_password = $("#again_password").val();
var data = new FormData(); //带附件上传
data.append("username", username);
data.append("password", password);
data.append("again_password", again_password);
data.append("user_head", $("#user_head").prop("files")[0]);
$.ajax({
url:'reg.php',
type:'POST',
data: data,
cache: false,
processData: false,
contentType: false,
success : function(data){
if (data === 'reg-reg_success') {
window.alert("注册成功");
location.href="login_ajax.html";
}
else if (data === 'user_esxit') {
window.alert("用户名已经注册");
}
else {
window.alert(data);
// window.alert("注册失败");
}
}
});
}
</script>
</head>
<body>
<div class="login-container">
<h1>注册</h1>
<div class="form-group">
<label for="username">用户名</label>
<input type="text" id="username" placeholder="请输入用户名" >
</div>
<div class="form-group">
<label for="password">密码</label>
<input type="password" id="password" placeholder="请输入密码" >
</div>
<div class="form-group">
<label for="again_password">再次输入密码</label>
<input type="password" id="again_password" placeholder="重新输入密码" >
</div>
<div class="form-group">
<label for="user_head"> </label>
<input type="file" id="user_head" >
</div>
<input type="submit" value="提交" class="submit-btn" onclick="do_reg()">
</div>
</body>
</html>
2.后端代码
文件名称:reg_ajax.php
<?php
//设置北京时间作为时区
date_default_timezone_set("PRC");
$username = $_POST['username'];
$password = $_POST['password'];
$again_password = $_POST['again_password'];
$tmp_path = $_FILES['user_head']['tmp_name']; //获取文件临时路径
$file_name = $_FILES['user_head']['name']; //获取文件的原始文件名
error_reporting(E_ALL & ~E_NOTICE); //屏蔽notic报告
#echo $file_name;
if ($password == $again_password){
$conn = mysqli_connect('127.0.0.1','root','root','learn') or die('数据库连接失败');
$sql = "select * from user where name='$username' ";
$result = mysqli_query($conn,$sql);
if (mysqli_num_rows($result) == 1){
echo 'user_esxit';
}else{
$file_extend = explode(".", $file_name);
//echo end(explode(".",$file_name));
$new_name = date('Ymd_His.') . end($file_extend);
move_uploaded_file($tmp_path,'./upload/'.$new_name) or die('upload_fail');
$now = date('Y-m-d H:i:s');
#echo $now;
$sql = "insert into user (name,password,user_head,create_time) values('$username','$password','$new_name','$now')";
#echo $sql;
mysqli_query($conn,$sql) or die('reg_fail');
echo 'reg_success';
mysqli_close($conn);
}
}else{
die('two secret is no same');
}
?>
每篇一言:我要做一颗星星,有棱有角,还会发光。