Skip to content

Commit

Permalink
Merge pull request #60 from boesing/bugfix/invalid-origin-values
Browse files Browse the repository at this point in the history
Handle invalid `Origin` header values in `CorsMiddleware`
  • Loading branch information
Ocramius authored Dec 8, 2023
2 parents 4163161 + b08de20 commit 425b0fd
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 4 deletions.
9 changes: 6 additions & 3 deletions src/Exception/InvalidOriginValueException.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@

final class InvalidOriginValueException extends RuntimeException implements ExceptionInterface
{
private function __construct(string $message, ?Throwable $previous = null)
{
private function __construct(
string $message,
public readonly string $origin,
?Throwable $previous = null
) {
parent::__construct($message, 0, $previous);
}

public static function fromThrowable(string $origin, Throwable $throwable): self
{
return new self(sprintf('Provided Origin "%s" is invalid.', $origin), $throwable);
return new self(sprintf('Provided Origin "%s" is invalid.', $origin), $origin, $throwable);
}
}
10 changes: 9 additions & 1 deletion src/Middleware/CorsMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Mezzio\Cors\Middleware;

use Mezzio\Cors\Exception\InvalidOriginValueException;
use Mezzio\Cors\Middleware\Exception\InvalidConfigurationException;
use Mezzio\Cors\Service\ConfigurationLocatorInterface;
use Mezzio\Cors\Service\CorsInterface;
Expand Down Expand Up @@ -46,11 +47,18 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
throw InvalidConfigurationException::fromInvalidPipelineConfiguration();
}

if (! $this->cors->isCorsRequest($request)) {
try {
$isCorsRequest = $this->cors->isCorsRequest($request);
} catch (InvalidOriginValueException $exception) {
return $this->responseFactory->unauthorized($exception->origin);
}

if (! $isCorsRequest) {
return $this->vary($handler->handle($request));
}

$metadata = $this->cors->metadata($request);

if ($this->cors->isPreflightRequest($request)) {
return $this->preflight($metadata) ?? $handler->handle($request);
}
Expand Down
33 changes: 33 additions & 0 deletions test/Middleware/CorsMiddlewareTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
namespace Mezzio\CorsTest\Middleware;

use Fig\Http\Message\RequestMethodInterface;
use InvalidArgumentException;
use Mezzio\Cors\Configuration\ConfigurationInterface;
use Mezzio\Cors\Configuration\RouteConfigurationInterface;
use Mezzio\Cors\Exception\InvalidOriginValueException;
use Mezzio\Cors\Middleware\CorsMiddleware;
use Mezzio\Cors\Middleware\Exception\InvalidConfigurationException;
use Mezzio\Cors\Service\ConfigurationLocatorInterface;
Expand Down Expand Up @@ -486,4 +488,35 @@ public function testWillDelegateUnknownRouteForRequestToRequestHandler(): void

$this->middleware->process($request, $handler);
}

public function testWillHandleRequestsWithInvalidOriginAsUnauthorized(): void
{
$request = $this->createMock(ServerRequestInterface::class);
$request
->method('getHeaderLine')
->willReturnMap([['Origin', 'foobarbaz://example.org']]);

$this->cors
->expects(self::once())
->method('isCorsRequest')
->with($request)
->willThrowException(
InvalidOriginValueException::fromThrowable(
'foobarbaz://example.org',
new InvalidArgumentException('Some exception from PSR-17 factory.')
),
);

$handler = $this->createMock(RequestHandlerInterface::class);
$handler
->expects(self::never())
->method('handle');

$this->responseFactoryInterface
->expects(self::once())
->method('unauthorized')
->with('foobarbaz://example.org');

$this->middleware->process($request, $handler);
}
}

0 comments on commit 425b0fd

Please sign in to comment.