Skip to content

Instantly share code, notes, and snippets.

@holizz
Created June 19, 2012 13:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save holizz/2954136 to your computer and use it in GitHub Desktop.
Save holizz/2954136 to your computer and use it in GitHub Desktop.
Fix many SQL injection vectors.
diff --git a/admin/your_subscriptions.php b/admin/your_subscriptions.php
index ddf74ae..97dbba5 100755
--- a/admin/your_subscriptions.php
+++ b/admin/your_subscriptions.php
@@ -7,7 +7,7 @@ global $user_ID, $s2nonce;
if ( isset($_GET['email']) ) {
global $wpdb;
- $user_ID = $wpdb->get_var("SELECT ID FROM $wpdb->users WHERE user_email = '" . urldecode($_GET['email']) . "'");
+ $user_ID = $wpdb->get_var($wpdb->prepare("SELECT ID FROM $wpdb->users WHERE user_email = %s", urldecode($_GET['email'])));
} else {
get_currentuserinfo();
}
diff --git a/classes/class-s2-admin.php b/classes/class-s2-admin.php
index 0d2b529..0220380 100755
--- a/classes/class-s2-admin.php
+++ b/classes/class-s2-admin.php
@@ -364,20 +364,20 @@ class s2_admin extends s2class {
$count['all_users'] = $wpdb->get_var("SELECT COUNT(ID) FROM $wpdb->users");
}
if ( $this->s2_mu ) {
- $count['registered'] = $wpdb->get_var("SELECT COUNT(meta_key) FROM $wpdb->usermeta WHERE meta_key='" . $wpdb->prefix . "capabilities' AND meta_key='" . $this->get_usermeta_keyname('s2_subscribed') . "'");
+ $count['registered'] = $wpdb->get_var($wpdb->prepare("SELECT COUNT(meta_key) FROM $wpdb->usermeta WHERE meta_key='" . $wpdb->prefix . "capabilities' AND meta_key=%s", $this->get_usermeta_keyname('s2_subscribed')));
} else {
- $count['registered'] = $wpdb->get_var("SELECT COUNT(meta_key) FROM $wpdb->usermeta WHERE meta_key='" . $this->get_usermeta_keyname('s2_subscribed') . "'");
+ $count['registered'] = $wpdb->get_var($wpdb->prepare("SELECT COUNT(meta_key) FROM $wpdb->usermeta WHERE meta_key=%s", $this->get_usermeta_keyname('s2_subscribed')));
}
$count['all'] = ($count['confirmed'] + $count['unconfirmed'] + $count['all_users']);
// get subscribers to individual categories but only if we are using per-post notifications
if ( $this->subscribe2_options['email_freq'] == 'never' ) {
if ( $this->s2_mu ) {
foreach ( $all_cats as $cat ) {
- $count[$cat->name] = $wpdb->get_var("SELECT COUNT(a.meta_key) FROM $wpdb->usermeta AS a INNER JOIN $wpdb->usermeta AS b ON a.user_id = b.user_id WHERE a.meta_key='" . $wpdb->prefix . "capabilities' AND b.meta_key='" . $this->get_usermeta_keyname('s2_cat') . $cat->term_id . "'");
+ $count[$cat->name] = $wpdb->get_var($wpdb->prepare("SELECT COUNT(a.meta_key) FROM $wpdb->usermeta AS a INNER JOIN $wpdb->usermeta AS b ON a.user_id = b.user_id WHERE a.meta_key='" . $wpdb->prefix . "capabilities' AND b.meta_key=%s", $this->get_usermeta_keyname('s2_cat') . $cat->term_id));
}
} else {
foreach ( $all_cats as $cat ) {
- $count[$cat->name] = $wpdb->get_var("SELECT COUNT(meta_value) FROM $wpdb->usermeta WHERE meta_key='" . $this->get_usermeta_keyname('s2_cat') . $cat->term_id . "'");
+ $count[$cat->name] = $wpdb->get_var($wpdb->prepare("SELECT COUNT(meta_value) FROM $wpdb->usermeta WHERE meta_key=%s", $this->get_usermeta_keyname('s2_cat') . $cat->term_id));
}
}
}
@@ -532,9 +532,9 @@ class s2_admin extends s2class {
global $wpdb;
$useremails = explode(",\r\n", $emails);
- $useremails = implode("', '", $useremails);
+ $useremails = implode(", ", array_map(function ($c) use ($wpdb) {return $wpdb->prepare('%s', $c);}, $useremails));
- $sql = "SELECT ID FROM $wpdb->users WHERE user_email IN ('$useremails')";
+ $sql = "SELECT ID FROM $wpdb->users WHERE user_email IN ($useremails)";
$user_IDs = $wpdb->get_col($sql);
foreach ( $user_IDs as $user_ID ) {
@@ -564,7 +564,7 @@ class s2_admin extends s2class {
global $wpdb;
$useremails = explode(",\r\n", $emails);
- $useremails = "'" . implode("', '", $useremails) . "'";
+ $useremails = implode(", ", array_map(function ($c) use ($wpdb) {return $wpdb->prepare('%s', $c);}, $useremails));
$sql = "SELECT ID FROM $wpdb->users WHERE user_email IN ($useremails)";
$user_IDs = $wpdb->get_col($sql);
@@ -597,10 +597,10 @@ class s2_admin extends s2class {
global $wpdb;
$subscribers = explode(",\r\n", $subscribers_string);
- $emails = "'" . implode("', '", $subscribers) . "'";
- $ids = $wpdb->get_col("SELECT ID FROM $wpdb->users WHERE user_email IN ($emails)");
- $ids = implode(',', $ids);
- $sql = "UPDATE $wpdb->usermeta SET meta_value='{$format}' WHERE meta_key='" . $this->get_usermeta_keyname('s2_format') . "' AND user_id IN ($ids)";
+ $emails = implode(", ", array_map(function ($c) use ($wpdb) {return $wpdb->prepare('%s', $c);}, $subscribers));
+ $ids = $wpdb->get_col($wpdb->prepare("SELECT ID FROM $wpdb->users WHERE user_email IN ($emails)"));
+ $ids = implode(',', array_map(function ($c) use ($wpdb) {return $wpdb->prepare('%d', $c);}, $ids));
+ $sql = $wpdb->prepare("UPDATE $wpdb->usermeta SET meta_value=%s WHERE meta_key=%s AND user_id IN ($ids)", $format, $this->get_usermeta_keyname('s2_format'));
$wpdb->get_results($sql);
} // end format_change()
@@ -612,7 +612,7 @@ class s2_admin extends s2class {
global $wpdb;
$useremails = explode(",\r\n", $emails);
- $useremails = "'" . implode("', '", $useremails) . "'";
+ $useremails = implode(", ", array_map(function ($c) use ($wpdb) {return $wpdb->prepare('%s', $c);}, $useremails));
$sql = "SELECT ID FROM $wpdb->users WHERE user_email IN ($useremails)";
$user_IDs = $wpdb->get_col($sql);
@@ -660,9 +660,9 @@ class s2_admin extends s2class {
if ( 'yes' == $this->subscribe2_options['show_autosub'] ) {
if ( $this->s2_mu ) {
- $sql = "SELECT DISTINCT a.user_id FROM $wpdb->usermeta AS a INNER JOIN $wpdb->usermeta AS b WHERE a.user_id = b.user_id AND a.meta_key='" . $this->get_usermeta_keyname('s2_autosub') . "' AND a.meta_value='yes' AND b.meta_key='" . $this->get_usermeta_keyname('s2_subscribed') . "'";
+ $sql = $wpdb->prepare("SELECT DISTINCT a.user_id FROM $wpdb->usermeta AS a INNER JOIN $wpdb->usermeta AS b WHERE a.user_id = b.user_id AND a.meta_key=%s AND a.meta_value='yes' AND b.meta_key=%s", $this->get_usermeta_keyname('s2_autosub'), $this->get_usermeta_keyname('s2_subscribed'));
} else {
- $sql = "SELECT DISTINCT user_id FROM $wpdb->usermeta WHERE $wpdb->usermeta.meta_key='" . $this->get_usermeta_keyname('s2_autosub') . "' AND $wpdb->usermeta.meta_value='yes'";
+ $sql = $wpdb->prepare("SELECT DISTINCT user_id FROM $wpdb->usermeta WHERE $wpdb->usermeta.meta_key=%s AND $wpdb->usermeta.meta_value='yes'", $this->get_usermeta_keyname('s2_autosub'));
}
$user_IDs = $wpdb->get_col($sql);
if ( '' == $user_IDs ) { return; }
@@ -694,9 +694,9 @@ class s2_admin extends s2class {
global $wpdb;
if ( $this->s2_mu ) {
- $sql = "SELECT DISTINCT a.user_id FROM $wpdb->usermeta AS a INNER JOIN $wpdb->usermeta AS b WHERE a.user_id = b.user_id AND a.meta_key='" . $this->get_usermeta_keyname('s2_cat') . "$deleted_category' AND b.meta_key='" . $this->get_usermeta_keyname('s2_subscribed') . "'";
+ $sql = $wpdb->prepare("SELECT DISTINCT a.user_id FROM $wpdb->usermeta AS a INNER JOIN $wpdb->usermeta AS b WHERE a.user_id = b.user_id AND a.meta_key=%s AND b.meta_key=%s", $this->get_usermeta_keyname('s2_cat') . $deleted_category, $this->get_usermeta_keyname('s2_subscribed'));
} else {
- $sql = "SELECT DISTINCT user_id FROM $wpdb->usermeta WHERE meta_key='" . $this->get_usermeta_keyname('s2_cat') . "$deleted_category'";
+ $sql = $wpdb->prepare("SELECT DISTINCT user_id FROM $wpdb->usermeta WHERE meta_key=%s", $this->get_usermeta_keyname('s2_cat') . $deleted_category);
}
$user_IDs = $wpdb->get_col($sql);
if ( '' == $user_IDs ) { return; }
diff --git a/classes/class-s2-core.php b/classes/class-s2-core.php
index 9120d6c..6456e5c 100755
--- a/classes/class-s2-core.php
+++ b/classes/class-s2-core.php
@@ -213,7 +213,7 @@ class s2class {
foreach ( $public_subscribers as $email ) {
$new_email = $this->sanitize_email($email);
if ( $email !== $new_email ) {
- $wpdb->get_results("UPDATE $this->public SET email='$new_email' WHERE CAST(email as binary)='$email'");
+ $wpdb->get_results($wpdb->prepare("UPDATE $this->public SET email=%s WHERE CAST(email as binary)=%s", $new_email, $email));
}
}
return;
@@ -742,7 +742,7 @@ class s2class {
if ( !$id ) {
return false;
}
- return $wpdb->get_var("SELECT email FROM $this->public WHERE id=$id");
+ return $wpdb->get_var($wpdb->prepare("SELECT email FROM $this->public WHERE id=%d", $id));
} // end get_email()
/**
@@ -754,7 +754,7 @@ class s2class {
if ( !$email ) {
return false;
}
- return $wpdb->get_var("SELECT id FROM $this->public WHERE email='$email'");
+ return $wpdb->get_var($wpdb->prepare("SELECT id FROM $this->public WHERE email=%s", $email));
} // end get_id()
/**
@@ -769,12 +769,12 @@ class s2class {
if ( false !== $this->is_public($email) ) {
// is this an email for a registered user
- $check = $wpdb->get_var("SELECT user_email FROM $wpdb->users WHERE user_email='$this->email'");
+ $check = $wpdb->get_var($wpdb->prepare("SELECT user_email FROM $wpdb->users WHERE user_email=%s", $this->email));
if ( $check ) { return; }
if ( $confirm ) {
- $wpdb->get_results("UPDATE $this->public SET active='1', ip='$this->ip' WHERE CAST(email as binary)='$email'");
+ $wpdb->get_results($wpdb->prepare("UPDATE $this->public SET active='1', ip=%s WHERE CAST(email as binary)=%s", $this->ip, $email));
} else {
- $wpdb->get_results("UPDATE $this->public SET date=CURDATE() WHERE CAST(email as binary)='$email'");
+ $wpdb->get_results($wpdb->prepare("UPDATE $this->public SET date=CURDATE() WHERE CAST(email as binary)=%s", $email));
}
} else {
if ( $confirm ) {
@@ -793,7 +793,7 @@ class s2class {
global $wpdb;
if ( !is_email($email) ) { return false; }
- $wpdb->get_results("DELETE FROM $this->public WHERE CAST(email as binary)='$email'");
+ $wpdb->get_results($wpdb->prepare("DELETE FROM $this->public WHERE CAST(email as binary)=%s", $email));
} // end delete()
/**
@@ -809,9 +809,9 @@ class s2class {
if ( false === $status ) { return false; }
if ( '0' == $status ) {
- $wpdb->get_results("UPDATE $this->public SET active='1' WHERE CAST(email as binary)='$email'");
+ $wpdb->get_results($wpdb->prepare("UPDATE $this->public SET active='1' WHERE CAST(email as binary)=%s", $email));
} else {
- $wpdb->get_results("UPDATE $this->public SET active='0' WHERE CAST(email as binary)='$email'");
+ $wpdb->get_results($wpdb->prepare("UPDATE $this->public SET active='0' WHERE CAST(email as binary)=%s", $email));
}
} // end toggle()
@@ -853,7 +853,7 @@ class s2class {
if ( '' == $email ) { return false; }
// run the query and force case sensitivity
- $check = $wpdb->get_var("SELECT active FROM $this->public WHERE CAST(email as binary)='$email'");
+ $check = $wpdb->get_var($wpdb->prepare("SELECT active FROM $this->public WHERE CAST(email as binary)=%s", $email));
if ( '0' == $check || '1' == $check ) {
return $check;
} else {
@@ -906,7 +906,7 @@ class s2class {
if ( '' == $email ) { return false; }
- $check = $wpdb->get_var("SELECT user_email FROM $wpdb->users WHERE user_email='$email'");
+ $check = $wpdb->get_var($wpdb->prepare("SELECT user_email FROM $wpdb->users WHERE user_email=%s", $email));
if ( $check ) {
return true;
} else {
@@ -922,7 +922,7 @@ class s2class {
if ( '' == $email ) { return false; }
- $id = $wpdb->get_var("SELECT id FROM $wpdb->users WHERE user_email='$email'");
+ $id = $wpdb->get_var($wpdb->prepare("SELECT id FROM $wpdb->users WHERE user_email=%s", $email));
return $id;
} // end get_user_id()
@@ -972,7 +972,7 @@ class s2class {
// text or HTML subscribers
if ( 'all' != $r['format'] ) {
$JOIN .= "INNER JOIN $wpdb->usermeta AS b ON a.user_id = b.user_id ";
- $AND .= " AND b.meta_key='" . $this->get_usermeta_keyname('s2_format') . "' AND b.meta_value=";
+ $AND .= $wpdb->prepare(" AND b.meta_key=%s AND b.meta_value=", $this->get_usermeta_keyname('s2_format'));
if ( 'html' == $r['format'] ) {
$AND .= "'html'";
} elseif ( 'html_excerpt' == $r['format'] ) {
@@ -989,7 +989,7 @@ class s2class {
$JOIN .= "INNER JOIN $wpdb->usermeta AS c ON a.user_id = c.user_id ";
$and = '';
foreach ( explode(',', $r['cats']) as $cat ) {
- ('' == $and) ? $and = "c.meta_key='" . $this->get_usermeta_keyname('s2_cat') . "$cat'" : $and .= " OR c.meta_key='" . $this->get_usermeta_keyname('s2_cat') . "$cat'";
+ ('' == $and) ? $and = $wpdb->prepare("c.meta_key=%s", $this->get_usermeta_keyname('s2_cat') . $cat) : $and .= $wpdb->prepare(" OR c.meta_key=%s", $this->get_usermeta_keyname('s2_cat') . $cat);
}
$AND .= " AND ($and)";
}
@@ -997,17 +997,17 @@ class s2class {
// specific authors
if ( '' != $r['author'] ) {
$JOIN .= "INNER JOIN $wpdb->usermeta AS d ON a.user_id = d.user_id ";
- $AND .= " AND (d.meta_key='" . $this->get_usermeta_keyname('s2_authors') . "' AND NOT FIND_IN_SET(" . $r['author'] . ", d.meta_value))";
+ $AND .= $wpdb->prepare(" AND (d.meta_key=%s AND NOT FIND_IN_SET(%s, d.meta_value))", $this->get_usermeta_keyname('s2_authors'), $r['author']);
}
if ( $this->s2_mu ) {
$sql = "SELECT a.user_id FROM $wpdb->usermeta AS a " . $JOIN . "WHERE a.meta_key='" . $wpdb->prefix . "capabilities'" . $AND;
} else {
- $sql = "SELECT a.user_id FROM $wpdb->usermeta AS a " . $JOIN . "WHERE a.meta_key='" . $this->get_usermeta_keyname('s2_subscribed') . "'" . $AND;
+ $sql = $wpdb->prepare("SELECT a.user_id FROM $wpdb->usermeta AS a " . $JOIN . "WHERE a.meta_key=%s" . $AND, $this->get_usermeta_keyname('s2_subscribed'));
}
$result = $wpdb->get_col($sql);
if ( $result ) {
- $ids = implode(',', $result);
+ $ids = implode(',', array_map(function ($c) use ($wpdb) {return $wpdb->prepare('%s', $c);}, $result));
$registered = $wpdb->get_col("SELECT user_email FROM $wpdb->users WHERE ID IN ($ids)");
}
@@ -1325,7 +1325,7 @@ class s2class {
if ( $subscribe != '1' ) { return $comment_ID; }
// Retrieve the information about the comment
- $sql = "SELECT comment_author_email, comment_approved FROM $wpdb->comments WHERE comment_ID='$comment_ID' LIMIT 1";
+ $sql = $wpdb->prepare("SELECT comment_author_email, comment_approved FROM $wpdb->comments WHERE comment_ID=%s LIMIT 1", $comment_ID);
$comment = $wpdb->get_row($sql, OBJECT);
if ( empty($comment) ) { return $comment_ID; }
@@ -1413,21 +1413,21 @@ class s2class {
}
$s2_post_types = apply_filters('s2_post_types', $s2_post_types);
foreach( $s2_post_types as $post_type ) {
- ('' == $type) ? $type = "'$post_type'" : $type .= ", '$post_type'";
+ ('' == $type) ? $type = $wpdb->prepare("%s", $post_type) : $type .= $wpdb->prepare(", %s", $post_type);
}
// collect posts
if ( $resend == 'resend' ) {
if ( $this->subscribe2_options['cron_order'] == 'desc' ) {
- $posts = $wpdb->get_results("SELECT ID, post_title, post_excerpt, post_content, post_type, post_password, post_date, post_author FROM $wpdb->posts WHERE post_date >= '$last' AND post_date < '$prev' AND post_status IN ($status) AND post_type IN ($type) ORDER BY post_date DESC");
+ $posts = $wpdb->get_results($wpdb->prepare("SELECT ID, post_title, post_excerpt, post_content, post_type, post_password, post_date, post_author FROM $wpdb->posts WHERE post_date >= %s AND post_date < %s AND post_status IN ($status) AND post_type IN ($type) ORDER BY post_date DESC"), $last, $prev);
} else {
- $posts = $wpdb->get_results("SELECT ID, post_title, post_excerpt, post_content, post_type, post_password, post_date, post_author FROM $wpdb->posts WHERE post_date >= '$last' AND post_date < '$prev' AND post_status IN ($status) AND post_type IN ($type) ORDER BY post_date ASC");
+ $posts = $wpdb->get_results($wpdb->prepare("SELECT ID, post_title, post_excerpt, post_content, post_type, post_password, post_date, post_author FROM $wpdb->posts WHERE post_date >= %s AND post_date < %s AND post_status IN ($status) AND post_type IN ($type) ORDER BY post_date ASC"), $last, $prev);
}
} else {
if ( $this->subscribe2_options['cron_order'] == 'desc' ) {
- $posts = $wpdb->get_results("SELECT ID, post_title, post_excerpt, post_content, post_type, post_password, post_date, post_author FROM $wpdb->posts WHERE post_date >= '$prev' AND post_date < '$now' AND post_status IN ($status) AND post_type IN ($type) ORDER BY post_date DESC");
+ $posts = $wpdb->get_results($wpdb->prepare("SELECT ID, post_title, post_excerpt, post_content, post_type, post_password, post_date, post_author FROM $wpdb->posts WHERE post_date >= %s AND post_date < %s AND post_status IN ($status) AND post_type IN ($type) ORDER BY post_date DESC"), $prev, $now);
} else {
- $posts = $wpdb->get_results("SELECT ID, post_title, post_excerpt, post_content, post_type, post_password, post_date, post_author FROM $wpdb->posts WHERE post_date >= '$prev' AND post_date < '$now' AND post_status IN ($status) AND post_type IN ($type) ORDER BY post_date ASC");
+ $posts = $wpdb->get_results($wpdb->prepare("SELECT ID, post_title, post_excerpt, post_content, post_type, post_password, post_date, post_author FROM $wpdb->posts WHERE post_date >= %s AND post_date < %s AND post_status IN ($status) AND post_type IN ($type) ORDER BY post_date ASC"), $prev, $now);
}
}
} else {
@@ -1641,7 +1641,7 @@ class s2class {
// do we need to install anything?
$this->public = $table_prefix . "subscribe2";
- if ( $wpdb->get_var("SHOW TABLES LIKE '{$this->public}'") != $this->public ) { $this->install(); }
+ if ( $wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $this->public)) != $this->public ) { $this->install(); }
//do we need to upgrade anything?
if ( is_array($this->subscribe2_options) && $this->subscribe2_options['version'] !== S2VERSION ) {
add_action('shutdown', array(&$this, 'upgrade'));
diff --git a/classes/class-s2-frontend.php b/classes/class-s2-frontend.php
index 809eda9..a3d69bb 100755
--- a/classes/class-s2-frontend.php
+++ b/classes/class-s2-frontend.php
@@ -64,7 +64,7 @@ class s2_frontend extends s2class {
$this->email = $this->sanitize_email($_POST['email']);
$this->ip = $_POST['ip'];
// does the supplied email belong to a registered user?
- $check = $wpdb->get_var("SELECT user_email FROM $wpdb->users WHERE user_email = '$this->email'");
+ $check = $wpdb->get_var($wpdb->prepare("SELECT user_email FROM $wpdb->users WHERE user_email = %s"), $this->email);
if ( '' != $check ) {
// this is a registered email
$this->s2form = $this->please_log_in;
@mattyrob
Copy link

I think I've got a way around the array_map issue, I've created a new function:

/**
Function to sanitise array of data for SQL
*/
function prepare_in_data($data) {
    global $wpdb;
    return $wpdb->prepare('%s', $data);
} // end prepare_in_data()

And all the array_map lines now look something like this:
$ids = implode(',', array_map(array($this, 'prepare_in_data'), $result));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment