me2*_*me2 145 php security session session-cookies
我正在尝试更多地了解PHP 会话修复和劫持以及如何防止这些问题.我一直在阅读Chris Shiflett网站上的以下两篇文章:
但是,我不确定我是否理解正确的事情.
为了帮助防止会话固定,调用session_regenerate_id(true)就足够了; 成功登录某人后?我想我理解正确.
他还讨论了通过$ _GET使用在URL中传递的令牌来防止会话劫持.怎么会完全这样做?我猜测当有人登录时你生成他们的令牌并将其存储在会话变量中,然后在每个页面上你将该会话变量与$ _GET变量的值进行比较?
这个令牌只需要在每个会话或每个页面加载时更改一次吗?
他们是一个防止劫持而不必在网址中传递值的好方法吗?这会更容易.
irc*_*ell 217
好的,有两个独立但相关的问题,每个问题都有不同的处理方式.
这是攻击者为用户显式设置会话的会话标识符的地方.通常在PHP中,它通过给他们一个URL来完成http://www.example.com/index...?session_name=sessionid
.一旦攻击者将URL提供给客户端,攻击就像会话劫持攻击一样.
有几种方法可以防止会话固定(完成所有这些操作):
session.use_trans_sid = 0
在您的php.ini
文件中设置.这将告诉PHP不要在URL中包含标识符,也不要读取标识符的URL.
session.use_only_cookies = 1
在您的php.ini
文件中设置.这将告诉PHP永远不要使用具有会话标识符的URL.
在会话状态发生变化时,重新生成会话ID.这意味着以下任何一种情况:
这是攻击者获取会话标识符的位置,并且能够发送请求,就好像他们是该用户一样.这意味着,由于攻击者具有标识符,因此它们与服务器的有效用户几乎无法区分.
您不能直接阻止会话劫持.但是,您可以采取措施使其变得非常困难和难以使用.
使用强会话哈希标识符:session.hash_function
in php.ini
.如果PHP <5.3,则将其设置session.hash_function = 1
为SHA1.如果PHP> = 5.3,请将其设置为session.hash_function = sha256
或session.hash_function = sha512
.
发送一个强大的哈希:session.hash_bits_per_character
in php.ini
.将此设置为session.hash_bits_per_character = 5
.虽然这并没有让它更难破解,但是当攻击者试图猜测会话标识符时,它确实会有所不同.ID将更短,但使用更多字符.
在文件中使用session.entropy_file
和设置其他熵.例如,将前者设置为后者,将后者设置为将从熵文件读取的字节数.session.entropy_length
php.ini
session.entropy_file = /dev/urandom
session.entropy_length = 256
从默认的PHPSESSID更改会话的名称.这是通过session_name()
使用您自己的标识符名称作为调用之前的第一个参数来完成的session_start
.
如果你真的是偏执狂,你也可以旋转会话名称,但要注意,如果你改变它,所有会话将自动失效(例如,如果你依赖于时间).但根据您的使用情况,它可能是一个选项......
经常轮换您的会话标识符.我不会每次请求都这样做(除非你真的需要那种级别的安全性),而是以随机的间隔.您希望经常更改此内容,因为如果攻击者劫持了一个会话,您不希望他们能够长时间使用它.
在会话中包括用户代理$_SERVER['HTTP_USER_AGENT']
.基本上,当会话开始时,将其存储在类似的东西中$_SESSION['user_agent']
.然后,在每个后续请求中检查它是否匹配.请注意,这可能是伪造的,因此它不是100%可靠,但它总比没有好.
在会话中包含用户的IP地址$_SERVER['REMOTE_ADDR']
.基本上,当会话开始时,将其存储在类似的东西中$_SESSION['remote_ip']
.对于一些为其用户使用多个IP地址的ISP(例如AOL曾经这样做),这可能会有问题.但如果你使用它,它会更安全.攻击者伪造IP地址的唯一方法是在真实用户和您之间的某个时刻危及网络.如果他们妥协网络,他们可能会比劫持(比如MITM攻击等)更糟糕.
在会话中和浏览器端包含一个令牌,您可以经常增量和比较.基本上,对于$_SESSION['counter']++
服务器端的每个请求.在浏览器端的JS中也做一些事情来做同样的事情(使用本地存储).然后,当您发送请求时,只需获取令牌的nonce,并验证服务器上的nonce是否相同.通过这样做,您应该能够检测到被劫持的会话,因为攻击者将没有确切的计数器,或者如果他们这样做,您将有2个系统传输相同的计数并且可以判断一个是伪造的.这不适用于所有应用程序,但是解决问题的一种方法.
会话固定和劫持之间的区别仅在于如何破坏会话标识符.在固定中,标识符被设置为攻击者事先知道的值.在劫持中,它是从用户猜测或被盗的.否则,一旦标识符被泄露,两者的效果是相同的.
每当您使用session_regenerate_id
旧会话重新生成会话标识符时都应删除.这与核心会话处理程序透明地发生.但是,一些使用的自定义会话处理程序session_set_save_handler()
不会执行此操作,并且可以对旧会话标识符进行攻击.如果您使用自定义会话处理程序,请确保跟踪您打开的标识符,如果它与您保存的标识符不同,则明确删除(或更改)旧标识符上的标识符.
使用默认会话处理程序,只需调用即可session_regenerate_id(true)
.这将删除旧的会话信息.旧ID不再有效,如果攻击者(或其他任何人)试图使用它,将导致创建新会话.但是要注意自定义会话处理程序....
如果您要销毁会话(例如注销时),请确保彻底销毁它.这包括取消设置cookie.使用session_destroy
:
function destroySession() {
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000,
$params["path"], $params["domain"],
$params["secure"], $params["httponly"]
);
session_destroy();
}
Run Code Online (Sandbox Code Playgroud)
Gum*_*mbo 37
两种会话攻击都有相同的目标:获得对另一个用户的合法会话的访问权限.但是攻击媒介是不同的:
在这两种攻击中,会话ID都是这些攻击所关注的敏感数据.因此,对于读访问(会话劫持)和写访问(会话固定),需要保护会话ID.
在这种情况下,使用HTTPS保护敏感数据的一般规则也适用.此外,您应该执行以下操作:
要防止会话固定攻击,请确保:
true
),并且仅在可能的情况下将其设置为HTTPS(将session.cookie_secure设置为true
); 你可以做到这两点session_set_cookie_params
.要防止会话劫持攻击,请确保:
true
)要防止两种会话攻击,请确保:
session_regenerate_id(true)
在身份验证尝试后(true
仅在成功时)或更改权限时更改会话ID 并销毁旧会话.(确保存储的任何更改$_SESSION
使用session_write_close
之前,如果你想保留相关的老ID的会话再生的ID;否则,只能使用新标识的会议将由这些变化的影响)你提到的令牌是"nonce" - 一次使用的号码.它们不一定只能使用一次,但是它们使用的时间越长,可以捕获和用于劫持会话的几率就越高.
nonce的另一个缺点是很难构建一个使用它们的系统,并允许在同一个窗体上有多个并行窗口.例如,用户在论坛上打开两个窗口,并开始处理两个帖子:
window 'A' loads first and gets nonce 'P'
window 'B' loads second and gets nonce 'Q'
Run Code Online (Sandbox Code Playgroud)
如果你无法跟踪多个窗口,你只能存储一个nonce - 窗口B/Q的nonce.当用户然后从窗口A提交他们的帖子并传入随机数'P'时,系统将拒绝该帖子为P != Q
.