I've submitted a plugin for review and it was not accepted as it needs some fixes with data sanitization and escaping.
One of the flagged examples was this line:
echo "<option value=\"$result->ID\" $selected>$result->display_name</option>\n";
(I'm guessing because of this value: $result->display_name)
third to last line of this function:
function get_users_with_role( $roles, $current_selected ) {
global $wpdb;
if ( ! is_array( $roles ) )
$roles = array_walk( explode( ",", $roles ), 'trim' );
$sql = '
SELECT ID, display_name
FROM ' . $wpdb->users . ' INNER JOIN ' . $wpdb->usermeta . '
ON ' . $wpdb->users . '.ID = ' . $wpdb->usermeta . '.user_id
WHERE ' . $wpdb->usermeta . '.meta_key = \'' . $wpdb->prefix . 'capabilities\'
AND (
';
$i = 1;
foreach ( $roles as $role ) {
$sql .= ' ' . $wpdb->usermeta . '.meta_value LIKE \'%"' . $role . '"%\' ';
if ( $i < count( $roles ) ) $sql .= ' OR ';
$i++;
}
$sql .= ' ) ';
$sql .= ' ORDER BY display_name ';
$results = $wpdb->get_results( $sql);
foreach ($results as $result){
$selected = null;
if($result->ID == $current_selected){
$selected = "selected =\"selected\"";
}
echo "<option value=\"$result->ID\" $selected>$result->display_name</option>\n";
}
}
Do we really need to escape the data that was already entered in the WP database, especially usernames and their integer ids?
$result->display_name
was modified before your code receives the value? Even if it wasn't dangerous, it may not be displayed (properly, or at all) because it contained invalid characters, etc. So always escape it when displaying to end-users. It's not just for security, but also ensures users see the proper data.