Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal for Enhancing Session Security in Fat-Free Framework #383

Open
Division70 opened this issue Dec 22, 2024 · 0 comments
Open

Proposal for Enhancing Session Security in Fat-Free Framework #383

Division70 opened this issue Dec 22, 2024 · 0 comments

Comments

@Division70
Copy link

Dear F3 Developer Community,

I'd like to propose an enhancement to the read() function in the session handling mechanism of Fat-Free Framework. The current implementation, while effective, may be too rigid for certain use cases, particularly in mobile environments where IP addresses can change frequently.

Here's a summary of the proposed changes:

  1. Implement a threat level assessment system instead of a binary check.
  2. Allow for customizable handling of high-threat situations.
  3. Improve logging for suspicious sessions.

Key features of the proposed implementation:

  • A point-based threat level system that considers IP changes, user agent changes, and session inactivity.
  • Configurable thresholds for threat levels and inactivity timeouts.
  • A hook for custom high-threat handling, falling back to the default 403 error if not defined.
  • Enhanced logging for low to medium threat levels.

This approach aims to balance security with flexibility, allowing developers to fine-tune the session security according to their specific needs while maintaining a robust default behavior.

I welcome any feedback, suggestions, or concerns from the community. Thank you for considering this proposal.

Best regards,

Christophe ROLLAND

Here's a snippet of the core changes:

const THREAT_LEVEL_HIGH = 3;
const INACTIVITY_THRESHOLD = 3600;

/**
*	Return session data in serialized format
*	@return string
*	@param $id string
**/
function read($id) {
	$this->sid=$id;
	if (!$data=$this->_cache->get($id.'.@'))
		return '';
	$this->_data = $data;
	if ($data['ip']!=$this->_ip || $data['agent']!=$this->_agent) {
		$fw=Base::instance();
		$threatLevel = 0;

		// Vérify IP
	    if ($this->_ip != $data['ip']) {
	        $threatLevel += 1;
	    }

	    // Vérify Agent
	    if ($this->_agent != $data['agent']) {
	        $threatLevel += 2;
	    }

	    // Vérify timestamp
	    $lastActivity = $this->stamp();
	    $currentTime = time();
	    $timeDiff = $currentTime - $lastActivity;
	    if ($timeDiff > self::INACTIVITY_THRESHOLD) { // more than 1 hour
	        $threatLevel += 1;
	    }

	    // Simple threat level evaluator
	    if ($threatLevel >= self::THREAT_LEVEL_HIGH) {
	        $this->destroy($id);
			$this->close();
			unset($fw->{'COOKIE.'.session_name()});

			// if a custom user function exist
		    if (function_exists('handleHighThreatLevel')) {
		        // call custom user function
		        handleHighThreatLevel($threatLevel, $this->_data);
		    } else {
		        // no custom fonctions ? let's go to the 403
		        $fw->error(403);
		    }

	        return false;
	    } elseif ($threatLevel > 0) {
    		// log lower threat level
    		$logger = new \Log('logs/session_suspects.log');
    		$logger->write("Session suspect : IP={$this->_ip}, Agent={$this->_agent}, ThreatLevel=$threatLevel, Time=$currentTime");

    		// Update session data
	        $data['ip'] = $this->_ip;
	        $data['agent'] = $this->_agent;
	        $this->_cache->set($id.'.@', $data);

		}
	}
	return $data['data'];
}

// anymwhere on the app
function handleHighThreatLevel($threatLevel, $data) {
	// custom user fonction to manage the behavior

	// custom redirect or anything you wan
	header('Location: /error/high-threat');
	exit;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants