Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions src/http/StatelessApplication.php
Original file line number Diff line number Diff line change
Expand Up @@ -420,17 +420,13 @@
$this->response->cookieValidationKey = $this->request->cookieValidationKey;
$this->response->enableCookieValidation = $this->request->enableCookieValidation;

// reset the session to ensure a clean state
$this->session->close();
// if a session cookie is present, set the session ID accordingly
$sessionId = $this->request->getCookies()->get($this->session->getName())->value ?? '';
$this->session->setId($sessionId);

Comment on lines +423 to 426
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Fix null dereference and avoid Yii cookie-validation mismatch when reading session ID

  • ->get(...)->value ?? '' will fatal when the cookie is absent because ->value is accessed on null.
  • Reading from $this->request->getCookies() depends on Yii cookie validation; the PHP session cookie (e.g., PHPSESSID) is typically not signed and may be filtered out when validation is enabled. Use PSR-7 $request->getCookieParams() instead and only set the ID when present and non-empty.

Apply this diff:

-        // if a session cookie is present, set the session ID accordingly
-        $sessionId = $this->request->getCookies()->get($this->session->getName())->value ?? '';
-        $this->session->setId($sessionId);
+        // if a session cookie is present, set the session ID accordingly
+        $sessionName = $this->session->getName();
+        $sessionId = $request->getCookieParams()[$sessionName] ?? null;
+        if (is_string($sessionId) && $sessionId !== '') {
+            $this->session->setId($sessionId);
+        }

Optionally, add a lightweight unit test to cover:

  • no session cookie present → setId() is not called
  • valid session cookie present → setId() receives that value
  • empty session cookie value → setId() is not called

I can draft the tests if helpful.


🏁 Script executed:

#!/bin/bash
# Locate the StatelessApplication.php file
file=$(rg -l "class StatelessApplication" --glob "*.php")
echo "StatelessApplication file: $file"

# Show lines around the snippet (lines ~423)
sed -n '400,460p' "$file"

# Show occurrences of getCookies in the file
rg -n "getCookies" -C2 "$file"

# Search for any use of getCookieParams in the repo
rg -n "getCookieParams" -C3 --glob "*.php"

Length of output: 3942


🏁 Script executed:

#!/bin/bash
# Display the session‐cookie logic in StatelessApplication
sed -n '400,460p' src/http/StatelessApplication.php

# Check if getCookieParams is already used in this file
rg -n 'getCookieParams' -C3 src/http/StatelessApplication.php

Length of output: 2383


Prevent null dereference and bypass Yii cookie validation for session ID

In src/http/StatelessApplication.php inside the reset() method (around line 423), the current code…

// if a session cookie is present, set the session ID accordingly
$sessionId = $this->request->getCookies()->get($this->session->getName())->value ?? '';
$this->session->setId($sessionId);

…can

  • fatally dereference ->value when the named cookie is missing (it returns null),
  • and silently overwrite the session ID with an empty string even if no cookie was provided,
  • while also relying on Yii’s cookie-validation (which drops unsigned PHPSESSID cookies).

Replace with PSR-7’s raw cookie params and guard both null and empty values:

-        // if a session cookie is present, set the session ID accordingly
-        $sessionId = $this->request->getCookies()->get($this->session->getName())->value ?? '';
-        $this->session->setId($sessionId);
+        // if a session cookie is present, set the session ID accordingly
+        $sessionName = $this->session->getName();
+        $sessionId   = $request->getCookieParams()[$sessionName] ?? null;
+        if (is_string($sessionId) && $sessionId !== '') {
+            $this->session->setId($sessionId);
+        }

To fully cover this behavior, add a small unit test for reset():

  • no session cookie → session->setId() is never invoked
  • valid non-empty cookie → session->setId() is called with that value
  • cookie present but empty → session->setId() is not invoked
🤖 Prompt for AI Agents
In src/http/StatelessApplication.php around lines 423-426, the code currently
dereferences ->value on a potentially null cookie and unconditionally calls
$this->session->setId('') when no cookie exists; change it to read the raw PSR-7
cookie params (e.g. $this->request->getCookieParams()), check for the cookie
name existence and that its value is non-null and non-empty before calling
$this->session->setId($value) so you never dereference null or overwrite the
session with an empty string; additionally add unit tests for reset(): (1) no
session cookie => assert setId() is never called, (2) valid non-empty cookie =>
assert setId() called with that value, (3) cookie present but empty => assert
setId() is not called.

// start the session with the correct 'ID'
$this->session->open();

$this->bootstrap();

$this->session->close();

Check warning on line 429 in src/http/StatelessApplication.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ $sessionId = $this->request->getCookies()->get($this->session->getName())->value ?? ''; $this->session->setId($sessionId); $this->bootstrap(); - $this->session->close(); + } /** * Finalizes the application lifecycle and converts the Yii2 Response to a PSR-7 ResponseInterface.

Check warning on line 429 in src/http/StatelessApplication.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ $sessionId = $this->request->getCookies()->get($this->session->getName())->value ?? ''; $this->session->setId($sessionId); $this->bootstrap(); - $this->session->close(); + } /** * Finalizes the application lifecycle and converts the Yii2 Response to a PSR-7 ResponseInterface.
}

/**
Expand All @@ -452,10 +448,10 @@
{
$this->cleanupEvents();

UploadedFile::reset();

Check warning on line 451 in src/http/StatelessApplication.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ protected function terminate(Response $response): ResponseInterface { $this->cleanupEvents(); - UploadedFile::reset(); + if ($this->flushLogger) { $this->getLog()->getLogger()->flush(true); }

Check warning on line 451 in src/http/StatelessApplication.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ protected function terminate(Response $response): ResponseInterface { $this->cleanupEvents(); - UploadedFile::reset(); + if ($this->flushLogger) { $this->getLog()->getLogger()->flush(true); }

if ($this->flushLogger) {
$this->getLog()->getLogger()->flush(true);

Check warning on line 454 in src/http/StatelessApplication.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ $this->cleanupEvents(); UploadedFile::reset(); if ($this->flushLogger) { - $this->getLog()->getLogger()->flush(true); + } return $response->getPsr7Response(); }

Check warning on line 454 in src/http/StatelessApplication.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "TrueValue": @@ @@ $this->cleanupEvents(); UploadedFile::reset(); if ($this->flushLogger) { - $this->getLog()->getLogger()->flush(true); + $this->getLog()->getLogger()->flush(false); } return $response->getPsr7Response(); }

Check warning on line 454 in src/http/StatelessApplication.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ $this->cleanupEvents(); UploadedFile::reset(); if ($this->flushLogger) { - $this->getLog()->getLogger()->flush(true); + } return $response->getPsr7Response(); }

Check warning on line 454 in src/http/StatelessApplication.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "TrueValue": @@ @@ $this->cleanupEvents(); UploadedFile::reset(); if ($this->flushLogger) { - $this->getLog()->getLogger()->flush(true); + $this->getLog()->getLogger()->flush(false); } return $response->getPsr7Response(); }
}

return $response->getPsr7Response();
Expand All @@ -477,17 +473,17 @@
*/
private function cleanupEvents(): void
{
Event::off('*', '*', $this->eventHandler);

Check warning on line 476 in src/http/StatelessApplication.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ */ private function cleanupEvents(): void { - Event::off('*', '*', $this->eventHandler); + foreach (array_reverse($this->registeredEvents) as $event) { if ($event->sender !== null && method_exists($event->sender, 'off')) { $event->sender->off($event->name);

Check warning on line 476 in src/http/StatelessApplication.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ */ private function cleanupEvents(): void { - Event::off('*', '*', $this->eventHandler); + foreach (array_reverse($this->registeredEvents) as $event) { if ($event->sender !== null && method_exists($event->sender, 'off')) { $event->sender->off($event->name);

foreach (array_reverse($this->registeredEvents) as $event) {

Check warning on line 478 in src/http/StatelessApplication.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "UnwrapArrayReverse": @@ @@ private function cleanupEvents(): void { Event::off('*', '*', $this->eventHandler); - foreach (array_reverse($this->registeredEvents) as $event) { + foreach ($this->registeredEvents as $event) { if ($event->sender !== null && method_exists($event->sender, 'off')) { $event->sender->off($event->name); }

Check warning on line 478 in src/http/StatelessApplication.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "UnwrapArrayReverse": @@ @@ private function cleanupEvents(): void { Event::off('*', '*', $this->eventHandler); - foreach (array_reverse($this->registeredEvents) as $event) { + foreach ($this->registeredEvents as $event) { if ($event->sender !== null && method_exists($event->sender, 'off')) { $event->sender->off($event->name); }
if ($event->sender !== null && method_exists($event->sender, 'off')) {
$event->sender->off($event->name);

Check warning on line 480 in src/http/StatelessApplication.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ Event::off('*', '*', $this->eventHandler); foreach (array_reverse($this->registeredEvents) as $event) { if ($event->sender !== null && method_exists($event->sender, 'off')) { - $event->sender->off($event->name); + } } $this->registeredEvents = [];

Check warning on line 480 in src/http/StatelessApplication.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ Event::off('*', '*', $this->eventHandler); foreach (array_reverse($this->registeredEvents) as $event) { if ($event->sender !== null && method_exists($event->sender, 'off')) { - $event->sender->off($event->name); + } } $this->registeredEvents = [];
}
}

$this->registeredEvents = [];

Event::offAll();

Check warning on line 486 in src/http/StatelessApplication.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ } } $this->registeredEvents = []; - Event::offAll(); + } /** * Handles application errors and returns a Yii2 Response instance.

Check warning on line 486 in src/http/StatelessApplication.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ } } $this->registeredEvents = []; - Event::offAll(); + } /** * Handles application errors and returns a Yii2 Response instance.
}

/**
Expand All @@ -507,7 +503,7 @@
{
$response = $this->errorHandler->handleException($exception);

$this->trigger(self::EVENT_AFTER_REQUEST);

Check warning on line 506 in src/http/StatelessApplication.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ private function handleError(Throwable $exception): Response { $response = $this->errorHandler->handleException($exception); - $this->trigger(self::EVENT_AFTER_REQUEST); + $this->state = self::STATE_END; return $response; }

Check warning on line 506 in src/http/StatelessApplication.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ private function handleError(Throwable $exception): Response { $response = $this->errorHandler->handleException($exception); - $this->trigger(self::EVENT_AFTER_REQUEST); + $this->state = self::STATE_END; return $response; }

$this->state = self::STATE_END;

Expand Down Expand Up @@ -542,6 +538,6 @@
*/
private function startEventTracking(): void
{
Event::on('*', '*', $this->eventHandler);

Check warning on line 541 in src/http/StatelessApplication.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ */ private function startEventTracking(): void { - Event::on('*', '*', $this->eventHandler); + } }

Check warning on line 541 in src/http/StatelessApplication.php

View workflow job for this annotation

GitHub Actions / mutation / PHP 8.3-ubuntu-latest

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ */ private function startEventTracking(): void { - Event::on('*', '*', $this->eventHandler); + } }
}
}
Loading