-
Notifications
You must be signed in to change notification settings - Fork 11.1k
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
[5.8] Handle SuspiciousOperationException in router #28866
Conversation
Would it be possible to add the |
Sure, that would prevent it from showing up in the error reporting, but still returns a 500 HTTP error. We believe the 404 HTTP code is more correct, as the request is not found rather than an unexpected server error. We use |
I see this PR fails some tests because this exception was first added by Symfony on 2 April. I wasn't aware of this when writing the test. Source: symfony/http-foundation@d325ae5#diff-7edb274bc39ed8c493badba7dd278826 |
try { | ||
$routes = $this->get($request->getMethod()); | ||
} catch (SuspiciousOperationException $e) { | ||
throw new NotFoundHttpException(null, $e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we forward e->code too, and also set some kind of exception message?
@SjorsO, I believe, I misunderstood your answer at first sight. You're probably right it is better to handle the exception in the internal exception handler rather than in the router itself. What are your thoughts regarding the 500 code vs 404 code? Until the recent change from Symfony the error code would have been 404. Perhaps that is an argument to continue using 404? |
@GrahamCampbell, I followed @SjorsO suggestion and moved the check to the internal exception handler. This ensure that suspicious operations is handled with HTTP 404 as of before April 2, but allows the developer to change to his desires by overriding the exception handler. Do you like this approach better as well? |
@@ -196,7 +198,7 @@ public function render($request, Exception $e) | |||
*/ | |||
protected function prepareException(Exception $e) | |||
{ | |||
if ($e instanceof ModelNotFoundException) { | |||
if ($e instanceof ModelNotFoundException || $e instanceof SuspiciousOperationException) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should not propagate the exception message from SuspiciousOperationException
to NotFoundHttpException
since we don't want to show it to users.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless, we do? Is the message you used in the tests actually realistic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we do. The 404 response was returned until the change was made by Symfony in April. The current 500 seems like an unhandled error. We see these attempts quite often. I believe attackers tries to scan for vulnerabilities in routing functionality (with no success in this case).
I found the same error reported here: octobercms/october#4359
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, in which case we don't want to pass along the real exception message. Just having it available as the previous exception is enough. It is often the case that people will show the exception message of httpnotfoundexception to users, so we don't want to show anything that is not meant for users.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I got your first reply wrong. I didn't thought of users showing the actual exception message, so you're probably right that we shouldn't pass the message a long.
I'll put this in a separate statement below the others with a null
message in the NotFoundHttpException
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated this PR to prevent propagating the exception message.
Is it true that we want to bake the 404 response into the framework? You already have control over the response via the render method of the exception handler and can easily return a 404 there. Might some applications not want to pay careful attention to these types of requests or possibly ban IP addresses? |
@taylorotwell that's a really good point! Having the option to react to these suspicious operations seems reasonable, and you're right that the developer can easily adjust the exception handler to return a 404 response like we did. |
I'm in favor of the current implementation of this PR. I think this exception can be ignored by the framework by default. In many of my projects I get either slack or email notifications when errors happen. I'm not a fan of having to add code to each project to prevent being notified about this harmless exception. |
@SjorsO the notifications was the same reason for me to open a PR to prevent coping the error handling to others projects. If someone likes to ban IP addresses as suggested by @taylorotwell, this can be done by overriding the exception handler. The exception isn't harmful, but the default server error might indicate to an attacker, something isn't fully handled. A default 404 response would perhaps be a better choice. Another consideration is the 400 response indicating a bad request which is just the case here. But Laravel doesn't come with a default 400 error view. However, no reel user should ever see this error as the application should never trigger the exception - only suspicious users. |
Some vulnerability scanners manipulate HTTP headers sent to the server. Symfony checks for suspicious operations with the
X-Http-Method-Override
andX-Forwarded-For
headers, and throws an exception if the value seems invalid.I would expect Laravel to handle these requests as not found, but instead the server responds with a server error.
This PR catch the
SuspiciousOperationException
thrown by Symfony and throws aNotFoundHttpException
instead.This prevents our error reporting tools from keep tracking this "expected" error.
It seems
X-Forwarded-Host
isn't affected in the Laravel router, but I would expect it to be based on the source code. Perhaps my test cases just didn't trigger the exception.