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

Handle unauthorized errors plus return safe codes #472

Merged
merged 8 commits into from
Oct 21, 2023

Conversation

Cruikshanks
Copy link
Member

https://eaflood.atlassian.net/browse/WATER-4085
https://eaflood.atlassian.net/browse/WATER-4155

The final step of our pass-through authentication story is dealing with unauthorized requests. This is where Hapi will compare the scope defined in the credentials our AuthPlugin sets to what is in the route config. If they don't match Hapi will through an error with a 403 Forbidden code.

When this happens our ErrorsPlugin will pick up the response and using ErrorPagesService determine if it should be redirected to an error page. Before this change, our logic would have deduced a 500 Internal Server Error and show the page for that.

Clearly, that's wrong but the solution is a little more complex. If you assume we don't render links to things a user cannot access, the request must have been manufactured i.e. directly entered into the browser. If we respond with a 403 and a nice 'You are not authorised' page we would be confirming the thing someone is trying to access exists, they just don't have the authority to. Similar to handling user enumeration attacks we don't want to do that. Instead, it is recommended to return a 404.

So, we need to amend our error handling logic to check for 403 errors but ensure we respond with 404 instead.

Finally, whilst we are messing with the logic, we will also deal with the fact that returning a 500 means the user never sees our error page. This is because the service is behind a F5 Silverline Managed Web Application Firewall (WAF) which blocks 5xx responses and returns its own error page. (It does this to prevent apps from leaking info because of unhandled errors.)

@Cruikshanks Cruikshanks added the enhancement New feature or request label Oct 19, 2023
@Cruikshanks Cruikshanks self-assigned this Oct 19, 2023
https://eaflood.atlassian.net/browse/WATER-4085
https://eaflood.atlassian.net/browse/WATER-4155

The final step of our pass through authentication story is dealing with unauthorized requests. This is where Hapi will compare the scope defined in the credentials our `AuthPlugin` sets to what is in the route config. If they don't match Hapi will through an error with a [403 Forbidden](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403) code.

When this happens our `ErrorsPlugin` will pick up the response and using `ErrorPagesService` determine if it should be redirected to an error page. Prior to this change our logic would have deduced its a [500 Internal Server Error](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500) and show the page for that.

Clearly that's wrong but the solution is a little more complex. If you assume we don't render links to things a user cannot access, then the request must have been manufactured i.e. directly entered into the browser. If we respond with a 403 and a nice 'You are not authorised' page we would be confirming the thing someone is trying to access exists, they just don't have authority too. Similar, to handling [user enumeration attacks](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/03-Identity_Management_Testing/04-Testing_for_Account_Enumeration_and_Guessable_User_Account) we don't want to do that. Instead, it is [recommended to return a 404](https://www.rfc-editor.org/rfc/rfc9110.html#name-403-forbidden).

So, we need to amend our error handling logic to check for `403` errors but ensure we respond with a `404` instead.

Finally, whilst we are messing with the logic we are also going to deal with the fact returning a `500` means the user never sees our error page. This is because the service is behind a [F5 Silverline Managed Web Application Firewall (WAF)](https://aws.amazon.com/marketplace/pp/prodview-7ge77z55kayes) which blocks `5xx` responses and returns its own error page. (It does this to prevent apps leaking info because of unhandled errors.)
These are the changes we thought would get the tests passing but they don't! :-)

The reason is we'd like to log that an unauthorised request has been made, but ensure we return `404` as the response code. But we've overlooked we determine what status code to send back first, then whether to log anything based on that calculated code.

So, we're going to need to rethink things to achieve all the things we want.
So, all fixed and we are doing what we wanted when a 403 is raised

- always log 'Not authorised'
- return 404 if we are going to render a page
- return 403 if this was an API (internal service) request

We did get ahead of ourselves though and have now broken the tests for `5xx` errors. So, next we'll fix that.
Just removing some of the inconsistencies between the tests.
Again we update our tests to reflect the outcome we want. Realised there was little point on creating routes with handlers that generate a scenario, if we then stub `ErrorPagesService` to return a specific result.

What `ErrorPagesService` is doing is very light weight. So, in this case we're happy to remove the stubbing altogether and let the scenarios (route setup in each test) dictate what the plugin needs to handle.
@Cruikshanks Cruikshanks force-pushed the handle-unauthorized-error-responses branch from 29631f0 to 3e38313 Compare October 19, 2023 17:22
@Cruikshanks Cruikshanks marked this pull request as ready for review October 19, 2023 17:45
Copy link
Contributor

@Jozzey Jozzey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test/plugins/error-pages.plugin.test.js Show resolved Hide resolved
@Cruikshanks Cruikshanks merged commit 0c728dd into main Oct 21, 2023
4 checks passed
@Cruikshanks Cruikshanks deleted the handle-unauthorized-error-responses branch October 21, 2023 10:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants