Skip to content

Commit

Permalink
Show FourOhFourButFound output, if any, not just on 404s but also on …
Browse files Browse the repository at this point in the history
…existing content

This means for example that previously, `/?file=/etc/passwd` didn't trigger the FourOhFourButFound output because `/` is a valid existing URL, but now it will.

It uses $_SERVER because that contains the original requested URL, Nette's Request service has it already sanitized a bit and will not retain new lines for example, which some CVE exploits use. This means I can troll more folks, yay!
  • Loading branch information
spaze committed Jan 15, 2025
1 parent f4f6a43 commit c691c0a
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 25 deletions.
1 change: 1 addition & 0 deletions app/disallowed-calls.neon
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ parameters:
allowIn:
- src/Application/ServerEnv.php
- tests/Application/ServerEnvTest.phpt
- tests/EasterEgg/FourOhFourButFoundTest.phpt
disallowedClasses:
-
class:
Expand Down
27 changes: 9 additions & 18 deletions app/src/EasterEgg/FourOhFourButFound.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@

namespace MichalSpacekCz\EasterEgg;

use MichalSpacekCz\Application\ServerEnv;
use MichalSpacekCz\Http\Robots\Robots;
use MichalSpacekCz\Http\Robots\RobotsRule;
use Nette\Application\Responses\TextResponse;
use Nette\Application\UI\Presenter;
use Nette\Http\IRequest;

readonly class FourOhFourButFound
{
Expand All @@ -18,32 +18,23 @@


public function __construct(
private IRequest $httpRequest,
private readonly Robots $robots,
private Robots $robots,
) {
}


public function sendItMaybe(Presenter $presenter): void
{
$url = $this->httpRequest->getUrl();
$url = ServerEnv::tryGetString('REQUEST_URI');
if ($url === null) {
return;
}
foreach (self::TEMPLATES as $request => $template) {
if (str_contains($url->getPath(), $request)) {
$this->sendIt($presenter, $template);
} else {
$query = $url->getQuery();
if ($query && str_contains(urldecode($query), $request)) {
$this->sendIt($presenter, $template);
}
if (str_contains($url, $request) || str_contains(urldecode($url), $request)) {
$this->robots->setHeader([RobotsRule::NoIndex, RobotsRule::NoFollow]);
$presenter->sendResponse(new TextResponse(file_get_contents($template)));
}
}
}


private function sendIt(Presenter $presenter, string $template): never
{
$this->robots->setHeader([RobotsRule::NoIndex, RobotsRule::NoFollow]);
$presenter->sendResponse(new TextResponse(file_get_contents($template)));
}

}
13 changes: 13 additions & 0 deletions app/src/Www/Presenters/BasePresenter.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use MichalSpacekCz\Application\Locale\LocaleLinkGenerator;
use MichalSpacekCz\Css\CriticalCss;
use MichalSpacekCz\Css\CriticalCssFactory;
use MichalSpacekCz\EasterEgg\FourOhFourButFound;
use MichalSpacekCz\Form\ThemeFormFactory;
use MichalSpacekCz\Form\UiForm;
use MichalSpacekCz\User\Manager;
Expand Down Expand Up @@ -38,6 +39,8 @@ abstract class BasePresenter extends Presenter

private ComponentParameters $componentParameters;

private FourOhFourButFound $fourOhFourButFound;


/**
* @internal
Expand Down Expand Up @@ -93,6 +96,15 @@ public function injectComponentParameters(ComponentParameters $componentParamete
}


/**
* @internal
*/
public function injectFourOhFourButFound(FourOhFourButFound $fourOhFourButFound): void
{
$this->fourOhFourButFound = $fourOhFourButFound;
}


#[Override]
protected function startup(): void
{
Expand All @@ -101,6 +113,7 @@ protected function startup(): void
if ($this->authenticator->isForbidden() && $this->getRequest()?->getMethod() !== Request::FORWARD) {
$this->forward(':Www:Forbidden:', ['message' => 'messages.forbidden.spam']);
}
$this->fourOhFourButFound->sendItMaybe($this);
}


Expand Down
3 changes: 0 additions & 3 deletions app/src/Www/Presenters/ErrorPresenter.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
use MichalSpacekCz\Application\Exceptions\ParameterNotStringException;
use MichalSpacekCz\Application\Locale\LocaleLink;
use MichalSpacekCz\Application\Locale\LocaleLinkGenerator;
use MichalSpacekCz\EasterEgg\FourOhFourButFound;
use MichalSpacekCz\ShouldNotHappenException;
use Nette\Application\BadRequestException;
use Nette\Application\UI\InvalidLinkException;
Expand All @@ -32,7 +31,6 @@ class ErrorPresenter extends BaseErrorPresenter

public function __construct(
private readonly LocaleLinkGenerator $localeLinkGenerator,
private readonly FourOhFourButFound $fourOhFourButFound,
private readonly AppRequest $appRequest,
private readonly Translator $translator,
) {
Expand Down Expand Up @@ -70,7 +68,6 @@ protected function getLocaleLinksGeneratorParams(): array

public function actionDefault(BadRequestException $exception): void
{
$this->fourOhFourButFound->sendItMaybe($this);
$code = (in_array($exception->getCode(), $this->statuses) ? $exception->getCode() : IResponse::S400_BadRequest);
$this->template->errorCode = $code;
$this->template->pageTitle = $this->translator->translate("messages.title.error{$code}");
Expand Down
5 changes: 1 addition & 4 deletions app/tests/EasterEgg/FourOhFourButFoundTest.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@ namespace MichalSpacekCz\EasterEgg;

use MichalSpacekCz\Test\Application\ApplicationPresenter;
use MichalSpacekCz\Test\Application\UiPresenterMock;
use MichalSpacekCz\Test\Http\Request;
use MichalSpacekCz\Test\TestCaseRunner;
use Nette\Application\Responses\TextResponse;
use Nette\Http\UrlScript;
use Tester\Assert;
use Tester\TestCase;

Expand All @@ -22,7 +20,6 @@ class FourOhFourButFoundTest extends TestCase

public function __construct(
private readonly FourOhFourButFound $fourOhFourButFound,
private readonly Request $request,
private readonly ApplicationPresenter $applicationPresenter,
) {
}
Expand Down Expand Up @@ -50,7 +47,7 @@ class FourOhFourButFoundTest extends TestCase
public function testSendItMaybe(string $url, ?string $contains): void
{
$presenter = new UiPresenterMock();
$this->request->setUrl(new UrlScript($url));
$_SERVER['REQUEST_URI'] = $url;
if ($contains === null) {
Assert::false($this->applicationPresenter->expectSendResponse(function () use ($presenter): void {
$this->fourOhFourButFound->sendItMaybe($presenter);
Expand Down

0 comments on commit c691c0a

Please sign in to comment.