-
-
Notifications
You must be signed in to change notification settings - Fork 432
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
Validation is processed before guarding #1780
Comments
Hi I have the following case too:
The input has a @validator directive and it always goes first even if I put it after @create. That seems wrong since I want to authenticate my user before validation is attempted. |
@spawnia I've managed to put something together that does the trick, but I'm totally not sure if this the way to go. Just thinking out loud. New directive<?php
namespace Nuwave\Lighthouse\Auth;
use Closure;
use GraphQL\Language\AST\DirectiveNode;
use Nuwave\Lighthouse\Schema\Directives\GuardDirective;
use Nuwave\Lighthouse\Schema\Values\FieldValue;
class AuthDirective extends GuardDirective
{
public function handleField(FieldValue $fieldValue, Closure $next): FieldValue
{
if ($this->fieldHasGuardDirective($fieldValue)) {
return parent::handleField($fieldValue, $next);
}
return $next($fieldValue);
}
protected function fieldHasGuardDirective(FieldValue $fieldValue): bool
{
/** @var DirectiveNode $directive */
foreach ($fieldValue->getField()->directives as $directive) {
if ($directive->name->value === 'guard') {
$this->directiveNode = $directive;
return true;
}
}
return false;
}
} Config'field_middleware' => [
\Nuwave\Lighthouse\Schema\Directives\TrimDirective::class,
\Nuwave\Lighthouse\Schema\Directives\SanitizeDirective::class,
\Nuwave\Lighthouse\Auth\AuthDirective::class, // <--- before validation
\Nuwave\Lighthouse\Validation\ValidateDirective::class,
\Nuwave\Lighthouse\Schema\Directives\TransformArgsDirective::class,
\Nuwave\Lighthouse\Schema\Directives\SpreadDirective::class,
\Nuwave\Lighthouse\Schema\Directives\RenameArgsDirective::class,
], |
@wimski that would run I think we should enhance the field middleware configuration to allow defining a default order for field middleware. That would allow interleaving optional field middleware directives such as |
This is actually a security risk in many situations, exposing validation before authentication allows an attacker to gain information from the system e.g.
Allows an attacker to discover valid accounts without being authed. |
I've come up with a workaround that uses a custom GraphQLContext: The GraphQLContext object is referenced and can be accessed through all middleware and directives in the lighthouse pipeline. Schematically:
Note that you have to update Here's a link to a gist with a working implementation. N.B.: I was hesitant to post this as it has at least one obvious flaw (having to track the project updates in order to reflect the changes in the custom files). But I thought it could show how the current pipeline can't be used to solve the issue and has to be rethought. Also: works :) |
I believe this issue has to be clearly stated somewhere in the docs and let people decide whether to use the library or not. Its a serious issue and exposes a lot of security vulnerabilities. |
I disagree @nyelnizy True that if you choose to implement like this - well that's at your own risk. But normally there's a lot that goes on in validation (Also be consistent with Laravel Validation). With this that means even little things like validating a user changing their email is not possible except in the resolver. |
@wimski how is this respected in lighthouse 6? |
@gwachhamit I have no idea. This was just an idea that I tested out, but never actually implemented in any real project. So your guess is as good as mine. I'm still hoping on a fundamental solution within the package, because this is not something I want want to attach myself on a project basis. |
This whole issue can be solved if we can modify the |
Describe the bug
When creating a mutation with both the
@guard
directive as well as the@validator
directive on the input, the validation is processed before the guarding.Expected behavior/Solution
I expect the guarding to be processed before the validation, because if someone is not authenticated, there's is no point in further handling the request with input validation.
Steps to reproduce
This test will fail, because the
name
attribute is not long enough. It should pass, because a user being unauthenticated should take precedence over validation.Lighthouse Version
5.3.0
The text was updated successfully, but these errors were encountered: