3

I've made a simple login form. It's made very generic to be used for any project. Now I wonder if the security is good enough and if my approach is safe.

On success

When successfully logged in I do two things. I set a cookie with username and hash (sha256). I also write a temp file to the server with the username and hash (sha256). Both username and hash now matches the cookie.

Can be logged in the day after

The reason for this approach is that I can still be logged in a day later. It does not need to check password, just match the hashes for that username.

Can it be easily hacked?

Is this a good approach? If not, what are the pitfalls? Can it be easily hacked? If so give alternatives.

If you need more information about the project, the full form is here https://github.com/jenstornell/wall and only the login part is here: https://github.com/jenstornell/knock

9
  • 3
    Is there a reason you're doing this instead of following any of the existing session standards?
    – Paul
    Commented Mar 11, 2019 at 11:59
  • 1
    what is it you're hashing?
    – TZHX
    Commented Mar 11, 2019 at 12:06
  • 5
    @JensTörnell existing PHP session implementations, JSON Web Tokens, etc. This is not ground you need to spend time plowing yourself.
    – Paul
    Commented Mar 11, 2019 at 13:31
  • 1
    If you change the hash to a random value (not the password hash) then you have basically invented sessions. Commented Mar 13, 2019 at 1:53
  • 1
    There's nothing wrong in asking to the user for its credentials now and then for security reasons. Some apps out there gives you the "perception" of long living sessions but they implement "refresh tokens" under the hood.
    – Laiv
    Commented Mar 13, 2019 at 7:55

4 Answers 4

2

I agree with nadir that this is not a space where you should 'roll your own' but I think it's long overdue that we start talking about how these things go wrong because it's the app developers that are creating these vulnerabilities and we need to learn how to stop doing that.

The biggest problem I see here is that you are storing the exact value needed to access the system. In a way, it's kind of like storing passwords in the clear. The issue is that there are many vulnerabilities in systems that allow attackers to get access to stored data like this. In this case, you were planning to store this in a file. A very common exploit is path/directory traversal. The 4th example shows a PHP example. You could move this into a database perhaps but PHP frameworks are notorious for SQL injection vulnerabilities due to the unwillingness or inability to use parameterized queries.

You need to operate under the presumption that these values might be retrieved and how to avoid them being used to access your system more broadly. In the case of passwords, if an attacker gets the shadow file full of hashes, they can't use them directly. A (ideally) costly process of cracking needs to be performed to get the actual passwords. But in your proposal, if the find a way to traverse the file system and get these files, it's basically game over: they've gained access.

Please don't take this to mean that if you've solved these issues, you have made your solution bullet-proof. Security is asymmetrical. An attacker just needs to find a hole or two. Th defender needs to plug all the holes. This is why it's best to leave the security tools to people who focus on that. I'm not saying you shouldn't try to understand, just that if you built your own, you are likely to make some of the same mistakes that have been made many times before.

6
  • I have not found a good login form that I can use for my tools. Therefor I built my own. For now I will still try to battle the problems one by one. If it doesn't work out, I've probably learned something on the way. Good point about the exact value stored in the file. A solution to that problem may be to have an option with a salt. Cookie hash may be alonghash and the file will be like hash('sha256', 'alonghashMySalt'). What do you think? Commented Mar 12, 2019 at 7:49
  • I think the comment from @Paul is right on target. Take your overall idea of a form that handles all the security details but build it upon JWT (or something similar) that already has a lot of researchers banging on it and is actively being improved.
    – JimmyJames
    Commented Mar 12, 2019 at 13:31
  • Essentially your solution is much like storing passwords. Here's a (out-of-date) article that goes through the history and basics. You would think that was a solved problem but the standards of what is considered secure is constantly in motion. Since that article Argon2 is the thing I'm seeing recommended. That's part of the reason you don't want to do this on you own. This kind of thing is never done. It's a full time job.
    – JimmyJames
    Commented Mar 12, 2019 at 13:35
  • 1
    To make the last bit more clear: This kind of thing is never complete. It's a full time job
    – JimmyJames
    Commented Mar 12, 2019 at 21:30
  • @JensTörnell I was reading something yesterday and feel the need to follow up on this. I found some articles that suggest that JWT is not a good solution for session management here and here. I found these from this article that is extremely critical of JWT and the related standards.
    – JimmyJames
    Commented Mar 14, 2019 at 13:34
1

For example; if someone got his hands on the username and hash "somehow", he can impersonate this user on your service and act on her behalf.
It's discouraged, even more so as a software-engineer, to try to devise "new"/personal security schemes from the ground up.
Security is a (highly) complex problem, so it's encouraged to reuse existing, maintained and long-standing solutions and to integrate them to your application using best practices.

5
  • I see. What I don't understand is how someone can get the hash from my cookie. It's only available from that specific domain "scope". Commented Mar 11, 2019 at 14:20
  • 1
    Make it simple; the attacker sniffed it, guessed it, XSS it etc.
    – nadir
    Commented Mar 11, 2019 at 14:28
  • 1
    @JensTörnell Other attack vector: got 5 seconds at the user's computer and took a picture in the devtools of your cookie value. Or they injected scripts on your page via XSS, or sniffed traffic, or are making milions of requests per second to guess it. For security, it's best to leave things to security experts who've already thought of and done this work, so you can focus on the real problems you're facing.
    – Delioth
    Commented Mar 11, 2019 at 16:32
  • 1
    This is really more of a comment than an answer right now.
    – Paul
    Commented Mar 11, 2019 at 21:13
  • 2
    @Delioth Stealing cookies is mostly a made-up problem. There is no reliable protection from it, and most existing solutions don't even try. And if there is an XSS vulnerability, then stealing the cookie exacerbates the issue, but only by a little.
    – Frax
    Commented Mar 12, 2019 at 6:30
1

There are three important things for me:

1. Unpredictable Code:

Your code should not be predictable. You are using username and hash. If this hash is static or predictable, it is really important vulnerability.

2. Secure Code

You need to secure where you store your code. If it is in cookie, then it must be HttpOnly and transferred via secure network.

3. Do not give unlimited access

Even for eligible user, do not give unlimited access. Give time limited access and extend it if needed.

4
  • 1. Very good point. I think I will implement options for what these should be. 2. I searched for it but the answer I got is that there is no such thing as a readonly cookie. 3. Also a good point. I've read about ajax that triggers a PHP file to keep the cookie alive. Not sure how good that solution is. Commented Mar 12, 2019 at 7:55
  • 1
    I am not familiar with PHP but you just need to create cookie and set cookie value by your hash value and make cookie readOnly(httpOnly). To secure cookie value to be stolen, transfer it via secure network(https). By this way, no one can read or change cookie value but when user request to server, you can read this cookie value from server. Then, validate it. This is main Cookie Authentication mechanism
    – Engineert
    Commented Mar 12, 2019 at 8:11
  • Yes, it's supported by PHP. In the PHP docs it says: "httponly When TRUE the cookie will be made accessible only through the HTTP protocol. This means that the cookie won't be accessible by scripting languages, such as JavaScript. It has been suggested that this setting can effectively help to reduce identity theft through XSS attacks (although it is not supported by all browsers), but that claim is often disputed." Commented Mar 12, 2019 at 8:17
  • For more reading... php.net/manual/en/function.setcookie.php Commented Mar 12, 2019 at 8:17
1

There has been many great answers and comments. I think it's unfair to accept one of them because every answer put something to the table. Instead I'll make a summery.

Problem

  1. Don't use predictable cookie keys like username and hash.
  2. Don't match the cookie hash with the file hash in case hacking the file system.
  3. HttpOnly is needed.
  4. Don't keep the cookie around for 20 years.
  5. Don't send things over http, only with https.
  6. Prevent XSS attacks.
  7. Prevent a million request to guess the password and username.
  8. Prevent sniffing attacks.
  9. Don't do security yourself.

Solution

  1. I added an option to set custom cookie keys.
  2. I added an option to set a custom salt that is hashed with the hash.
  3. I set HttpOnly to true in setcookie.
  4. I will keep it shorter, like 2 days or 2 weeks before needing to login again.
  5. I set secure to true in setcookie.
  6. I will include more secure headers
  7. To succeed with such attack, even if they know the username, they need both the cookie hash key and the hash+salt. The server will go down and the sun will go out before then.
  8. I added header("X-Content-Type-Options: nosniff");
  9. I still want to try it out. Sorry if I'm too stubborn.

If I've missed something, I will keep this updated

1
  • 1
    Seems ok. These are common matters to keep in mind with client-side sessions. Never trust blindly on the client-side because you have no way to be sure about who or what is sending requests to the server. Finally, whether you store the hash in temp files or in databases is irrelevant. These are mere implementation details.
    – Laiv
    Commented Mar 13, 2019 at 10:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.