0

I am trying to understand sessions in php. As far as I understand in a basic login system the sessions work like this: On a page exampledomain.com/login.php:

if (password_verify($_POST['user_password'], $result->password_hash)) {
  //write user data into PHP SESSION
  $_SESSION['user_name'] = $_POST['user_name'];
}

Then on the pages that only logged in users can view I check:

if (isset($_SESSION['user_name'])) {
  //do something
}

Now what I don't understand is what if a hacker on his own servers (hackerdomain.com) does something like this assuming he knows a username:

session_start();
$_SESSION['user_name'] = 'Test';

<form method="post" action="exampledomain.com/page-only-logged-in-users-can-view.php" name="loginform">
 <input type="submit"  name="login" value="Login" />
</form>

Now he set a value in $_SESSION['user_name'] so he will be logged in wihtout even needing a password. I got very confused about this session thing. I read php documentation but I still don't get it.

Ikhlak S.
  • 8,578
  • 10
  • 57
  • 77
Victordb
  • 519
  • 1
  • 11
  • 25
  • 1
    Session is only for your server, so no other server can't alter session details. – Lovepreet Singh Jul 04 '18 at 17:29
  • @LovepreetSingh can't* – Core972 Jul 04 '18 at 17:31
  • 1
    But basically My Server cannot get at Your Servers Sessions – RiggsFolly Jul 04 '18 at 17:33
  • 1
    ^^^^ what he said. However, sessions can be stolen and manipulated within your own server. If you use weak SESSION ids it could be brute-forced, or it may be leaked, which then the hacker may take advantage of it and identify himself as the owner of the session. – Sam Jul 04 '18 at 17:33
  • ^ But even then, the hacker can't write arbitrary data to `$_SESSION` (unless your code allows it). So even if I intercepted Alice's session cookie, I can't then use it to pretend to be Bob. – Niet the Dark Absol Jul 04 '18 at 17:36
  • Depends on the quality of the programmer... Think for instance they check `$_SESSION` ids with cookies? If there's no session, but it finds a cookie then it does its thing based on cookie value. – Sam Jul 05 '18 at 00:20

2 Answers2

1

A session in the end is a cookie that a server send to the browser. This cookie is special and has some properties like:

  • Name. For example, in php by default, PHPSESSID
  • Value. For a session id, a random string identifying the cookie on the server (this cookie has associated data like user name, email, etc)
  • Domain: Defines domain scope of the cookies, where the cookie will be send by browser (eg: a non value means just the main domain server generating the cookie without subdomains. A domain value includes subdomains by default)
  • Path: Path indicates a URL path that must exist in the requested URL in order to send the Cookie header
  • Expires / Max-Age: Expires the cookie at certain time (eg: 2018-08-03T17:30:56.146Z)
  • httpOnly: boolean value, if true then cookie can't be accessed by javascript (document.cookie) to prevent XSS attacks
  • Secure: boolean value, if true cookie must be sent under https
  • Same site: SameSite cookies let servers require that a cookie shouldn't be sent with cross-site requests, which somewhat protects against cross-site request forgery attacks (CSRF). SameSite cookies are still experimental and not yet supported by all browsers.

More info at https://developer.mozilla.org/es/docs/Web/HTTP/Cookies

Jose Mato
  • 2,709
  • 1
  • 17
  • 18
  • So basically a session can only be set by me or my app, no user can set a value in a session if my app does not allow them to? Is that correct? – Victordb Jul 04 '18 at 17:49
  • Yes, that assumption is correct :)) A cookie generated on your server can't be modified in other server. To perform a session hijack, the attacker needs the value of the session id (phpsessid) and this could be obtainer with XSS for example, that's the reason it's good to use the flag httpOnly (and the secure option true). If someone at frontend level (browser) tries to modify the phpsessid then the session will be invalid at backend, returning an access error (401 / whatever you indicate) – Jose Mato Jul 04 '18 at 17:53
  • So to be clear, on a basic login system, a user inputs username and password, I check it against database and if they match I set a session with whatever value (even number 1) and on the protected pages I check only if that session variable is set? And if it's set I know for sure only the users that input username and password can view that page? – Victordb Jul 04 '18 at 18:57
  • Yes, it's correct, you store a value like 1 (accessGranted = 1 for example) and the users when visit each protected page, browser will send the cookie and you will know for sure the user was logged in (this is the behaviour for session cookies). So, short answer, yes. – Jose Mato Jul 04 '18 at 19:00
  • Thank you, and everyone else for replies. One more thing what do you mean by behavior for session cookies is there any other type of sessions? – Victordb Jul 04 '18 at 19:13
  • Yes, sending a bearer token/jwt token as http header for example. In that way you are not handling default sessions (stored in a file insode the server) and avoiding session cookies propagation between load balancers (each server behind a balancer by default have their own session ids) – Jose Mato Jul 04 '18 at 21:31
1

Session is stored on the server that handles the request. For each session an unique identifier is being generated.

There are some attacks against sessions:

  • Session Fixing - when the attacker knows session id he can explicitly set PHPSESSID in the url. Normally, this is set within a cookie file
  • Session side jacking when you use packet sniffer to get the cookie and you use this cookie.
  • XSS when someone put some code f.e into iframe and when you enter the page it executes the code with your rights according to session

If a hacker does what you wrote it will generate session but on his own server not on yours. By default PHP stores sessions in files a directory is set in php.ini and can be visible with session_save_path(); function. Even though he executes the same code he won't have access to $result->password_hash because I guess it comes from DB which he doesn't have an access to.

Hopefully, you understand it now.

Robert
  • 19,800
  • 5
  • 55
  • 85