Changeset 4384

Show
Ignore:
Timestamp:
10/13/06 00:24:51 (2 years ago)
Author:
markjaquith
Message:

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

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/2.0/wp-admin/admin-functions.php

    r4376 r4384  
    849849        if ('_' == $entry['meta_key'] { 0 }) 
    850850            $style .= ' hidden'; 
     851 
     852        if ( is_serialized($entry['meta_value']) ) { 
     853            if ( is_serialized_string($entry['meta_value']) ) { 
     854                // this is a serialized string, so we should display it 
     855                $entry['meta_value'] = maybe_unserialize($entry['meta_value']); 
     856            } else { 
     857                // this is a serialized array/object so we should NOT display it 
     858                --$count; 
     859                continue; 
     860            } 
     861        } 
     862 
    851863        $entry['meta_key'] = wp_specialchars( $entry['meta_key'], true ); 
    852864        $entry['meta_value'] = wp_specialchars( $entry['meta_value'], true ); 
     
    923935    $metakeyselect = $wpdb->escape(stripslashes(trim($_POST['metakeyselect']))); 
    924936    $metakeyinput = $wpdb->escape(stripslashes(trim($_POST['metakeyinput']))); 
    925     $metavalue = $wpdb->escape(stripslashes(trim($_POST['metavalue']))); 
     937    $metavalue = maybe_serialize(stripslashes((trim($_POST['metavalue'])))); 
     938    $metavalue = $wpdb->escape($metavalue); 
    926939 
    927940    if ( ('0' === $metavalue || !empty ($metavalue)) && ((('#NONE#' != $metakeyselect) && !empty ($metakeyselect)) || !empty ($metakeyinput)) ) { 
     
    951964function update_meta($mid, $mkey, $mvalue) { 
    952965    global $wpdb; 
    953  
     966    $mvalue = maybe_serialize(stripslashes($mvalue)); 
     967    $mvalue = $wpdb->escape($mvalue); 
     968    $mid = (int) $mid; 
    954969    return $wpdb->query("UPDATE $wpdb->postmeta SET meta_key = '$mkey', meta_value = '$mvalue' WHERE meta_id = '$mid'"); 
    955970} 
  • branches/2.0/wp-admin/options.php

    r4335 r4384  
    149149<?php 
    150150$options = $wpdb->get_results("SELECT * FROM $wpdb->options ORDER BY option_name"); 
    151 foreach ( (array) $options as $option ) 
    152     $options_to_update[] = $option->option_name; 
    153 $options_to_update = implode(',', $options_to_update); 
    154 ?> 
    155151 
    156 <input type="hidden" name="page_options" value="<?php echo $options_to_update; ?>" />  
    157  
    158 <?php 
    159152foreach ( (array) $options as $option) : 
    160     $value = wp_specialchars($option->option_value); 
     153    $disabled = ''; 
     154    if ( is_serialized($option->option_value) ) { 
     155        if ( is_serialized_string($option->option_value) ) { 
     156            // this is a serialized string, so we should display it 
     157            $value = wp_specialchars(maybe_unserialize($option->option_value), 'single'); 
     158            $options_to_update[] = $option->option_name; 
     159            $class = 'all-options'; 
     160        } else { 
     161            $value = 'SERIALIZED DATA'; 
     162            $disabled = ' disabled="disabled"'; 
     163            $class = 'all-options disabled'; 
     164        } 
     165    } else { 
     166        $value = wp_specialchars($option->option_value, 'single'); 
     167        $options_to_update[] = $option->option_name; 
     168        $class = 'all-options'; 
     169    } 
    161170    echo " 
    162171<tr> 
     
    164173<td>"; 
    165174 
    166     if (stristr($value, "\n")) echo "<textarea class='all-options' name='$option->option_name' id='$option->option_name' cols='30' rows='5'>$value</textarea>"; 
    167     else echo "<input class='all-options' type='text' name='$option->option_name' id='$option->option_name' size='30' value='" . $value . "' />"; 
     175    if (stristr($value, "\n")) echo "<textarea class='$class' name='$option->option_name' id='$option->option_name' cols='30' rows='5'>$value</textarea>"; 
     176    else echo "<input class='$class' type='text' name='$option->option_name' id='$option->option_name' size='30' value='" . $value . "'$disabled />"; 
    168177     
    169178    echo "</td> 
     
    173182?> 
    174183  </table> 
    175 <p class="submit"><input type="submit" name="Update" value="<?php _e('Update Options &raquo;') ?>" /></p> 
     184<?php $options_to_update = implode(',', $options_to_update); ?> 
     185<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> 
    176186  </form> 
    177187</div> 
  • branches/2.0/wp-admin/wp-admin.css

    r4335 r4384  
    360360textarea.all-options, input.all-options { 
    361361    width: 250px; 
     362} 
     363 
     364input.disabled, textarea.disabled { 
     365    background: #ccc; 
    362366} 
    363367 
  • branches/2.0/wp-includes/functions.php

    r4373 r4384  
    263263 
    264264function maybe_unserialize($original) { 
    265     if ( false !== $gm = @ unserialize($original) ) 
    266         return $gm; 
    267     else 
    268         return $original; 
     265    if ( is_serialized($original) ) // don't attempt to unserialize data that wasn't serialized going in 
     266        if ( false !== $gm = @ unserialize($original) ) 
     267            return $gm; 
     268    return $original; 
     269
     270 
     271function maybe_serialize($data) { 
     272    if ( is_string($data) ) 
     273        $data = trim($data); 
     274    elseif ( is_array($data) || is_object($data) ) 
     275        return serialize($data); 
     276    if ( is_serialized($data) ) 
     277        return serialize($data); 
     278    return $data; 
     279
     280 
     281function is_serialized($data) { 
     282    if ( !is_string($data) ) // if it isn't a string, it isn't serialized 
     283        return false; 
     284    $data = trim($data); 
     285    if ( preg_match("/^[adobis]:[0-9]+:.*[;}]/si",$data) ) // this should fetch all legitimately serialized data 
     286        return true; 
     287    return false; 
     288
     289 
     290function is_serialized_string($data) { 
     291    if ( !is_string($data) ) // if it isn't a string, it isn't a serialized string 
     292        return false; 
     293    $data = trim($data); 
     294    if ( preg_match("/^s:[0-9]+:.*[;}]/si",$data) ) // this should fetch all serialized strings 
     295        return true; 
     296    return false; 
    269297} 
    270298 
     
    366394 
    367395    $_newvalue = $newvalue; 
    368     if ( is_array($newvalue) || is_object($newvalue) ) 
    369         $newvalue = serialize($newvalue); 
     396    $newvalue = maybe_serialize($newvalue); 
    370397 
    371398    wp_cache_set($option_name, $newvalue, 'options'); 
     
    396423        return; 
    397424 
    398     if ( is_array($value) || is_object($value) ) 
    399         $value = serialize($value); 
     425    $value = maybe_serialize($value); 
    400426 
    401427    wp_cache_set($name, $value, 'options'); 
     
    430456    } 
    431457 
    432     $original = $value; 
    433     if ( is_array($value) || is_object($value) ) 
    434         $value = $wpdb->escape(serialize($value)); 
     458    $post_meta_cache[$post_id][$key][] = $value; 
     459 
     460    $value = maybe_serialize($value); 
     461    $value = $wpdb->escape($value); 
    435462 
    436463    $wpdb->query("INSERT INTO $wpdb->postmeta (post_id,meta_key,meta_value) VALUES ('$post_id','$key','$value')"); 
    437  
    438     $post_meta_cache[$post_id][$key][] = $original; 
    439464 
    440465    return true; 
     
    512537 
    513538    $original_value = $value; 
    514     if ( is_array($value) || is_object($value) ) 
    515        $value = $wpdb->escape(serialize($value)); 
     539    $value = maybe_serialize($value); 
     540    $value = $wpdb->escape($value); 
    516541 
    517542    $original_prev = $prev_value; 
    518     if ( is_array($prev_value) || is_object($prev_value) ) 
    519        $prev_value = $wpdb->escape(serialize($prev_value)); 
     543    $prev_value = maybe_serialize($prev_value); 
     544    $prev_value = $wpdb->escape($prev_value); 
    520545 
    521546    if (! $wpdb->get_var("SELECT meta_key FROM $wpdb->postmeta WHERE meta_key = '$key' AND post_id = '$post_id'") ) { 
     
    22532278    $meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key); 
    22542279 
    2255     if ( is_array($meta_value) || is_object($meta_value) ) 
    2256         $meta_value = serialize($meta_value); 
    2257     $meta_value = trim( $meta_value ); 
     2280    // FIXME: usermeta data is assumed to be already escaped 
     2281    $meta_value = stripslashes($meta_value); 
     2282    $meta_value = maybe_serialize($meta_value); 
     2283    $meta_value = $wpdb->escape($meta_value); 
    22582284     
    22592285    if (empty($meta_value)) { 
  • branches/2.0/wp-includes/pluggable-functions.php

    r4287 r4384  
    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