-
Notifications
You must be signed in to change notification settings - Fork 11k
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
[6.x] Limit expected bindings #35865
Conversation
// $builder = $this->getBuilder(); | ||
// $builder->select('*')->from('users')->where('id', '<>', [12, 30]); | ||
// $this->assertSame('select * from "users" where "id" <> ?', $builder->toSql()); | ||
// $this->assertEquals([0 => 12, 1 => 30], $builder->getBindings()); |
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.
Was this intentional? (To clarify I'm talking about the ^^ above ^^ commented out tests)
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.
Yes. This test checks something that is a security vulnerability works.
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.
But it's commented out... 🤷🏻♂️
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.
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.
@u01jmg3 As far as I can tell, the whereIn()
-function should be used when querying if a value is in an array:
Since devs may encounter situations where they don't know if the argument is a string or an array, it is convenient to be able to use where()
with an array.
But apparently this convenience function can cause unexpected behavior which can be exploited: https://blog.laravel.com/security-laravel-62011-7302-8221-released
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.
How exactly would such behaviour be exploitable? In the worst case, it should throw an error, shouldn't it?
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.
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.
@taylorotwell @driesvints @GrahamCampbell @KaneCohen @jaylinski @genesiscz
Do you really think that the following patch fixes the vulnerability? I don't think so.
$value = is_array($value) ? head($value) : $value;
According to Laravel Security Advisory - January 13 2021 | Kane Cohen, the following exploitation should work.
// HTTP Request Query: https://laravel.com/users?id[]=1&id[]=1
$id = Request::input('id');
User::where('id', $id)->where('is_admin', 0)->first();
// This could lead to a query where "is_admin" column is set to 1.
After the patch, attackers can also do like this:
// HTTP Request Query: https://laravel.com/users?id[0][]=1&id[0][]=1
$id = Request::input('id');
User::where('id', $id)->where('is_admin', 0)->first();
// This could lead to a query where "is_admin" column is set to 1.
Since PHP input arrays can be nested multiple times, this is not a fundamental fix.
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.
This should be a validation this that you should do before, as it is a standard to always validate your data before using them , and Laravel Validation rules can validate values to check it is a string or array or boolean and can also do casts, but more importantly it can know when an array is inserted instead of a string for example. so this should be a valid Fix for this error.
Limit the bindings to the number of bindings we actually expect for the given query.