Decrease responsibility of a class

Asked

Viewed 97 times

2

I recently had the need to work with object-oriented sessions and created the following class:
https://github.com/mateusdemboski/PHPsessionManager/blob/master/src/Session.php

<?php
/**
 * @author Mateus Demboski <[email protected]>
 * @link <https://github.com/mateusdemboski/PHPsessionManager>
 */

#namespace Demboski;

/**
 * Class Session
 */
class Session {

    /**
     * Verify if a PHP session already been started.
     *
     * @return bool
     */
    public static function isStarted(){
        return session_status() == PHP_SESSION_ACTIVE;
    }

    /**
     * Verify if a key exists on session.
     *
     * @param null $session_key
     * @return bool
     */
    public static function exists($session_key = null){
        return isset($_SESSION[$session_key]);
    }

    /**
     * Initialize session data. If session has already started in PHP the
     * script generate a exception.
     *
     * @return bool
     * @throws \Exception
     */
    public static function start(){
        if(self::isStarted())
            throw new \Exception('A session has already started in PHP!');

        return session_start();
    }

    /**
     * Destroys all data registered to a session.
     *
     * @return bool
     */
    public static function destroy(){
        return session_destroy();
    }

    /**
     * Get the value by key from current session.
     *
     * @param string|int $session_key
     * @param bool $unserialize
     * @return string|null
     */
    public static function get($session_key, $unserialize = false){
        if(!self::isStarted())
            throw new \BadFunctionCallException('A session in PHP need be started!');

        if(self::exists($session_key))

            if($unserialize)
                return unserialize(base64_decode($_SESSION[$session_key]));

            else
                return $_SESSION[$session_key];

        else return null;
    }

    /**
     * Assign a value from key in the current session.
     *
     * @param string $session_key
     * @param mixed $value
     * @param bool $serialize
     * @return bool
     */
    public static function set($session_key, $value, $serialize = false){
        if(!self::isStarted())
            throw new \BadFunctionCallException('A session in PHP need be started!');


        if($serialize) $value = base64_encode(serialize($value));

        $_SESSION[$session_key] = $value;

        return $_SESSION[$session_key] == $value;
    }

    /**
     * Delete an item from session by key.
     *
     * @param $session_key
     * @return bool
     */
    public static function delete($session_key){
        if(!self::isStarted())
            throw new \BadFunctionCallException('A session in PHP need be started!');

        $return = true;

        if(self::exists($session_key))
            unset($_SESSION[$session_key]);
        else
            $return = false;

        return $return;
    }

    /**
     * Destroys all data registered to a session and start a new session.
     *
     * @return bool
     */
    public static function clean(){
        if(!self::isStarted())
            throw new \BadFunctionCallException('A session in PHP need be started!');

        self::destroy();
        self::start();
        return true;
    }

    /**
     * Set the current session name.
     * The session name references the name of the session, which is
     * used in cookies and URLs (e.g. PHPSESSID).
     *
     * @param null $session_name
     * @return string
     */
    public static function setName($session_name = null){
        return session_name($session_name);
    }

    /**
     * Get the current session name.
     * The session name references the name of the session, which is
     * used in cookies and URLs (e.g. PHPSESSID).
     *
     * @return string
     */
    public static function getName(){
        return session_name();
    }

    /**
     * Set the current session id
     *
     * @param null $session_id
     * @return string
     */
    public static function setId($session_id = null){
        return session_id($session_id);
    }

    /**
     * Get the current session id
     *
     * @return string
     */
    public static function getId(){
        return session_id();
    }

    /**
     * Update the current session id with a newly generated one.
     *
     * @param bool $deleteOldSession
     * @return bool
     */
    public static function regenerateId($deleteOldSession = false){
        return session_regenerate_id($deleteOldSession);
    }

    /**
     * prevent the session hijacking
     *
     * @param string $session_key Default is "PREVENT_SESSION_HIJACKING".
     * @param array $hashAlgo Is the Name of selected hashing algorithm (e.g. "md5", "sha256", "haval160,4", etc..)
     * @param int|string $exit Default is 1.
     */
    public static function preventHijacking($session_key = 'PREVENT_SESSION_HIJACKING',
                                            $hashAlgo = 'md5',
                                            $exit = 1){
        $hashData = $_SERVER['HTTP_USER_AGENT'] . $_SERVER['REMOTE_ADDR'];
        $hash = hash($hashAlgo, $hashData);
        if(self::isStarted() && !self::exists($session_key))
            self::set($session_key, $hash );
        elseif(self::isStarted() || !self::exists($session_key) || self::get($session_key) != $hash ){
            exit($exit);
        }
    }
}

But she seems to have a lot of responsibilities, like the method preventHijacking is a method of security for sessions and does not seem to me to be in the right place, but at the same time I think it is unnecessary to create a new class within the namespace only for this method.

What could be done in this case?
How could this class be improved?

  • 1

    In my view the method is ok preventHijacking. It might be interesting for you to rewrite your code to work as one custom Session Handler and natively include the preventHijacking in traditional PHP calls.

1 answer

2


As far as the class is concerned, I do not see any problem, and I do not understand the responsibility described in the question. The best answer can only be given after the project will be examined.

Preventing Hijaking from sessions is a recurring subject, approaches are several but experience has led me to address some methods:

1) always use https - this because it is filtered too much problem associated with session theft.

2) regenerate the session_id where possible it is equally important especially to each new "login" and "logout" if this is the case for the project.

3) I recommend a reading in my reply on Prevention Session Hijacking

Finally I recommend the use of a TOKEN that is generated every request, also in session.

Everything together makes it very difficult and prevents session theft competently.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.