一:php中sesion的配置
二: php手册中的函数
1:bool session_start ( void ) 启动新会话或者重用现有会话
当会话自动开始或者通过 session_start() 手动开始的时候, PHP 内部会调用会话管理器的 open 和 read 回调函数。 会话管理器可能是 PHP 默认的, 也可能是扩展提供的(SQLite 或者 Memcached 扩展), 也可能是通过 session_set_save_handler() 设定的用户自定义会话管理器。 通过 read 回调函数返回的现有会话数据(使用特殊的序列化格式存储), PHP 会自动反序列化数据并且填充 $_SESSION 超级全局变量。
2:string session_name ([ string $name
] ) — 读取/设置会话名称
请求开始的时候,会话名称会被重置并且存储到 session.name 配置项
会话名称至少需要一个字母,不能全部都使用数字, 否则,每次都会生成一个新的会话 ID。
3:string session_cache_limiter ([ string $cache_limiter
] ) — 读取/设置缓存限制器
4:string session_id ([ string $id
] ) — 获取/设置当前会话 ID
不同的会话管理器对于会话 ID 中可以使用的字符有不同的限制。 例如文件会话管理器仅允许会话 ID 中使用以下字符:a-z A-Z 0-9 , (逗号)和 - (减号)
5:bool session_regenerate_id ([ bool $delete_old_session
= false ] ) — 使用新生成的会话 ID 更新现有会话 ID
delete_old_session
是否删除原 ID 所关联的会话存储文件。
6:会话数据的服务器端存储:
string session_encode ( void ) — 将当前会话数据编码为一个字符串
注意:
session_encode() 返回一个序列化后的字符串,包含被编码的、储存于 $_SESSION 超全局变量中的当前会话数据。
请注意,序列方法 和 serialize() 是不一样的。 该序列方法是内置于 PHP 的,能够通过设置 session.serialize_handler来设置。
bool session_decode ( string $data
)
注意:
session_decode() 对 $data
参数中的已经序列化的会话数据进行解码, 并且使用解码后的数据填充 $_SESSION 超级全局变量。
请注意,这里的反序列化方法不同于 unserialize() 函数。 序列化方法时 PHP 内置的,并且可以通过session.serialize_handler 配置项进行修改。
session.serialize_handler
string
session.serialize_handler 定义用来序列化/解序列化的处理器名字。当前支持 PHP 内部格式(名为 php)和 WDDX(名为 wddx)。如果 PHP 编译时加入了 WDDX 支持,则只能用 WDDX。默认为 php。
6:session生命周期
int session_cache_expire ([ string $new_cache_expire
] ) — 返回当前缓存的到期时间
注意:
请求开始的时候,缓存到期时间会被重置为 180,并且保存在 session.cache_expire 配置项中。 因此,针对每个请求,需要在 session_start() 函数调用之前 调用 session_cache_expire() 来设置缓存到期时间。
Note: 仅在 session.cache_limiter 的设置值 不是 nocache 的时候, 才可以设置 new_cache_expire
参数。
array session_get_cookie_params ( void ) 返回一个包含当前会话 cookie 信息的数组:
void session_unset ( void ) — Free all session variables
7:seesion 控制
bool session_set_save_handler ( callable $open
, callable $close
, callable $read
,callable $write
, callable $destroy
, callable $gc
[, callable $create_sid
] )
bool session_set_save_handler ( SessionHandlerInterface $sessionhandler
[, bool$register_shutdown
= true ] ) 要求: PHP 5.4 开始
三:session安全
1:session 数据暴露
1、使用SSL是一种特别有效的手段,它可以使数据在服务器和客户端之间传送时暴露的可能性降到最低。这对于传送敏感数据的应用来说非常重要。
SSL在HTTP之上提供了一个保护层,以使所有在HTTP请求和应答中的数据都得到了保护。
2、使用SSL是一种特别有效的手段,它可以使数据在服务器和客户端之间传送时暴露的可能性降到最低。这对于传送敏感数据的应用来说非常重要。
SSL在HTTP之上提供了一个保护层,以使所有在HTTP请求和应答中的数据都得到了保护。
2:session 劫持
原理:所有这些手段的第一步都是取得一个合法的会话标识来伪装成合法用户, 所以关于会话,需要关注的主要问题是会话标识的保密性问题
方式:
一个攻击者可以通过三种方法来取得合法的会话标识:
- 猜测
- 捕获
- 固定
PHP生成的是随机性很强的会话标识,所以被猜测的风险是不存在的。常见的是通过捕获网络通信数据以得到会话标识。为了避免会话标识被捕获的风险,可以使用SSL,同时还要对浏览器漏洞及时修补。
防护:深度防范原则
当会话标识不幸被攻击者知道的情况下,你的目标应该是使前述的伪装过程变得更复杂。
把伪装过程变得更复杂的关键是加强验证。会话标识是验证的首要方法,同时你可以用其它数据来补充它。你可以用的所有数据只是在每个HTTP请求中的数据:
GET / HTTP/1.1
Host: example.org
User-Agent: Firefox/1.0
Accept: text/html, image/png, image/jpeg, image/gif, */*
Cookie: PHPSESSID=1234
你应该意识到请求的一致性,并把不一致的行为认为是可疑行为。例如,虽然User-Agent(发出本请求的浏览器类型)头部是可选的,但是只要是发出该头部的浏览器通常都不会变化它的值。如果你一个拥有1234的会话标识的用户在登录后一直用Mozilla Firfox浏览器,突然转换成了IE,这就比较可疑了。例如,此时你可以用要求输入密码方式来减轻风险,同时在误报时,这也对合法用户产生的冲击也比较小。你可以用下面的代码来检测User-Agent的一致性:
<?php session_start(); if (isset($_SESSION['HTTP_USER_AGENT'])) { if ($_SESSION['HTTP_USER_AGENT'] != md5($_SERVER['HTTP_USER_AGENT'])) { /* Prompt for password */ exit; } } else { $_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']); }
我观察过,在某些版本的IE浏览器中,用户正常访问一个网页和刷新一个网页时发出的Accept头部信息不同,因此Accept头部不能用来判断一致性。
确保User-Agent头部信息一致的确是有效的,但如果会话标识通过cookie传递(推荐方式),有道理认为,如果攻击者能取得会话标识,他同时也能取得其它HTTP头部。由于cookie暴露与浏览器漏洞或跨站脚本漏洞相关,受害者需要访问攻击者的网站并暴露所有头部信息。所有攻击者要做的只是重建头部以防止任何对头部信息一致性的检查。
比较好的方法是产生在URL中传递一个标记,可以认为这是第二种验证的形式(虽然更弱)。使用这个方法需要进行一些编程工作,PHP中没有相应的功能。例如,假设标记保存在$token中,你需要把它包含在所有你的应用的内部链接中:
<?php $url = array(); $html = array(); $url['token'] = rawurlencode($token); $html['token'] = htmlentities($url['token'], ENT_QUOTES, 'UTF-8'); ?> <a href="index.php?token=<?php echo $html['token']; ?>">Click Here</a>
为了更方便地管理这个传递过程,你可能会把整个请求串放在一个变量中。你可以把这个变量附加到所有链接后面,这样即便你一开始没有使用该技巧,今后还是可以很方便地对你的代码作出变化。
该标记需要包含不可预测的内容,即便是在攻击者知道了受害者浏览器发出的HTTP头部的全部信息也不行。一种方法是生成一个随机串作为标记:
<?php $string = $_SERVER['HTTP_USER_AGENT']; $string .= 'SHIFLETT'; $token = md5($string); $_SESSION['token'] = $token; ?>
当你使用随机串时(如SHIFLETT),对它进行预测是不现实的。此时,捕获标记将比预测标记更为方便,通过在URL中传递标记和在cookie中传递会话标识,攻击时需要同时抓取它们二者。这样除非攻击者能够察看受害者发往你的应用所有的HTTP请求原始信息才可以,因为在这种情况下所有内容都暴露了。这种攻击方式实现起来非常困难(所以很罕见),要防止它需要使用SSL。
有专家警告不要依赖于检查User-Agent的一致性。这是因为服务器群集中的HTTP代理服务器会对User-Agent进行编辑,而本群集中的多个代理服务器在编辑该值时可能会不一致。如果你不希望依赖于检查User-Agent的一致性。你可以生成一个随机的标记:
<?php
$token = md5(uniqid(rand(), TRUE));
$_SESSION['token'] = $token;
?>
这一方法的安全性虽然是弱一些,但它更可靠。上面的两个方法都对防止会话劫持提供了强有力的手段。你需要做的是在安全性和可靠性之间作出平衡。