Is this change in update_record safe?

Is this change in update_record safe?

by John Papaioannou -
Number of replies: 18
Researching bug 2776, I found that a problem existed in update_record. Here's a diff:
*** 1209,1215 ****

foreach ($ddd as $key => $value) {
$count++;
! $update .= $key .' = \''. $value .'\'';
if ($count < $numddd) {
$update .= ', ';
}
--- 1209,1215 ----

foreach ($ddd as $key => $value) {
$count++;
! $update .= $key .' = '. $db->qstr($value);
if ($count < $numddd) {
$update .= ', ';
}

Obviously, if $value contains an apostrophe then the query is going to fail. If it contains a slash, then the value will probably change without anyone noticing.

I changed it to call ADODB's qstr() and removed the enclosing apostrophes (qstr automatically adds them).

The reason I 'm mentioning this is that it's an ultra far-reaching change, and obviously all code that uses it cannot be tested. It looks completely safe to me, but just in case I 'm overlooking something...

Average of ratings: -
In reply to John Papaioannou

Re: Is this change in update_record safe?

by Martin Dougiamas -
Picture of Core developers Picture of Documentation writers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers
Well, it's not needed because everything around Moodle is quoted before it gets to that function (in lib/setup.php, as well as the occasional addslashes() when non-REQUEST data is being inserted).

For performance reasons I wouldn't want to add an extra function call to every field on every update, especially when it's not actually adding anything ... wink
In reply to Martin Dougiamas

Re: Is this change in update_record safe?

by Martín Langhoff -
I suspect it'd be adding double-escapes. It's easy to test. Post something with a single quote and it'll probably store \' literally in the database.

Recently one of our teams came across a (non-Moodle) database that had been populated in exactly that way. They weren't happy.
In reply to Martin Dougiamas

Re: Is this change in update_record safe?

by Martin Dougiamas -
Picture of Core developers Picture of Documentation writers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers
I've reverted it and fixed the original page (it was sending unnecessary data anyway).
In reply to Martin Dougiamas

Re: Is this change in update_record safe?

by John Papaioannou -
You do realize that this means that whenever we do an update_record, no matter if we just want to update one single numeric value, we have to explicitly remember to quote all user-writable character fields in that record?

Can't say I 'm happy with that, and if I had to explicitly quote each time I did a (possibly irrelevant, as when moving a course) UPDATE, I 'd prefer to explicitly remove quotes before calling update_record whenever I did arelevant UPDATE (answering Martin L here).

I'm pretty sure that if I were to sweep the db and code right now I 'd find other places where similar bugs exist. It's just so easy to fall into this trap.

As for the performance hit, how many updates are we doing per page view anyway?

I'll shut up now since I 'm the minority, but at the least the documentation for update_record should include bright neon warning signs.
In reply to John Papaioannou

Re: Is this change in update_record safe?

by Martin Dougiamas -
Picture of Core developers Picture of Documentation writers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers
In practice 99% of data sent to update_records is actually from the user and already quoted (possibly even by magic_quotes which is C code).  The exceptions are really few.
In reply to John Papaioannou

Re: Is this change in update_record safe?

by Petr Skoda -
Picture of Core developers Picture of Documentation writers Picture of Peer reviewers Picture of Plugin developers
I agree that unslashed data are a big security problem, I do hate magic quotes. It is very, very time consuming to check all data that goes into mod/xx/lib.php functions - there is always possibility of hidden SQL injection sad

If I was starting a new project, I would not use magic quotes and instead did the slashing in datalib.php and custom SQL code - it would be very easy to check for SQL injections.

It might be good to have this code commented out in source, I would enable it on my site...
In reply to John Papaioannou

Re: Is this change in update_record safe?

by John Papaioannou -
I think I 'm going crazy.

Yesterday I confirmed bug 2776 (got the error myself), made the change. Then at some point Martin reverted the change in datalib and reopened the bug. So far so good.

Right now, with the exact same steps, I can't repro the bug. In fact, by checking the code, the bug seems to not exist!

Did anyone make a relevant change I overlooked in the meantime or is it time for me to seek professional help? thoughtful
In reply to John Papaioannou

Re: Is this change in update_record safe?

by Martin Dougiamas -
Picture of Core developers Picture of Documentation writers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers
That was me, I fixed the problem like this.  Forgot to close the bug sorry.
In reply to Martin Dougiamas

Re: Is this change in update_record safe?

by Martín Langhoff -
$newcourse = NULL;
$newcourse->id = $courseid;

Ouch. This is going to backfire on PHP5, which doesn't auto-instantiate pseudo objects.

In reply to Martín Langhoff

Re: Is this change in update_record safe?

by Martin Dougiamas -
Picture of Core developers Picture of Documentation writers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers
I think you're mistaken, I do this all over the place and my PHP5 server seems OK.
In reply to Martin Dougiamas

Re: Is this change in update_record safe?

by John Papaioannou -
And I keep on changing this to

$newcourse = new stdClass;
$newcourse->id = $courseid;

wherever I find it... I didn't commit that last change though, forgot. tongueout
In reply to John Papaioannou

Re: Is this change in update_record safe?

by Martin Dougiamas -
Picture of Core developers Picture of Documentation writers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers
It reads better - I'll stick with that too from now on.
In reply to Martin Dougiamas

Re: Is this change in update_record safe?

by Martin Dougiamas -
Picture of Core developers Picture of Documentation writers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers
Actually smile why not:

$variable = new Object;

?
In reply to Martin Dougiamas

Re: Is this change in update_record safe?

by John Papaioannou -
Why not indeed? smile

I don't know, once I had read stdClass in the PHP docs I never continued searching. Is Object a standard way of doing the same thing?
In reply to John Papaioannou

Re: Is this change in update_record safe?

by Martin Dougiamas -
Picture of Core developers Picture of Documentation writers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers
I'd put the definition in lib/setup.php a long time ago and forgotten about it.

class object {}
In reply to Martin Dougiamas

Re: Is this change in update_record safe?

by Martín Langhoff -
I was certain I'd seen posts from someone (Petr?) complaining that some flavour of PHP v5 didn't handle that well. Sorry.
In reply to Martín Langhoff

Re: Is this change in update_record safe?

by Hannes Gassert -
The flavour" you're referring to is PHP5 in error_reporting(E_STRICT) mode - which correctly produces a warning in such cases.