-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
[3.x] Fix guarded to return always true #2082
Conversation
…'t initialize $this->grammar
…ally have columns
Codecov Report
@@ Coverage Diff @@
## master #2082 +/- ##
=========================================
Coverage 86.88% 86.88%
Complexity 671 671
=========================================
Files 31 31
Lines 1556 1556
=========================================
Hits 1352 1352
Misses 204 204
Continue to review full report at Codecov.
|
tests/ModelTest.php
Outdated
{ | ||
Guarded::create(['var' => 'val']); | ||
|
||
$this->assertEquals(1, Guarded::count()); |
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.
It's not related test case, i think that we should test that model Guarded doesn't set fields in guarded attribute of Model
$model = Guarded::create(['var' => 'val', 'foobar' => 'bar']);
$this->assertFalse(isset($model->foobar));
See tests in laravel
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.
The error this PR refers to, occurs when Laravel checks using an isGuardedColumn
method.
This method however doesn't perform the actual guard checks, it checks if "the given column is a valid, guardable column" (whatever that may mean), which means returning true on this makes sense in a MongoDB scope, given the free nature of documents.
It's easy to add the test, but it's not strictly neccessary as the isGuarded
method checks for this (code from Laravel 7.25.0):
return $this->getGuarded() == ['*'] ||
! empty(preg_grep('/^'.preg_quote($key).'$/i', $this->getGuarded())) ||
! $this->isGuardableColumn($key);
Edit: I looked at the exploit, but since it specifically mentions foo->bar
assignments, maybe add a test for json statements too? Adding 'foobar->foo' => true
and ensure it's not set?
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.
Change test case, please, we can show that test will be broken if laravel changes behavior with guarded fields
@fish3046 I've talked few days ago with @Smolevich about this:
Thanks! |
Hopefully these test and readme changes address the concerns. Thanks for reviewing this so quickly. |
@fish3046 thanks for contributing! |
[3.x] Fix guarded to return always true
An update to Laravel has caused a breakdown when using guarded models. See this for more info:
https://blog.laravel.com/security-release-laravel-61834-7232
laravel/framework#33777
One error this caused is:
Call to a member function compileColumnListing() on null
This is because
\Illuminate\Database\Schema\Builder::__construct()
now creates a grammar object, and our overloaded constructor does not. I've removed our constructor to fall back to the parent's, as we aren't doing anything special in ours.The next error is
BadMethodCallException : Method Jenssegers\Mongodb\Schema\Grammar::compileColumnListing does not exist
This is because the new default behavior on guarded models is to query the schema for a column listing to ensure you are guarding actual fields. Because we are a document model, I have overloaded
Model::isGuardableColumn()
to return true. This aides in preventing all manner of checks and complications that don't really apply to Mongo models.fixes #2078