Skip to content

Commit 425b0fd

Browse files
authored
Merge pull request #60 from boesing/bugfix/invalid-origin-values
Handle invalid `Origin` header values in `CorsMiddleware`
2 parents 4163161 + b08de20 commit 425b0fd

File tree

3 files changed

+48
-4
lines changed

3 files changed

+48
-4
lines changed

src/Exception/InvalidOriginValueException.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,16 @@
1111

1212
final class InvalidOriginValueException extends RuntimeException implements ExceptionInterface
1313
{
14-
private function __construct(string $message, ?Throwable $previous = null)
15-
{
14+
private function __construct(
15+
string $message,
16+
public readonly string $origin,
17+
?Throwable $previous = null
18+
) {
1619
parent::__construct($message, 0, $previous);
1720
}
1821

1922
public static function fromThrowable(string $origin, Throwable $throwable): self
2023
{
21-
return new self(sprintf('Provided Origin "%s" is invalid.', $origin), $throwable);
24+
return new self(sprintf('Provided Origin "%s" is invalid.', $origin), $origin, $throwable);
2225
}
2326
}

src/Middleware/CorsMiddleware.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Mezzio\Cors\Middleware;
66

7+
use Mezzio\Cors\Exception\InvalidOriginValueException;
78
use Mezzio\Cors\Middleware\Exception\InvalidConfigurationException;
89
use Mezzio\Cors\Service\ConfigurationLocatorInterface;
910
use Mezzio\Cors\Service\CorsInterface;
@@ -46,11 +47,18 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
4647
throw InvalidConfigurationException::fromInvalidPipelineConfiguration();
4748
}
4849

49-
if (! $this->cors->isCorsRequest($request)) {
50+
try {
51+
$isCorsRequest = $this->cors->isCorsRequest($request);
52+
} catch (InvalidOriginValueException $exception) {
53+
return $this->responseFactory->unauthorized($exception->origin);
54+
}
55+
56+
if (! $isCorsRequest) {
5057
return $this->vary($handler->handle($request));
5158
}
5259

5360
$metadata = $this->cors->metadata($request);
61+
5462
if ($this->cors->isPreflightRequest($request)) {
5563
return $this->preflight($metadata) ?? $handler->handle($request);
5664
}

test/Middleware/CorsMiddlewareTest.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
namespace Mezzio\CorsTest\Middleware;
66

77
use Fig\Http\Message\RequestMethodInterface;
8+
use InvalidArgumentException;
89
use Mezzio\Cors\Configuration\ConfigurationInterface;
910
use Mezzio\Cors\Configuration\RouteConfigurationInterface;
11+
use Mezzio\Cors\Exception\InvalidOriginValueException;
1012
use Mezzio\Cors\Middleware\CorsMiddleware;
1113
use Mezzio\Cors\Middleware\Exception\InvalidConfigurationException;
1214
use Mezzio\Cors\Service\ConfigurationLocatorInterface;
@@ -486,4 +488,35 @@ public function testWillDelegateUnknownRouteForRequestToRequestHandler(): void
486488

487489
$this->middleware->process($request, $handler);
488490
}
491+
492+
public function testWillHandleRequestsWithInvalidOriginAsUnauthorized(): void
493+
{
494+
$request = $this->createMock(ServerRequestInterface::class);
495+
$request
496+
->method('getHeaderLine')
497+
->willReturnMap([['Origin', 'foobarbaz://example.org']]);
498+
499+
$this->cors
500+
->expects(self::once())
501+
->method('isCorsRequest')
502+
->with($request)
503+
->willThrowException(
504+
InvalidOriginValueException::fromThrowable(
505+
'foobarbaz://example.org',
506+
new InvalidArgumentException('Some exception from PSR-17 factory.')
507+
),
508+
);
509+
510+
$handler = $this->createMock(RequestHandlerInterface::class);
511+
$handler
512+
->expects(self::never())
513+
->method('handle');
514+
515+
$this->responseFactoryInterface
516+
->expects(self::once())
517+
->method('unauthorized')
518+
->with('foobarbaz://example.org');
519+
520+
$this->middleware->process($request, $handler);
521+
}
489522
}

0 commit comments

Comments
 (0)