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

Bugfix: Infinite recursion sanity checks with more helpful error messages #214

Merged

Conversation

nathanbrauer
Copy link
Contributor

@nathanbrauer nathanbrauer commented Oct 16, 2023

Issue #213

The following snippet in ShareDraftController.php at L161 includes no sanity checks to prevent infinite recursions when it attempts to follow redirects internally via recursions.

private function getRenderedPageByURL(string $url): HTTPResponse
{
// Clean and update live global variables. This is how
// HTTPRequestBuilder::createFromEnvironment works internally.
$variables = HTTPRequestBuilder::cleanEnvironment(Environment::getVariables());
$variables['_SERVER']['REQUEST_URI'] = $url;
$variables['_SERVER']['REQUEST_METHOD'] = 'GET';
$variables['_SERVER']['HTTP_USER_AGENT'] =
isset($variables['_SERVER']['HTTP_USER_AGENT']) &&
$variables['_SERVER']['HTTP_USER_AGENT']
? $variables['_SERVER']['HTTP_USER_AGENT']
: 'CLI';
Environment::setVariables($variables);
// Health-check prior to creating environment
$pageRequest = HTTPRequestBuilder::createFromVariables($variables, @file_get_contents('php://input'));
$response = Director::singleton()->handleRequest($pageRequest);
if ($response->isRedirect()) {
// The redirect will probably be Absolute URL so just want the path
$newUrl = parse_url($response->getHeader('location') ?? '', PHP_URL_PATH);
return $this->getRenderedPageByURL($newUrl);
}
return $response;
}

Infinite recursions, such as those experienced in #213, would previously cause fatal time out or memory limit errors.

This pull request resolves this problem by adding sanity checks, preventing unanticipated internal infinite recursions via "logging" a minimal redirect stack to a private array on ShareDraftController and throws an Exception (with helpful information for developers) if....

  1. ...a URL has already been processed for redirection (infinite recursion detected), OR
  2. ...30 redirects have been logged
    (30 is an arbitrary number that seems to be more than what is typically necessary; this could, in a separate PR, be pulled into a config variable if desired)

Examples of Exception outputs

Infinite recursion detected

Screenshot from 2023-10-14 15-10-05

Max redirect recursions reached

Screenshot from 2023-10-14 15-09-30

Related

Info

  • Edits for maintainers are enabled
  • Set to merge into 2 and can be rebased onto 3 without issue

@muskie9

Adds sanity checks to prevent unanticipated internal infinite recursions (now throws Exceptions with helpful messages; previously timed out or hit memory limits)
@nathanbrauer nathanbrauer force-pushed the bugfix/infinite-recursion-protections branch from 4bb4641 to 88676bf Compare October 16, 2023 01:23
@nathanbrauer
Copy link
Contributor Author

Extracted some duplicate code to satisfy previously failed workflow

src/Controllers/ShareDraftController.php Outdated Show resolved Hide resolved
src/Controllers/ShareDraftController.php Outdated Show resolved Hide resolved
src/Controllers/ShareDraftController.php Outdated Show resolved Hide resolved
src/Controllers/ShareDraftController.php Outdated Show resolved Hide resolved
src/Controllers/ShareDraftController.php Outdated Show resolved Hide resolved
src/Controllers/ShareDraftController.php Outdated Show resolved Hide resolved
@emteknetnz emteknetnz changed the base branch from 2 to 2.9 November 9, 2023 20:41
@emteknetnz emteknetnz changed the base branch from 2.9 to 2 November 9, 2023 20:59
@emteknetnz emteknetnz merged commit a5d74bc into silverstripe:2 Nov 9, 2023
12 checks passed
emteknetnz added a commit to creative-commoners/silverstripe-sharedraftcontent that referenced this pull request Nov 9, 2023
…silverstripe#214)

* Infinite recursion protections
Adds sanity checks to prevent unanticipated internal infinite recursions (now throws Exceptions with helpful messages; previously timed out or hit memory limits)

* Accepting coding standards

Co-authored-by: Steve Boyd <[email protected]>

* MNT Linting

---------

Co-authored-by: Steve Boyd <[email protected]>
@emteknetnz
Copy link
Member

I've merged this, though I noticed that it was targetting the 2 branch instead of the 2.9 branch, sorry I should have picked up as part of peer review

I've created a backport PR to get this into 2.9 where I've cherry-picked the squahed merge commit. Once that is merged it will be automatically tagged as 2.9.4

@nathanbrauer
Copy link
Contributor Author

Thanks for all your work to get this across the finish line, @emteknetnz!

@nathanbrauer nathanbrauer deleted the bugfix/infinite-recursion-protections branch November 10, 2023 00:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants