Skip to content

Commit ed931f7

Browse files
committed
Add safe(r) query abstraction
Add db_query_safe that accepts parameters separately. Use it in some places.
1 parent 6cc0deb commit ed931f7

File tree

6 files changed

+72
-71
lines changed

6 files changed

+72
-71
lines changed

include/cvs-auth.inc

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,18 @@ function verify_password($user, $pass)
1212
{
1313
db_connect();
1414

15-
$username = real_clean($user);
16-
$res = mysql_query("SELECT svnpasswd FROM users WHERE cvsaccess AND username = '$username'");
15+
$res = db_query_safe("SELECT svnpasswd FROM users WHERE cvsaccess AND username = ?", [$user]);
1716

1817
if ($res && mysql_num_rows($res) == 1) {
1918
$row = mysql_fetch_array($res);
20-
return gen_svn_pass($username, $pass) === $row["svnpasswd"];
19+
return gen_svn_pass($user, $pass) === $row["svnpasswd"];
2120
}
2221

2322
return false;
2423
}
2524

2625
function verify_username($user) {
2726
db_connect();
28-
29-
$username = real_clean($user);
30-
$res = mysql_query("SELECT 1 FROM users WHERE cvsaccess AND username = '$username'");
31-
32-
if ($res && mysql_num_rows($res) == 1) {
33-
return true;
34-
}
35-
36-
return false;
27+
$res = db_query_safe("SELECT 1 FROM users WHERE cvsaccess AND username = ?", [$user]);
28+
return $res && mysql_num_rows($res) == 1;
3729
}

include/functions.inc

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,21 @@ function db_query($query)
119119
return $res;
120120
}
121121

122+
function db_prepare_query($query, $params) {
123+
if (substr_count($query, '?') !== count($params)) {
124+
die("Incorrect number of parameters to query.");
125+
}
126+
127+
$i = 0;
128+
return preg_replace_callback('/\?/', function() use ($params, &$i) {
129+
return "'" . mysql_real_escape_string($params[$i++]) . "'";
130+
}, $query);
131+
}
132+
133+
function db_query_safe($query, array $params = [])
134+
{
135+
return db_query(db_prepare_query($query, $params));
136+
}
122137

123138
function db_get_one($query)
124139
{
@@ -198,7 +213,7 @@ function show_prev_next($begin, $rows, $skip, $total, $extra = [], $table = true
198213

199214
function show_country_options($cc = "")
200215
{
201-
$res = db_query("SELECT id, name FROM country ORDER BY name");
216+
$res = db_query_safe("SELECT id, name FROM country ORDER BY name");
202217
while ($row = mysql_fetch_assoc($res)) {
203218
echo "<option value=\"{$row['id']}\"", $cc == $row['id'] ? " selected" : "", ">{$row['name']}</option>";
204219
}
@@ -291,7 +306,7 @@ function undo_magic_quotes() {
291306

292307

293308
function find_group_address_from_notes_for($id) {
294-
$res = db_query("SELECT note FROM users_note WHERE userid=$id LIMIT 1");
309+
$res = db_query_safe("SELECT note FROM users_note WHERE userid = ? LIMIT 1", [$id]);
295310
$row = mysql_fetch_assoc($res);
296311
$cc = "";
297312
if (preg_match("/\[group: (\w+)\]/", $row["note"], $matches)) {
@@ -316,7 +331,7 @@ function find_group_address_from_notes_for($id) {
316331
define("MT_USER_APPROVE_MAIL", "group@php.net");
317332
define("MT_USER_REMOVE_MAIL", "group@php.net");
318333
function user_approve($id) {
319-
$res = db_query("UPDATE users SET cvsaccess=1, enable=1 WHERE userid=$id");
334+
$res = db_query_safe("UPDATE users SET cvsaccess=1, enable=1 WHERE userid=?", [$id]);
320335
if ($res && mysql_affected_rows()) {
321336
$cc = find_group_address_from_notes_for($id);
322337
$mailtext = $cc ? $cc : EMAIL_DEFAULT_CC;
@@ -343,7 +358,7 @@ function user_approve($id) {
343358

344359
function user_remove($id) {
345360
$userinfo = fetch_user($id);
346-
$res = db_query("DELETE FROM users WHERE userid=$id");
361+
$res = db_query_safe("DELETE FROM users WHERE userid=?", [$id]);
347362
if ($res && mysql_affected_rows()) {
348363
$cc = find_group_address_from_notes_for($id);
349364

@@ -360,8 +375,8 @@ function user_remove($id) {
360375

361376
/* Notify public records */
362377
mail($to, $subject, $message,"From: PHP Group <group@php.net>\nIn-Reply-To: <cvs-account-$id@php.net>", "-fnoreply@php.net");
363-
db_query("DELETE FROM users_note WHERE userid=$id");
364-
db_query("DELETE FROM users_profile WHERE userid=$id");
378+
db_query_safe("DELETE FROM users_note WHERE userid=?", [$id]);
379+
db_query_safe("DELETE FROM users_profile WHERE userid=?", [$id]);
365380
warn("record $id ($userinfo[username]) removed");
366381
return true;
367382
}
@@ -446,32 +461,23 @@ function is_mirror_site_admin($user) {
446461
function can_modify($user,$userid) {
447462
if (is_admin($user)) return true;
448463

449-
$userid = (int)$userid;
450-
451-
$quser = addslashes($user);
452-
$query = "SELECT userid FROM users"
453-
. " WHERE userid=$userid"
454-
. " AND (email='$quser' OR username='$quser')";
455-
456-
$res = db_query($query);
464+
$query = "SELECT userid FROM users WHERE userid = ? AND (email = ? OR username = ?)";
465+
$res = db_query_safe($query, [$userid, $user, $user]);
457466
return $res ? mysql_num_rows($res) : false;
458467
}
459468

460469
function fetch_user($user) {
461-
$query = "SELECT * FROM users LEFT JOIN users_note USING (userid)";
462470
if ((int)$user) {
463-
$query .= " WHERE users.userid=$user";
464-
}
465-
else {
466-
$quser = addslashes((string)$user);
467-
$query .= " WHERE username='$quser' OR email='$quser'";
468-
}
469-
470-
if ($res = db_query($query)) {
471-
return mysql_fetch_array($res);
471+
$res = db_query_safe(
472+
"SELECT * FROM users LEFT JOIN users_note USING (userid) WHERE users.userid = ?",
473+
[$user]);
474+
} else {
475+
$res = db_query_safe(
476+
"SELECT * FROM users LEFT JOIN users_note USING (userid) WHERE username = ? OR email = ?",
477+
[$user, $user]);
472478
}
473479

474-
return false;
480+
return mysql_fetch_array($res);
475481
}
476482
function invalid_input($in) {
477483
if (!empty($in['email']) && strlen($in['email']) && !is_emailable_address($in['email'])) {
@@ -503,13 +509,8 @@ function validateAction($k) {
503509
}
504510

505511
function fetch_event($id) {
506-
$query = "SELECT * FROM phpcal WHERE id=$id";
507-
508-
if ($res = db_query($query)) {
509-
return mysql_fetch_array($res,MYSQL_ASSOC);
510-
}
511-
512-
return false;
512+
$res = db_query_safe("SELECT * FROM phpcal WHERE id = ?", [$id]);
513+
return mysql_fetch_array($res,MYSQL_ASSOC);
513514
}
514515

515516
function display_options($options,$current) {

manage/challenge-response.php

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@
1313

1414
if (isset($_POST['confirm_them']) && isset($_POST['confirm']) && is_array($_POST['confirm'])) {
1515
foreach ($_POST['confirm'] as $address) {
16-
$addr = mysql_real_escape_string($address);
17-
db_query("insert into accounts.confirmed (email, ts) values ('$addr', NOW())");
16+
db_query_safe("insert into accounts.confirmed (email, ts) values (?, NOW())", [$address]);
1817
}
1918
}
2019

21-
$user_db = mysql_real_escape_string($user);
22-
$res = db_query("select distinct sender from phpmasterdb.users left join accounts.quarantine on users.email = rcpt where username='$user_db' and not isnull(id)");
20+
// TODO: Where does $user come from here?
21+
$res = db_query_safe(
22+
"select distinct sender from phpmasterdb.users left join accounts.quarantine on users.email = rcpt " .
23+
"where username=? and not isnull(id)", [$user]);
2324

2425
$inmates = [];
2526
while ($row = mysql_fetch_row($res)) {
@@ -81,7 +82,9 @@ function sort_by_domain($a, $b)
8182
</form>
8283

8384
<?php
84-
$res = db_query("select count(id) from phpmasterdb.users left join accounts.quarantine on users.email = rcpt where username='$user_db'");
85+
$res = db_query_safe(
86+
"select count(id) from phpmasterdb.users left join accounts.quarantine on users.email = rcpt " .
87+
" where username=?", [$user]);
8588

8689
$n = 0;
8790
if (mysql_num_rows($res) > 0) {

manage/event.php

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,22 @@
2525
head("event administration");
2626
db_connect();
2727

28-
$valid_vars = ['id', 'action','in','begin','max','search','order','full','unapproved'];
29-
foreach($valid_vars as $k) {
30-
$$k = isset($_REQUEST[$k]) ? $_REQUEST[$k] : false;
31-
}
28+
$id = isset($_REQUEST['id']) ? $_REQUEST['id'] : false;
29+
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : false;
30+
$in = isset($_REQUEST['in']) ? $_REQUEST['in'] : false;
31+
$begin = isset($_REQUEST['begin']) ? $_REQUEST['begin'] : false;
32+
$max = isset($_REQUEST['max']) ? $_REQUEST['max'] : false;
33+
$search = isset($_REQUEST['search']) ? $_REQUEST['search'] : false;
34+
$order = isset($_REQUEST['order']) ? $_REQUEST['order'] : false;
35+
$full = isset($_REQUEST['full']) ? $_REQUEST['full'] : false;
36+
$unapproved = isset($_REQUEST['unapproved']) ? $_REQUEST['unapproved'] : false;
37+
3238
if($id) $id = (int)$id;
3339

3440
if ($id && $action) {
3541
switch ($action) {
3642
case 'approve':
37-
if (db_query("UPDATE phpcal SET approved=1,app_by='".real_clean($cuser)."' WHERE id=$id")
43+
if (db_query_safe("UPDATE phpcal SET approved=1,app_by=? WHERE id=?", [$cuser, $id])
3844
&& mysql_affected_rows()) {
3945
$event = fetch_event($id);
4046
$message = "This event has been approved. It will appear on the PHP website shortly.";
@@ -48,7 +54,7 @@
4854
break;
4955
case 'reject':
5056
$event = fetch_event($id);
51-
if (db_query("DELETE FROM phpcal WHERE id=$id")
57+
if (db_query_safe("DELETE FROM phpcal WHERE id=?", [$id])
5258
&& mysql_affected_rows()) {
5359
$message = $event['approved'] ? "This event has been deleted." : "This event has been rejected.";
5460
$did = $event['approved'] ? 'Deleted' : 'Rejected';

manage/user-notes.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,8 @@
145145
if (($iprange = wildcard_ip($_GET['votessearch'])) !== false) {
146146
$search = html_entity_decode($_GET['votessearch'], ENT_QUOTES, 'UTF-8');
147147
$start = real_clean($iprange[0]); $end = real_clean($iprange[1]);
148-
$resultCount = db_query("SELECT count(votes.id) AS total_votes FROM votes JOIN (note) ON (votes.note_id = note.id) WHERE ".
149-
"(hostip >= $start AND hostip <= $end) OR (ip >= $start AND ip <= $end)");
148+
$resultCount = db_query_safe("SELECT count(votes.id) AS total_votes FROM votes JOIN (note) ON (votes.note_id = note.id) WHERE ".
149+
"(hostip >= ? AND hostip <= ?) OR (ip >= ? AND ip <= ?)", [$start, $end, $start, $end]);
150150
$resultCount = mysql_fetch_assoc($resultCount);
151151
$resultCount = $resultCount['total_votes'];
152152
$isSearch = '&votessearch=' . hsc($search);
@@ -158,7 +158,7 @@
158158

159159
} elseif (filter_var(html_entity_decode($_GET['votessearch'], ENT_QUOTES, 'UTF-8'), FILTER_VALIDATE_IP)) {
160160
$searchip = (int) ip2long(filter_var(html_entity_decode($_GET['votessearch'], ENT_QUOTES, 'UTF-8'), FILTER_VALIDATE_IP));
161-
$resultCount = db_query("SELECT count(votes.id) AS total_votes FROM votes JOIN(note) ON (votes.note_id = note.id) WHERE hostip = $searchip OR ip = $searchip");
161+
$resultCount = db_query_safe("SELECT count(votes.id) AS total_votes FROM votes JOIN(note) ON (votes.note_id = note.id) WHERE hostip = ? OR ip = ?", [$searchip, $searchip]);
162162
$resultCount = mysql_fetch_assoc($resultCount);
163163
$resultCount = $resultCount['total_votes'];
164164
$isSearch = '&votessearch=' . hsc(long2ip($searchip));
@@ -169,7 +169,7 @@
169169
"ORDER BY votes.id DESC LIMIT $limitVotes, 25";
170170
} else {
171171
$search = (int) html_entity_decode($_GET['votessearch'], ENT_QUOTES, 'UTF-8');
172-
$resultCount = db_query("SELECT count(votes.id) AS total_votes FROM votes JOIN(note) ON (votes.note_id = note.id) WHERE votes.note_id = $search");
172+
$resultCount = db_query_safe("SELECT count(votes.id) AS total_votes FROM votes JOIN(note) ON (votes.note_id = note.id) WHERE votes.note_id = ?", [$search]);
173173
$resultCount = mysql_fetch_assoc($resultCount);
174174
$resultCount = $resultCount['total_votes'];
175175
$isSearch = '&votessearch=' . hsc($search);
@@ -181,7 +181,7 @@
181181
}
182182
} else {
183183
$isSearch = null;
184-
$resultCount = db_query("SELECT COUNT(votes.id) AS total_votes FROM votes JOIN(note) ON (votes.note_id = note.id)");
184+
$resultCount = db_query_safe("SELECT COUNT(votes.id) AS total_votes FROM votes JOIN(note) ON (votes.note_id = note.id)");
185185
$resultCount = mysql_fetch_assoc($resultCount);
186186
$resultCount = $resultCount['total_votes'];
187187
$sql = "SELECT votes.id, UNIX_TIMESTAMP(votes.ts) AS ts, votes.vote, votes.note_id, note.sect, votes.hostip, votes.ip ".
@@ -513,7 +513,7 @@
513513
die ("Note #$id has already been approved");
514514
}
515515

516-
if ($row['id'] && db_query("UPDATE note SET status=NULL WHERE id=".real_clean($id))) {
516+
if ($row['id'] && db_query_safe("UPDATE note SET status=NULL WHERE id=?", [$id])) {
517517
note_mail_on_action(
518518
$cuser,
519519
$id,
@@ -530,7 +530,7 @@
530530
case 'delete':
531531
if ($id) {
532532
if ($row = note_get_by_id($id)) {
533-
if ($row['id'] && db_query("DELETE note,votes FROM note LEFT JOIN (votes) ON (note.id = votes.note_id) WHERE note.id = ".real_clean($id))) {
533+
if ($row['id'] && db_query_safe("DELETE note,votes FROM note LEFT JOIN (votes) ON (note.id = votes.note_id) WHERE note.id = ?", [$id])) {
534534
// ** alerts **
535535
//$mailto .= get_emails_for_sect($row["sect"]);
536536
$action_taken = ($action == "reject" ? "rejected" : "deleted");
@@ -647,7 +647,7 @@
647647
$sql = 'DELETE FROM votes WHERE votes.note_id = ' . real_clean($id) . ' AND votes.vote = 0';
648648
}
649649
/* Make sure the note has votes before we attempt to delete them */
650-
$result = db_query("SELECT COUNT(id) AS id FROM votes WHERE note_id = " . real_clean($id));
650+
$result = db_query_safe("SELECT COUNT(id) AS id FROM votes WHERE note_id = ?", [$id]);
651651
$rows = mysql_fetch_assoc($result);
652652
if (!$rows['id']) {
653653
echo "<p>No votes exist for Note ID ". hsc($id) ."!</p>";

manage/users.php

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,18 +61,17 @@ function csrf_validate(&$mydata, $name) {
6161

6262
# ?username=whatever will look up 'whatever' by email or username
6363
if ($username) {
64-
$tmp = filter_input(INPUT_GET, "username", FILTER_CALLBACK, ["options" => "mysql_real_escape_string"]) ?: "";
6564
$query = "SELECT userid FROM users"
66-
. " WHERE username='$tmp' OR email='$tmp'";
67-
$res = db_query($query);
65+
. " WHERE username=? OR email=?";
66+
$res = db_query_safe($query, [$username, $username]);
6867

6968
if (!($id = @mysql_result($res, 0))) {
7069
warn("wasn't able to find user matching '$username'");
7170
}
7271
}
7372
if ($id) {
74-
$query = "SELECT * FROM users WHERE users.userid=$id";
75-
$res = db_query($query);
73+
$query = "SELECT * FROM users WHERE users.userid=?";
74+
$res = db_query_safe($query, [$id]);
7675
$userdata = mysql_fetch_array($res);
7776
if (!$userdata) {
7877
warn("Can't find user#$id");
@@ -249,7 +248,7 @@ function csrf_validate(&$mydata, $name) {
249248
</tr>
250249
<?php
251250
if ($id) {
252-
$res = db_query("SELECT markdown FROM users_profile WHERE userid=$id");
251+
$res = db_query_safe("SELECT markdown FROM users_profile WHERE userid=?", [$id]);
253252
$userdata['profile_markdown'] = '';
254253
if ($profile_row = mysql_fetch_assoc($res)) {
255254
$userdata['profile_markdown'] = $profile_row['markdown'];
@@ -305,7 +304,7 @@ function csrf_validate(&$mydata, $name) {
305304
?>
306305
<h2 id="notes">Notes:</h2>
307306
<?php
308-
$res = db_query("SELECT note, UNIX_TIMESTAMP(entered) AS ts FROM users_note WHERE userid=$id");
307+
$res = db_query_safe("SELECT note, UNIX_TIMESTAMP(entered) AS ts FROM users_note WHERE userid=?", [$id]);
309308
while ($res && $userdata = mysql_fetch_assoc($res)) {
310309
echo "<div class='note'>", date("r",$userdata['ts']), "<br />".$userdata['note']."</div>";
311310
}
@@ -350,7 +349,7 @@ function csrf_validate(&$mydata, $name) {
350349
$res = db_query($query);
351350
#echo $query;
352351

353-
$res2 = db_query("SELECT FOUND_ROWS()");
352+
$res2 = db_query_safe("SELECT FOUND_ROWS()");
354353
$total = (int)mysql_result($res2,0);
355354

356355

0 commit comments

Comments
 (0)