WordPress.org

Make WordPress Core

Changeset 4382


Ignore:
Timestamp:
10/12/06 23:54:36 (9 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.