8000 [Security] add Request type json check in json_login by lsmith77 · Pull Request #22477 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[Security] add Request type json check in json_login #22477

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

Merged
merged 1 commit into from
Apr 29, 2017

Conversation

lsmith77
Copy link
Contributor
@lsmith77 lsmith77 commented Apr 19, 2017
Q A
Branch? master
Bug fix? no
New feature? yes
BC breaks? no, unreleased feature
Deprecations? no
Tests pass? yes
Fixed tickets
License MIT
Doc PR -

follow up to #22425 to limit the UsernamePasswordJsonAuthenticationListener to only requests with appropriate JSON content type.

I am not entirely happy with this implementation but mostly because Symfony out of the box only provides very limited content type negotiation. I guess anyone that wants to tweak the content negotiation will simply need to ensure the Request::$format is set accordingly before the code is triggered.

@lsmith77 lsmith77 force-pushed the check-request-type-in-json-login branch from 23a3293 to b4d4500 Compare April 19, 2017 20:23
@lsmith77 lsmith77 changed the title add Request type json check in json_login [Security] add Request type json check in json_login Apr 19, 2017
@lsmith77 lsmith77 requested a review from dunglas April 19, 2017 20:24
Copy link
Member
@chalasr chalasr left a comment

Choose a reason for hiding this comment

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

We should add a test for this (the existing ones might fail since we don't use a json request into)

@@ -73,6 +73,9 @@ public function __construct(TokenStorageInterface $tokenStorage, AuthenticationM
public function handle(GetResponseEvent $event)
{
$request = $event->getRequest();
if ('json' !== $request->getRequestFormat() || 'json' !== $request->getContentType()) {
Copy link
Member

Choose a reason for hiding this comment

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

AFAIK the checked content type should be application/json

Copy link
Member

Choose a reason for hiding this comment

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

nevermind, it seems getContentType() does return json

@@ -73,6 +73,9 @@ public function __construct(TokenStorageInterface $tokenStorage, AuthenticationM
public function handle(GetResponseEvent $event)
{
$request = $event->getRequest();
if ('json' !== $request->getRequestFormat() || 'json' !== $request->getContentType()) {
Copy link
Member

Choose a reason for hiding this comment

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

I would use false !== strpos($format, 'json') instead of the strict test to allow to execute the listener for any JSON-based formats including JSON-LD and HAL.

@lsmith77 lsmith77 force-pushed the check-request-type-in-json-login branch 3 times, most recently from 772ef1d to 104cc9c Compare April 20, 2017 06:23
@lsmith77
Copy link
Contributor Author

hmm .. will have to investigate why tests are partially passing with some configurations. any hints welcome.

|| false !== strpos($request->getContentType(), 'json')
) {
return;
}
Copy link
Member
@chalasr chalasr Apr 20, 2017

Choose a reason for hiding this comment

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

I think this should be:

if (false === strpos($request->getRequestFormat(), 'json') && false === strpos($request->getContentType(), 'json')) {
    return;
}

Skipping only if both request format and content type do not contain json. It makes your tests green.
If we want to skip if only one of them does not contain json, you have to set the _format in all the existing tests in addition to the content type (and still change false !== in false ===, actually we are skipping for json requests :))

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah .. logic mistake :)

@lsmith77 lsmith77 force-pushed the check-request-type-in-json-login branch 2 times, most recently from cc5ff7c to 223d133 Compare April 20, 2017 09:42
@stof
Copy link
Member
stof commented Apr 20, 2017

@lsmith77 some jobs are just skipping all tests for PRs (to limit the number of queued jobs due to the activity on the repo), which is why they cannot fail

Copy link
Member
@chalasr chalasr left a comment

Choose a reason for hiding this comment

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

👍

@lsmith77 lsmith77 force-pushed the check-request-type-in-json-login branch from 223d133 to f62c7be Compare April 20, 2017 11:09
@lsmith77
Copy link
Contributor Author

ok .. tests are fixed

@nicolas-grekas nicolas-grekas added this to the 3.3 milestone Apr 20, 2017
@chalasr
Copy link
Member
chalasr commented Apr 20, 2017

For next reviewers, here is the main reason for this PR:

my point above regarding checking the content type is so that one could use form_login and json_login in parallel on the same routes and within the same firewall

@lsmith77 lsmith77 force-pushed the check-request-type-in-json-login branch from f62c7be to 045a36b Compare April 24, 2017 06:23
@lsmith77
Copy link
Contributor Author

rebased on master

@lsmith77
Copy link
Contributor Author

@dunglas ok for you?

@fabpot
Copy link
Member
fabpot commented Apr 29, 2017

Thank you @lsmith77.

@fabpot fabpot merged commit 045a36b into symfony:master Apr 29, 2017
fabpot added a commit that referenced this pull request Apr 29, 2017
…mith77)

This PR was merged into the 3.3-dev branch.

Discussion
----------

[Security] add Request type json check in json_login

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no, unreleased feature
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets |
| License       | MIT
| Doc PR        | -

follow up to #22425 to limit the `UsernamePasswordJsonAuthenticationListener` to only requests with appropriate JSON content type.

I am not entirely happy with this implementation but mostly because Symfony out of the box only provides very limited content type negotiation. I guess anyone that wants to tweak the content negotiation will simply need to ensure the Request::$format is set accordingly before the code is triggered.

Commits
-------

045a36b add Request type json check in json_login
stof added a commit that referenced this pull request Apr 30, 2017
…sent on bad request (ogizanagi)

This PR was merged into the 3.3-dev branch.

Discussion
----------

[Security] json login listener: ensure a json response is sent on bad request

| Q             | A
| ------------- | ---
| Branch?       | master (3.3)
| Bug fix?      | yesish
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | N/A
| License       | MIT
| Doc PR        | N/A

I would have simply recommended to set the proper format when declaring the route:

```yml
# routing.yml
api_login:
    path: /login
    defaults: { _format: json }
```

but, since #22477 has been merged, and considering #22477 (comment):

> my point above regarding checking the content type is so that one could use form_login and json_login in parallel on the same routes and within the same firewall

we may consider setting the request format to json when throwing the `BadRequestHttpException`, so used conjointly with the TwigBundle, the exception is rendered using the `exception.json.twig` template.

ping @lsmith77

(An alternative would be to check the Accept header to set the request format to json if it's the preferred one instead of doing it each time we throw the exception. But Symfony never used such content negotiation AFAIK, and I think it's safe enough to assume someone sending json is expecting json as ouput for exceptions.)

Commits
-------

4427cf9 [Security] json login listener: ensure a json response is sent on bad request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants
0