Make WordPress Core

Changeset 4382


Ignore:
Timestamp:
10/12/2006 11:54:36 PM (18 years ago)
Author:
markjaquith
Message:

Prevent users from entering strings that will be interpreted as serialized arrays/objects on the way out. fixes #2591

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-admin/admin-functions.php

    r4355 r4382  
    982982        if ('_' == $entry['meta_key'] { 0 })
    983983            $style .= ' hidden';
     984
     985        if ( is_serialized($entry['meta_value']) ) {
     986            if ( 's' == $entry['meta_value']{0} ) {
     987                // this is a serialized string, so we should display it
     988                $entry['meta_value'] = maybe_unserialize($entry['meta_value']);
     989            } else {
     990                // this is a serialized array/object so we should NOT display it
     991                --$count;
     992                continue;
     993            }
     994        }
     995
    984996        $key_js = js_escape($entry['meta_key']);
    985997        $entry['meta_key'] = wp_specialchars( $entry['meta_key'], true );
     
    10571069    $metakeyselect = $wpdb->escape(stripslashes(trim($_POST['metakeyselect'])));
    10581070    $metakeyinput = $wpdb->escape(stripslashes(trim($_POST['metakeyinput'])));
    1059     $metavalue = $wpdb->escape(stripslashes(trim($_POST['metavalue'])));
     1071    $metavalue = prepare_data(stripslashes((trim($_POST['metavalue']))));
     1072    $metavalue = $wpdb->escape($metavalue);
    10601073
    10611074    if ( ('0' === $metavalue || !empty ($metavalue)) && ((('#NONE#' != $metakeyselect) && !empty ($metakeyselect)) || !empty ($metakeyinput)) ) {
     
    10881101function update_meta($mid, $mkey, $mvalue) {
    10891102    global $wpdb;
     1103    if ( is_serialized(stripslashes($mvalue)) ) // $mvalue looks to be already serialized, so we should serialize it again to prevent the data from coming out in a different form than it came in
     1104        $mvalue = serialize($mvalue);
    10901105    $mid = (int) $mid;
    1091 
    10921106    return $wpdb->query("UPDATE $wpdb->postmeta SET meta_key = '$mkey', meta_value = '$mvalue' WHERE meta_id = '$mid'");
    10931107}
  • trunk/wp-admin/options.php

    r4336 r4382  
    125125<?php
    126126$options = $wpdb->get_results("SELECT * FROM $wpdb->options ORDER BY option_name");
    127 foreach ( (array) $options as $option )
    128     $options_to_update[] = $option->option_name;
    129 $options_to_update = implode(',', $options_to_update);
    130 ?>
    131127
    132 <input type="hidden" name="page_options" value="<?php echo $options_to_update; ?>" />
    133 
    134 <?php
    135128foreach ( (array) $options as $option) :
    136     $value = wp_specialchars($option->option_value, 'single');
     129    $disabled = '';
     130    if ( is_serialized($option->option_value) ) {
     131        if ( 's' == $option->option_value{0} ) {
     132            // this is a serialized string, so we should display it
     133            $value = wp_specialchars(maybe_unserialize($option->option_value), 'single');
     134            $options_to_update[] = $option->option_name;
     135            $class = 'all-options';
     136        } else {
     137            $value = 'SERIALIZED DATA';
     138            $disabled = ' disabled="disabled"';
     139            $class = 'all-options disabled';
     140        }
     141    } else {
     142        $value = wp_specialchars($option->option_value, 'single');
     143        $options_to_update[] = $option->option_name;
     144        $class = 'all-options';
     145    }
    137146    echo "
    138147<tr>
     
    140149<td>";
    141150
    142     if (stristr($value, "\n")) echo "<textarea class='all-options' name='$option->option_name' id='$option->option_name' cols='30' rows='5'>$value</textarea>";
    143     else echo "<input class='all-options' type='text' name='$option->option_name' id='$option->option_name' size='30' value='" . $value . "' />";
     151    if (stristr($value, "\n")) echo "<textarea class='$class' name='$option->option_name' id='$option->option_name' cols='30' rows='5'>$value</textarea>";
     152    else echo "<input class='$class' type='text' name='$option->option_name' id='$option->option_name' size='30' value='" . $value . "'$disabled />";
    144153   
    145154    echo "</td>
     
    149158?>
    150159  </table>
    151 <p class="submit"><input type="submit" name="Update" value="<?php _e('Update Options &raquo;') ?>" /></p>
     160<?php $options_to_update = implode(',', $options_to_update); ?>
     161<p class="submit"><input type="hidden" name="page_options" value="<?php echo wp_specialchars($options_to_update, true); ?>" /><input type="submit" name="Update" value="<?php _e('Update Options &raquo;') ?>" /></p>
    152162  </form>
    153163</div>
  • trunk/wp-admin/wp-admin.css

    r4355 r4382  
    444444textarea.all-options, input.all-options {
    445445    width: 250px;
     446}
     447
     448input.disabled, textarea.disabled {
     449    background: #ccc;
    446450}
    447451
  • trunk/wp-includes/functions.php

    r4379 r4382  
    157157
    158158function maybe_unserialize($original) {
    159     if ( false !== $gm = @ unserialize($original) )
    160         return $gm;
    161     else
    162         return $original;
     159    if ( is_serialized($original) ) // don't attempt to unserialize data that wasn't serialized going in
     160        if ( false !== $gm = @ unserialize($original) )
     161            return $gm;
     162    return $original;
     163}
     164
     165function is_serialized($data) {
     166    if ( !is_string($data) ) // if it isn't a string, it isn't serialized
     167        return false;
     168    $data = trim($data);
     169    if ( preg_match("/^[adobis]:[0-9]+:.*[;}]/si",$data) ) // this should fetch all legitimately serialized data
     170        return true;
     171    return false;
     172}
     173
     174function is_serialized_string($data) {
     175    if ( !is_string($data) ) // if it isn't a string, it isn't a serialized string
     176        return false;
     177    $data = trim($data);
     178    if ( preg_match("/^s:[0-9]+:.*[;}]/si",$data) ) // this should fetch all serialized strings
     179        return true;
     180    return false;
    163181}
    164182
     
    240258
    241259    $_newvalue = $newvalue;
    242     if ( is_array($newvalue) || is_object($newvalue) )
    243         $newvalue = serialize($newvalue);
     260    $newvalue = prepare_data($newvalue);
    244261
    245262    wp_cache_set($option_name, $newvalue, 'options');
     
    263280        return;
    264281
    265     if ( is_array($value) || is_object($value) )
    266         $value = serialize($value);
     282    $value = prepare_data($value);
    267283
    268284    wp_cache_set($name, $value, 'options');
     
    284300    wp_cache_delete($name, 'options');
    285301    return true;
     302}
     303
     304function prepare_data($data) {
     305    if ( is_string($data) )
     306        $data = trim($data);
     307    elseif ( is_array($data) || is_object($data) )
     308        return serialize($data);
     309    if ( is_serialized($data) )
     310        return serialize($data);
     311    return $data;
    286312}
    287313
  • trunk/wp-includes/pluggable.php

    r4339 r4382  
    7979    if ($metavalues) {
    8080        foreach ( $metavalues as $meta ) {
    81             @ $value = unserialize($meta->meta_value);
    82             if ($value === FALSE)
    83                 $value = $meta->meta_value;
     81            $value = maybe_unserialize($meta->meta_value);
    8482            $user->{$meta->meta_key} = $value;
    8583
     
    132130    if ($metavalues) {
    133131        foreach ( $metavalues as $meta ) {
    134             @ $value = unserialize($meta->meta_value);
    135             if ($value === FALSE)
    136                 $value = $meta->meta_value;
     132            $value = maybe_unserialize($meta->meta_value);
    137133            $user->{$meta->meta_key} = $value;
    138134
  • trunk/wp-includes/post.php

    r4372 r4382  
    230230    }
    231231
    232     $original = $value;
    233     if ( is_array($value) || is_object($value) )
    234         $value = $wpdb->escape(serialize($value));
     232    $post_meta_cache[$post_id][$key][] = $value;
     233
     234    $value = prepare_data($value);
     235    $value = $wpdb->escape($value);
    235236
    236237    $wpdb->query("INSERT INTO $wpdb->postmeta (post_id,meta_key,meta_value) VALUES ('$post_id','$key','$value')");
    237 
    238     $post_meta_cache[$post_id][$key][] = $original;
    239238
    240239    return true;
     
    312311
    313312    $original_value = $value;
    314     if ( is_array($value) || is_object($value) )
    315         $value = $wpdb->escape(serialize($value));
     313    $value = prepare_data($value);
     314    $value = $wpdb->escape($value);
    316315
    317316    $original_prev = $prev_value;
    318     if ( is_array($prev_value) || is_object($prev_value) )
    319         $prev_value = $wpdb->escape(serialize($prev_value));
     317    $prev_value = prepare_data($prev_value);
     318    $prev_value = $wpdb->escape($prev_value);
    320319
    321320    if (! $wpdb->get_var("SELECT meta_key FROM $wpdb->postmeta WHERE meta_key = '$key' AND post_id = '$post_id'") ) {
  • trunk/wp-includes/user.php

    r3854 r4382  
    115115    $meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key);
    116116
    117     if ( is_array($meta_value) || is_object($meta_value) )
    118         $meta_value = serialize($meta_value);
    119     $meta_value = trim( $meta_value );
     117    // FIXME: usermeta data is assumed to be already escaped
     118    $meta_value = stripslashes($meta_value);
     119    $meta_value = prepare_data($meta_value);
     120    $meta_value = $wpdb->escape($meta_value);
    120121
    121122    if (empty($meta_value)) {
Note: See TracChangeset for help on using the changeset viewer.