Protecting your users session - url session vars / $_SESSION / $_COOKIE

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Protecting your users session - url session vars / $_SESSION / $_COOKIE

    I know this topic has come up before but there is a few issues that haven't been addressed ....
    this topic kind of started between me and arnage in the chat box so i thought i would make it a topic so everyone can see this discussion.

    First of all i would like to start out by saying by having url session variables is pretty much setting yourself up to be hacked via cross site scripting.
    most people are aware about referrer ( $_SERVER['HTTP_REFERER'] ) but for the few that dont it passes the last address of the last site you visited to the new site...

    An Easy Protection from this is to use a protection page where the url session is not passed to.
    eg: if your url session variable is named $sid then you will require a page before you goto the next site that does not collect $sid via $_GET['sid']

    Also you have to make sure no html injection can be made into your site.... this means protecting EVERY input a user can make (this includes ALL $_SERVER , $_SESSION , $_COOKIE , $_GET, $_POST , $_FILE, $_REQUEST etc) via htmlspecialchars() ... you should also use mysql_escape_string() on all these also.

    DO NOT TRUST ANY INPUT A USER CAN MAKE
    (even if you think theres no way of changing it in a million years)

    Do you use [ img] bbcodes ? if so make sure this is also protected against referrer etc by using a GD library.

    Q) Do you have image uploaders on your site? ... are they protected with GD library?
    A) No i have uploaders on my site for all types of files..... Well your at risk from a XSS hole from people stealing your url session variables and even checking every MIME type will not help you as this can be spoofed
    checking the digital signature of every file may help you as its doubtful anyone would go to so much trouble to steal a session of a wap site but even this can be spoofed :/
    i know some people dont like using GD library on .gif as without the aid of imagemagick it stops the animation from playing (animations to show or be hacked.... your choice)

    there is a few other methods of xss holes that also can be used against url session variables such as changing character encoding types etc .. which i havent mentioned but im trying to keep this from being to long a topic as people will not read all of this if i make it to long.
    (these methods can also be used to bypass your spam/bad word protection also.)

    you can protect your url session variables by protecting them by using a check against the browser name but pretty much everyone knows how to change your browser name these days...
    you can also protect against the same way by checking against IP .... however if you do this you are at risk of losing members as some networks such as orange change there ip`s frequently

    So the best option is to use $_SESSION or $_COOKIE to protect your users session....

    whats the difference between $_SESSION and $_COOKIE?
    $_SESSION is done via sever side where as $_COOKIE is client side (users browser) which can be easily changed by the user.
    $_SESSION also requires Cookies to be enabled on the users browser.

    So this means the initial session_id() gets stored as a $_COOKIE on the users browser and as we all know $_COOKIE`s can be edited by the user.
    which its is wise to use session_regenerate_id() every page load to enable a Dynamic session...

    How can $_SESSION be stolen ..... the main way a $_SESSION can be stolen is by being on shared Hosting by accessing the /tmp folder which is used by everyone... there is a few other methods that a hacker can use to impersonate a session
    which is why it would be a good idea to use a Dynamic session and then store old sessions .... and log both users out if an old session is used. (log both out because the REAL USER might send the old session id and not the hacker)


    Im going to stop here with this post as otherwise my post is going to be to long and people wont read it ... but i could keep going lol
    Last edited by something else; 18.04.12, 20:37.

    #2
    Well if i can add, if many _SERVER are used theirs value can be converted globaly like:

    PHP Code:
    if (isset($_SERVER)) {
     foreach (
    $_SERVER as $key => $value) {
      
    $_SERVER[$key] = htmlentities($valueENT_QUOTES'UTF-8');
     }
     unset(
    $_SERVER[$key]);

    And $_SERVER['HTTP_REFERER'] should be used with HTTP_HOST and checked.

    There are many thing like $sid = $_GET['sid']; or $id = $_GET['id']; and right after something like:

    PHP Code:
    mysql_query("SELECT * FROM `table` WHERE `id` = '".$id."'"); 
    GETting var like that is outdated, it always needs to be checked if is isset(). I like to use ternary here, saves space.
    If its like that $sid, it is most likely md5 hash, string with letters and numbers so check it for that:

    PHP Code:
    $sid = !empty($_GET['sid']) ? (preg_match('/^[a-z0-9]{32}$/iD'$_GET['sid']) ? $_GET['sid'] : null) : null
    and in case of $id which is number, check it is it a number:

    PHP Code:
    $id = empty($_GET['id']) ? null abs(intval($_GET['id'])); 
    And recheck before query is that var with desired value:

    PHP Code:
    if (!empty($id)) {
    // in the bussines

    As for the previous query, $id is quoted like string, not number and plus in double quotes. First, it needs to be like:
    PHP Code:
    mysql_query("SELECT * FROM `table` WHERE `id` = ".$id.""); 
    .. but i really like single quotes in queries simply because php parser doesn't apply \n in it. ;)

    I would write it like this for number:
    PHP Code:
    mysql_query('SELECT * FROM `table` WHERE `id` = '.$id.''); 
    this for vars like $sid:
    PHP Code:
    mysql_query('SELECT * FROM `table` WHERE `sid` = "'.$sid.'"'); 
    this for functions:
    PHP Code:
    mysql_query('SELECT * FROM `table` WHERE `fun` = "'.some_function().'"'); 
    or if function returns int:
    PHP Code:
    mysql_query('SELECT * FROM `table` WHERE `int` = '.some_function().''); 
    As for _SESSIONs and logins, its just used to carry login data arround after
    - filed form
    - select query user name and password
    - if true passing those to _SESSION

    ... so by my oppinion is the best to make some function and to check it friquentely, like:

    PHP Code:
    function users() {
     
    $username = !empty($_SESSION['username']) ? safe_query_function($_SESSION['username']) : null;
     
    $password = !empty($_SESSION['password']) ? safe_query_function($_SESSION['password']) : null;
     if (isset(
    $username$password)) {
      
    $query mysql_query('SELECT * FROM `users` WHERE `username` = "'.$username.'" AND `password` = "'.$password.'" LIMIT 1');
      return (bool) (
    mysql_num_rows($query) > 0);
     } else {
      return 
    false;
     }
    }
    if (
    users()) {
    // in the bussines

    Hope this helps.
    Last edited by arnage; 18.04.12, 21:18.
    <!DOCTYPE html PUBLIC "-//WAPFORUM.RS

    Comment


      #3
      OMG , i love this thread :D .. it helps me on security ..

      one little question if is number for example $id i use to check it as is_numeric($id) is there something wrong on that .. regarding security ?
      This is ten percent luck, twenty percent skill
      Fifteen percent concentrated power of will
      Five percent pleasure, fifty percent pain

      And a hundred percent reason to remember the name!

      Comment


        #4
        is_numeric() will except 1e3 or 0xf5

        but you can use ctype_digit("1e3") which will return false and is faster than an if statement
        note: ctype_digit("") has to be a numerical string not an integer
        also you can use things like:
        PHP Code:
        if(!ctype_alpha($page)) exit; 
        for letters only to protect against include attacks against things like:
        PHP Code:
        include_once("$page.php"); 
        to stop the hacker ffrom seting page=../../somefile.php?blah= etc

        Comment


          #5
          This Thread should be sticky.

          Comment


            #6
            Originally posted by something else View Post
            is_numeric() will except 1e3 or 0xf5

            but you can use ctype_digit("1e3") which will return false and is faster than an if statement
            note: ctype_digit("") has to be a numerical string not an integer
            also you can use things like:
            PHP Code:
            if(!ctype_alpha($page)) exit; 
            for letters only to protect against include attacks against things like:
            PHP Code:
            include_once("$page.php"); 
            to stop the hacker ffrom seting page=../../somefile.php?blah= etc

            oo i didn't knew that : D thanx a lot . .. i likely use is_numeric(); on pagination ... i will change it .. good to know such things !
            This is ten percent luck, twenty percent skill
            Fifteen percent concentrated power of will
            Five percent pleasure, fifty percent pain

            And a hundred percent reason to remember the name!

            Comment


              #7
              Originally posted by arnage View Post
              PHP Code:
              mysql_query("SELECT * FROM `table` WHERE `id` = ".$id.""); 
              .. but i really like single quotes in queries simply because php parser doesn't apply \n in it. ;)

              I would write it like this for number:
              PHP Code:
              mysql_query('SELECT * FROM `table` WHERE `id` = '.$id.''); 
              These 2 methods of mysql_querys can be sql injected if the $id is not verified as an integer even if you use mysql_escape_string() on it..
              mysql_escape_string adds a backslash to things like ' to change it to \'
              however an injection may contain no ' eg:
              PHP Code:
              1 UNION SELECT password FROM users WHERE id 
              your mysql_query would now look like:
              PHP Code:
              mysql_query("SELECT * FROM `table` WHERE `id` = 1 UNION SELECT password FROM users WHERE id = 1"); 

              Comment


                #8
                Nope, it can't. The first one can because of double quotes, with only single quotes doesn't, it will return false itself.
                And it is checked in ternary with abs() and intval(), first to be positive and second to be int (or float), and than it goes to empty() check which returns false on 0 value (if is tried to inject anything, regardless of previous int checking) and for floats like 0.0...
                This is rock solid, it even doesn't need mysq real escape string in this particular case.
                I will write one example tomorrow, now im by phone so can:t type that much.
                Last edited by arnage; 18.04.12, 21:32.
                <!DOCTYPE html PUBLIC "-//WAPFORUM.RS

                Comment


                  #9
                  Originally posted by arnage View Post
                  Nope, it can't. The first one can because of double quotes, with only single quotes doesn't, it will return false itself.
                  And it is checked in ternary with abs() and intval(), first to be positive and second to be int (or float), and than it goes to empty() check which returns false on 0 value (if is tried to inject anything, regardless of previous int checking) and for floats like 0.0...
                  This is rock solid, it even doesn't need mysq real escape string in this particular case.
                  didnt realize it wouldnt with single quotes

                  but this is also where you shouldnt use mysql_error() as you can crash the sql then mysql_error() will give away table names/rows

                  Comment


                    #10
                    I never use it except to see some result which i dont't understand, than its removed.
                    Most of my queries are in if() condition or its result, or if on some 100% safe page, like adding mod status or the like, mysql query error is suppresed with @ sign.
                    <!DOCTYPE html PUBLIC "-//WAPFORUM.RS

                    Comment


                      #11
                      here a nice read on $_SESSION and $_COOKIES for people wanting to update there site from a url session
                      Cookies and Sessions | Practical PHP Programming | TuxRadar Linux

                      Comment


                        #12
                        Originally posted by something else View Post
                        here a nice read on $_SESSION and $_COOKIES for people wanting to update there site from a url session
                        Cookies and Sessions | Practical PHP Programming | TuxRadar Linux
                        Nice tut lol

                        Author's Note: Are cookies dangerous? No, not at all ... However, they cannot read your credit card number, raid your fridge, or anything of the sort!

                        hahaaa
                        This is ten percent luck, twenty percent skill
                        Fifteen percent concentrated power of will
                        Five percent pleasure, fifty percent pain

                        And a hundred percent reason to remember the name!

                        Comment


                          #13
                          can stolen cookies used for accessing a page without logging in?
                          Last edited by suael; 06.05.12, 14:30.

                          Comment


                            #14
                            Originally posted by suael View Post
                            can stolen cookies used for accessing a page without logging in?
                            yes providing that site hasnt got different protection such as same ip number

                            Comment


                              #15
                              i av tried thz code to get source code of secret.php usng cookies of my own account but failed . .showng connection closed by remote server . . wht would be the error. . ?
                              Last edited by suael; 07.05.12, 03:53.

                              Comment

                              Working...
                              X