在 PHP 中使用会话和 cookie 创建安全登录

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5435068/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 21:23:54  来源:igfitidea点击:

Creating a secure login using sessions and cookies in PHP

phpsecuritysessionauthenticationcookies

提问by steveo225

I am making a login script that I would like to be as secure as possible. Problem is, security seems to be a never ending battle. So essentially, I am looking for suggestions and improvements to my ideas.

我正在制作一个我希望尽可能安全的登录脚本。问题是,安全似乎是一场永无止境的战斗。所以基本上,我正在寻找对我的想法的建议和改进。

What I have is a login based solely on sessions. Anytime the session information changes, session_regenerate_id()is called to avoid obvious hiHymaning attempts.

我所拥有的是仅基于会话的登录。每当会话信息发生变化时,session_regenerate_id()都会调用它以避免明显的劫持尝试。

When the session is not set, I check a cookie for valid login, and on success, I update the session.

如果未设置会话,我会检查 cookie 是否有效登录,成功后,我会更新会话。

I attempt to secure the cookie by adding a hash value along with a piece of unique user information (like username or id). This hash is comprised of various information, including the username/id, undecipherable password hash, part of the IP address, etc. By extracting the username/id from the cookie, I can make a new hash from the valid user information and compare that with the hash in the cookie. My hopes here are to prevent fake cookies and cookie hiHymaning (unless they also spoof the IP address).

我尝试通过添加一个散列值以及一条唯一的用户信息(如用户名或 ID)来保护 cookie。这个散列由各种信息组成,包括用户名/id、无法破译的密码散列、部分IP地址等。通过从cookie中提取用户名/id,我可以从有效的用户信息中制作一个新的散列并进行比较与 cookie 中的哈希值。我的希望是防止假 cookie 和 cookie 劫持(除非他们也欺骗 IP 地址)。

EDITAssume that the login itself will be done via HTTPS/SSL, so the transfer is (reasonably) secure.

编辑假设登录本身将通过 HTTPS/SSL 完成,因此传输是(合理)安全的。

Am I on the right track? What else can be done to secure my login?

我在正确的轨道上吗?还可以采取哪些措施来保护我的登录信息?

Thanks for the help!

谢谢您的帮助!

采纳答案by RT Cunningham

There is no such thing as secure cookie UNLESS it's transmitted over SSL only. It can be mitigated some when using a persistent non-session cookie (like remember me), by doing exactly what you're doing, but not in the same way you're thinking of doing it.

没有安全 cookie 之类的东西,除非它仅通过 SSL 传输。在使用持久性非会话 cookie(如记住我)时,可以通过完全执行您正在执行的操作来减轻一些影响,但与您所考虑的操作方式不同。

You can indeed store server variables such as the user-agent, the ip address and so forth (and even JavaScript variables), but they are only good for validating that the persistent cookie data matches the client's new connection. The ip address isn't a good idea except when you know that the client (like you only) isn't going to change on every page load (a la AOL).

您确实可以存储服务器变量,例如用户代理、IP 地址等(甚至是 JavaScript 变量),但它们仅适用于验证持久性 cookie 数据是否与客户端的新连接匹配。IP 地址不是一个好主意,除非您知道客户端(仅像您一样)不会在每次页面加载时都更改(美国在线)。

Modern web browsers and 3rd party services like LastPass can store login credentials that only require a key press (and sometimes not even that) to send the data to the login form. Persistent cookies are only good for those people who refuse to use what's available otherwise. In the end, persistent, non-session cookies are not really required anymore.

现代 Web 浏览器和 LastPass 等 3rd 方服务可以存储登录凭据,只需按一下键(有时甚至不需要)即可将数据发送到登录表单。持久性 cookie 只适合那些拒绝使用其他可用内容的人。最后,不再需要持久的、非会话的 cookie。

回答by rook

Stop what you are doing. Do not check the user-agentor the ip address. The user-agent is an attacker controlled variable and checking this value does not increase the security of this system. The ip address will change for legitimate reasons, such as if a user is behind a load balancer or TOR.

停止你正在做的事情。不要检查user-agent或 ip 地址。用户代理是攻击者控制的变量,检查该值不会增加系统的安全性。IP 地址会因合法原因而更改,例如用户是否在负载均衡器或 TOR 后面。

A session id must always be a cryptographic nonce. In php just call session_start()and then start using the $_SESSIONsuper global. PHP takes care of all of this for you. If you want to improve php's session handler, use the configurations. Enable use_only_cookies, cookie_httponlyand cookie_secure. Also setting the entropy_fileto /dev/urandomis a good idea if you are on a *nix system but if your under windows then your in trouble.

会话 id 必须始终是加密 nonce。在 php 中只需调用session_start()然后开始使用$_SESSION超级全局。PHP 会为您处理所有这些。如果您想改进 php 的会话处理程序,请使用配置。启用use_only_cookiescookie_httponlycookie_secure。如果您使用的是 *nix 系统,那么设置entropy_fileto/dev/urandom也是一个好主意,但如果您在 Windows 下,那么您就有麻烦了。

For instance to authenticate a user:

例如验证用户:

//In a header file
session_start();
...
if(check_login($_POST['user_name'],$_POST['password'])){
   //Primary key of this user
   $_SESSION['user_id']=get_user_id($_POST['user_name']);
   $_SESSION['logged_id']=True;
}

And to verify if a user is logged in:

并验证用户是否已登录:

//in a header file
session_start()
...
if(!$_SESSION['logged_id']){
   header("location: login.php");
   die();//The script will keep executing unless you die()
}

To improve this system read OWASP A9 and use HTTPS for the entire life of the session. Also read OWASP A5: CSRF aka "session riding" and OWASP A2: XSS because they can both be used to compromise a session.

要改进此系统,请阅读 OWASP A9 并在整个会话期间使用 HTTPS。另请阅读 OWASP A5:CSRF 又名“会话骑行”和 OWASP A2:XSS,因为它们都可用于破坏会话。

回答by RT Cunningham

I use a cookie based method (using setcookie function) but ....

我使用基于 cookie 的方法(使用 setcookie 函数)但是 ....

session_start();
...
if(check_login($_POST['user_name'],$_POST['password'])){
   //Primary key of this user
   $_SESSION['user_id']=get_user_id($_POST['user_name']);
   $_SESSION['logged_id']=True;
}

...these methods are wrooooong !!!!

...这些方法太棒了!!!!

I crack my website with an attack based on the cookie.

我通过基于 cookie 的攻击来破解我的网站。

  1. I used cookie option of the WebCruiser vulnerability scanner, so I get my cookie after login.
  2. Then I changed a simply value on cookie
  3. Then I clicked save cookie.
  4. At this point I clicked on webbrowser see on the left panel then I clicked right then I clicked on refresh page, so I got my admin page without using the login page with user and password.
  1. 我使用了 WebCruiser 漏洞扫描器的 cookie 选项,所以我在登录后得到了我的 cookie。
  2. 然后我在 cookie 上更改了一个简单的值
  3. 然后我点击了保存cookie。
  4. 在这一点上,我点击了左侧面板上的 webbrowser see 然后我点击了右边然后我点击了刷新页面,所以我得到了我的管理页面,而没有使用带有用户和密码的登录页面。

So if someone push you a virus to read the cookie history of IE or Firefox, you'll be happy to find out your admin user and pass can be used by others.

因此,如果有人向您推送病毒以读取 IE 或 Firefox 的 cookie 历史记录,您会很高兴发现您的管理员用户和密码可以被其他人使用。

So how to fix the problem? Simple: combine the cookie with session server or session's cookie with sessions server, or session with file session, or cookie with file session.... will be secure but slow :((((

那么如何解决问题呢?简单:将 cookie 与会话服务器或会话的 cookie 与会话服务器,或会话与文件会话,或 cookie 与文件会话.... 将是安全的但很慢 :((((

回答by Ali Al-Naimi

SESSION more secure than cookie and my advise is to create a unique id for the current login attempted like :

SESSION 比 cookie 更安全,我的建议是为当前尝试的登录创建一个唯一的 ID,例如:

$id = uniqid();
$_SESSION['username'.$id] = "something ...";

回答by dbers

I keep all login data in the users session, this way its all stored server side.

我将所有登录数据保存在用户会话中,这样所有的登录数据都存储在服务器端。

The only thing i would store in a client cookie is stuff like 'auto login', 'session id'

我唯一会存储在客户端 cookie 中的是诸如“自动登录”、“会话 ID”之类的东西