Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP-会话标识符-安全性_Php_Security_Session_Ssl_Session Variables - Fatal编程技术网

PHP-会话标识符-安全性

PHP-会话标识符-安全性,php,security,session,ssl,session-variables,Php,Security,Session,Ssl,Session Variables,我有一个关于使用全局$\u SESSION[]变量的问题 现在对于我的web应用程序,每当用户登录时,都会返回与该用户名和特定密码匹配的行。然后我获取列user\u hash,并将该user\u hash存储在$\u会话['id']中 我使用此会话来识别哪个用户已登录,并基于此唯一哈希执行数据库查询。我在某个地方读到过这样一个“静态”标识符(静态标识符是用户\u散列,因为它永远不会改变)是不安全的,我宁愿让用户\u散列动态地改变 因此,我实现了一个系统,每当用户登录和/或导航到web应用程序中的

我有一个关于使用全局
$\u SESSION[]
变量的问题

现在对于我的web应用程序,每当用户登录时,都会返回与该用户名和特定密码匹配的行。然后我获取列
user\u hash
,并将该
user\u hash
存储在
$\u会话['id']

我使用此会话来识别哪个用户已登录,并基于此唯一哈希执行数据库查询。我在某个地方读到过这样一个“静态”标识符(静态标识符是用户\u散列,因为它永远不会改变)是不安全的,我宁愿让用户\u散列动态地改变

因此,我实现了一个系统,每当用户登录和/或导航到web应用程序中的其他页面时,我都会生成一个新的哈希,将其存储在数据库中,然后将其存储在全局
$\u会话['id']
变量中。我设法做到了这一点,但现在每当有人试图从两台设备登录时,具有“旧”会话的设备无效,因为用户\u哈希从新设备更改,并注销具有旧会话的用户


我的问题是,这样做真的有意义吗?我在我的Web服务器上使用ssl(https),所以会话劫持相对来说是不可能的?如果仅使用静态会话标识符存在安全缺陷,是否有更好的方法使其动态化,同时不注销其他用户?

两个有用的链接:


我设法做到了这一点,但现在每当有人试图从两台设备登录时,具有“旧”会话的设备无效,因为用户\u哈希从新设备更改,并注销具有旧会话的用户

虽然这可能取决于您的安全要求,但我在上面发布的帖子说:

将旧会话标记为已过时,并将其标记为在十秒钟内[或在适合您需要的某个时间]过期。这样,任何排队的请求仍然可以访问过期的会话,但我们不必让它永远打开


因此,我实现了一个系统,每当用户登录和/或导航到web应用程序中的其他页面时,我都会生成一个新的哈希,将其存储在数据库中,然后将其存储在全局$u会话['id']变量中

就我个人而言,我怀疑这是非常有效的,并将导致您的服务器负载这一不断的改造,巨大的开销。这是不需要的

如果您真的想重新创建会话,只需使用
session\u regenate\u id()
并将其设置为时间值(比如每10分钟一次),如本文顶部所示

唯一重要的是会话标识。浏览器或最终用户永远看不到会话数组中的所有值

所以,;只要会话id是一个long随机值,它就会隐藏在可见的地方。有关如何确保PHP提供更多随机和更长命名会话ID的详细信息,请参阅

php.ini:

如果在数据库中存储会话,请确保会话id的列名足够长,否则由于会话名称被截断,会话将永远无法连接


其他一些因素

  • 确保您的会话cookie被PHP设置为
    加密的
    。无论TLS连接的状态如何,都必须手动执行此操作。请参见上面的
    session.cookie\u secure=1

  • 您可以通过添加浏览器或ip特定数据(例如,这些相应的
    $\u SERVER
    值的散列)来帮助最小化已经不太可能发生的Hjack事件,以便在执行warrent重复检查会话的任务时进行比较,以比较浏览器类型/客户端ip是否仍然与会话记录中的内容进行比较。这两种方法中的每一种都可能存在问题,例如,移动连接上的少数人可能在登录期间更改IP,或者多个设备上的用户可能在每个设备上都有不同的浏览器,但根据需要找到一种方法进行比较(这也在页面顶部的中引用)

  • 如上所述,
    $\u会话
    数据从未存储在客户机上,因此从数据库中散列值以存储在
    $\u会话
    中很可能超出您的安全需要

  • (单个)最重要的是会话id是安全的,并且足够大,可以舒适地容纳一个潜在的黑客使用假会话id钓鱼,作为在雷舰上玩战舰的近亲


使用https,仍然可以进行会话劫持、跨站点脚本或sqlinject@RaymondNijland虽然会话劫持通常要求用户在使用TLS时在浏览器中安装恶意软件,但这并不是网站可以轻松防范的。如果您在HTTPS上传输会话ID,它不受中间人攻击,这是会话劫持的常见形式。@ Devon,我的意思是在会话劫持时,攻击者正在强制SeStudioID找到用户正在使用的有效的…defualt PHP会话处理不是很安全这里有一个关于与Laravel讨论此问题的快速阅读:。简而言之,您可以执行应用程序逻辑来要求重要事项(删除某些内容、访问帐户详细信息等)的密码,但https是防止劫持的最佳保护。请使用段落。像这样的一堆文本很难阅读。谢谢你!回答得好@我很高兴听到这个消息。哪些部分对您的影响最大?你知道什么了吗?
static function regenerateSession()
{
    // If this session is obsolete it means there already is a new id
    if(isset($_SESSION['OBSOLETE']) || $_SESSION['OBSOLETE'] == true)
        return;

    // Set current session to expire in 10,30,100 seconds etc.
    $_SESSION['OBSOLETE'] = true;
    $_SESSION['EXPIRES'] = time() + 10; //or 30 seconds or whatever.

    // Create new session without destroying the old one
    session_regenerate_id(false);

    // Grab current session ID and close both sessions to allow other scripts to use them
    $newSession = session_id();
    session_write_close();

    // Set session ID to the new one, and start it back up again
    session_id($newSession);
    session_start();

    // Now we unset the obsolete and expiration values for the session we want to keep
    unset($_SESSION['OBSOLETE']);
    unset($_SESSION['EXPIRES']);
}
session.save_handler = files
session.use_cookies = 1
session.cookie_secure = 1
session.use_only_cookies = 1
session.cookie_domain = "example.com"
session.cookie_httponly = 1
session.entropy_length = 32
session.entropy_file = /dev/urandom
session.hash_function = sha256
session.hash_bits_per_character = 5