0


如何让你的会话更安全,浅析Session与Cookie

    在我们面试的时候,面试官问及 XSS 漏洞的时候,我们常常会说比如劫持 Cookie,问及防御方法的时候,又常常会说设置
httponly

,本篇文章将从代码层面简单的普及 Session 和 Cookie 的生成过程,及防御的方法,希望看到这篇文章后,下一次遇到面试官的时候,你能够自豪的跟他说我知道防御 XSS 漏洞,能够把流程讲清楚,把原理讲明白!

先从 Cookie 讲起

    什么是 Cookie 呢?简单来说,当用户访问某个网站时,该网站的服务器会生成一个Cookie并发送到用户的浏览器,**浏览器将其存储在本地计算机上。**之后,每当用户再次访问该网站时,浏览器会将Cookie发送回服务器,服务器通过这些信息来识别用户,维持用户的登录状态,或者记录用户的浏览习惯、购物车。

    在 PHP 中,我们常常使用
setcookie

函数生成用户的 cookie,其函数解释如下:

  setcookie()

是 PHP 中的一个函数,用于设置 cookie 的各种属性,并向客户端发送 cookie。cookie 是一种机制,允许服务器向浏览器发送少量数据,并且浏览器会存储这些数据,下次访问同一网站时会发送回服务器。
函数的基本语法如下:

setcookie(name, value, expires, path, domain, secure, httponly);

参数说明:

  • name:cookie 的名称。
  • value:cookie 的值。
  • expires:cookie 过期的 Unix 时间戳。如果未设置或设置为 0,则 cookie 在浏览器会话结束时过期。
  • path:cookie 在哪个路径下有效。默认为当前脚本的目录以及所有子目录。
  • domain:cookie 在哪个域名下有效。注意,如果设置此参数,cookie 只会在指定的域下工作。
  • secure:如果设置为 true,cookie 只有在 HTTPS 连接下才会被发送。
  • httponly:如果设置为 true,cookie 将不会通过客户端脚本访问(如 JavaScript),有助于减少跨站脚本攻击(XSS)。

使用实例如下:

setcookie("user", "JohnDoe", time() + 3600, "/", "example.com", true, true);
    上面的代码会设置一个名为 
user

的 cookie,值为

JohnDoe

,有效期为 1 小时,在整个网站的路径下有效,仅适用于

example.com

域,并且需要通过安全的 HTTPS 连接传输,同时禁止通过客户端脚本访问。

为什么会有 Session

    众所周知,Session相对于Cookie来说,由于其服务器端存储的特性,通常被认为更安全。其安全性体现在与,**Session数据存储在服务器上,这意味着它们不受浏览器设置的影响,并且不容易受到XSS攻击。**同时,Session可以在用户会话期间持续存在,而不需要每次页面加载时都重新发送Cookie。

    在 PHP 中,我们常常使用
session_start()

函数来开始或继续一个现有的会话,用

session_regenerate_id()

防止会话劫持。

Session 与 Cookie 的区别如下:

Cookie

Session

存储位置

Cookie存储在用户的浏览器中,

Session数据存储在服务器上,这意味着它们不受浏览器设置的影响

安全性

如果Cookie没有设置为HttpOnly,那么JavaScript可以读取Cookie

Session通常通过一个会话ID来识别,这个ID在每次请求时都会发送到客户端。如果会话ID被窃取,攻击者可以使用它来访问用户的会话。

持久性

Cookie在每次HTTP请求和响应中都会被发送

Session可以在用户会话期间持续存在,而不需要每次页面加载时都重新发送Cookie。

跨域问题

由于同源策略(SOP),Cookie通常受到同源限制

Session不受SOP的限制,可以在不同域间使用。

01- 前端代码编写

    创建文件
/session/index.html

,用以提交用户名及密码,发送数据给到后端验证,实验代码如下:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>登录示例</title>
</head>
<body>
<form action="login.php" method="post">
    用户名:<input type="text" name="username" required>
    密码:<input type="password" name="password" required>
    <input type="submit" value="登录">
</form>
</body>
</html>
    前端页面反馈如下,麻雀虽小,五脏俱全:

02-后端 Session 生成

    创建后端处理 php 代码
login.php

,用以在通过验证的用户名和密码后,创建 Session 会话 ID,实验代码如下:

<?php
// 模拟用户数据库
$users = array(
    'user1' => 'password1',
    'user2' => 'password2'
);

// 从表单中获取用户名和密码
$username =$_POST['username'];
$password =$_POST['password'];

// 验证用户名和密码
if (isset($users[$username]) && $users[$username] === $password) {
    // 生成安全的会话ID
    session_start();
    session_regenerate_id();
    $_SESSION['loggedin'] = true;
    $_SESSION['username'] =$username;

    // 设置 session ID 到 Cookie
    setcookie(session_name(), session_id(), time() + 3600, '/', '', true, true);

    echo '<pre style="color: green; font-size: 18px;">';
    echo '登录成功,您的会话信息如下:';
    echo '<br><code>' . htmlspecialchars($_COOKIE[session_name()]) . '</code>';
    echo '</pre>';
} else {
    echo '<pre style="color: red; font-size: 18px;">';
    echo '登录失败,用户名或密码错误。';
    echo '</pre>';
}
?>

03-Session 会话使用

    在我们后端
login.php

生成完 Session 会话后,我们访问目标网站下的其他页面,比如

info.php

,需要通过 Session 去验证我们的身份,其后端代码如下:

<?php
// 检查会话是否已启动
if (!isset($_COOKIE[session_name()])) {
    // 如果会话未启动,重定向到登录页面
    header('Location: login.php');
    exit;
}

// 开始会话
session_start();

// 检查用户是否已登录
if (!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']) {
    // 如果用户未登录,重定向到登录页面
    header('Location: login.php');
    exit;
}

// 显示用户信息
echo '<pre style="color: green; font-size: 18px;">';
echo '欢迎,' . htmlspecialchars($_SESSION['username']) . '!';
echo '</pre>';

?>

04-实验会话使用

    首先我们通过表单数据,构造 POST 型请求,将用户名
user1

和密码

password1

以 POST 型提交,服务器端返回数据包如下:

    此时当后端验证完成后,会发出
set-cookie

的命令,将

sessionID

进行设置后发送给前端浏览器。

    如果我们发送多次请求,会发现每次进行登录的请求时,都会重新设置
sessionID

,此时我们有多个

sessionID

,都是指向用户

user1

    经过测试,这些
sessionid

都是指向用户

user1

,因此会发现这种重复性的登陆行为,并没有保障用户数据的安全性。

    旧的
sessionid

并未销毁,仍旧可被识别:

    这是因为我们在设置的过程中,并没有使用的相应识别机制,在重复提交登录表单的时候进行旧的 ID 的销毁,但是由于
sessionID

的爆破难度较高,因此安全性并不会受到较大的影响。

如何设置 httponly 来保证

**sessionID**

的安全性:

    在之前的后端代码中,有这样一行内容:
    // 设置 session ID 到 Cookie
    setcookie(session_name(), session_id(), time() + 3600, '/', '', true, true);
    最后两个参数
true

,保证了首先数据包只有在

https

下才能传送,保障了

cookie

不会被恶意的监听到,比如在防御中间人攻击上起到了一定的保护作用,其次第二个

true

,设置了

httponly

这样即使网站出现了 XSS 漏洞,也能保障我们的

cookie

不被黑客窃取,两者结合保障了会话的安全性。

总结

    在本篇文章中,我们首先从
cookie

讲起,理解了

session

cookie

的不同,

session

为什么比

cookie

安全,以及如何去设置

http-only

及其设置的效果,希望对大家理解

cookie

session

有所帮助。

标签: 安全 web安全

本文转载自: https://blog.csdn.net/cul1n/article/details/136093418
版权归原作者 颠勺厨子 所有, 如有侵权,请联系我们删除。

“如何让你的会话更安全,浅析Session与Cookie”的评论:

还没有评论