[wp-trac] [WordPress Trac] #37757: Add `allowed_classes` to `maybe_unserialize` When WordPress is running on PHP 7+

WordPress Trac noreply at wordpress.org
Fri Feb 21 12:34:48 UTC 2025


#37757: Add `allowed_classes` to `maybe_unserialize` When WordPress is running on
PHP 7+
-------------------------------------------------+-------------------------
 Reporter:  chrisguitarguy                       |       Owner:  (none)
     Type:  enhancement                          |      Status:  new
 Priority:  normal                               |   Milestone:  Awaiting
                                                 |  Review
Component:  Security                             |     Version:
 Severity:  normal                               |  Resolution:
 Keywords:  has-patch has-unit-tests 2nd-        |     Focuses:
  opinion                                        |
-------------------------------------------------+-------------------------

Comment (by FrancescoCarlucci):

 Replying to [comment:14 siliconforks]:
 > Everything in the `wp_options` table and metadata tables gets passed to
 `maybe_unserialize`.  WordPress core sometimes stores objects of type
 `stdClass` here (I'm not sure if there are other classes).

 That's what I am saying, the majority of things are serialized as strings,
 not objects. If WP uses `stdClass` we could comment the filter to
 highlight that `stdClass` class should be added in the `allowed_classes`
 whitelist :)

 > I believe that @johnbillion is talking about
 [https://core.trac.wordpress.org/attachment/ticket/37757/ticket-37757.patch
 this patch] which added another parameter to `maybe_unserialize` without
 adding a filter.

 I see. That's why I believe a filter is the best option. While is `true`
 by default, there is no risk of breaking BC, while it offers developers a
 hook to harden WP against PHP Object injection.

 Here is another patch that merges not approaches and shouldn't break stuff
 :)

 {{{#!php
 <?php
 function maybe_unserialize( $data ) {
         if ( is_serialized( $data ) ) { // Don't attempt to unserialize
 data that wasn't serialized going in.

                 $options = apply_filters(
                         'maybe_unserialize_options',
                         [
                                 'allowed_classes' => true,
                                 'max_depth'       => 4096,
                         ]
                 );

                 return @unserialize( trim( $data ), $options );
         }

         return $data;
 }

 }}}

 Example usage of the filter:

 {{{#!php
 <?php
 add_filter( 'maybe_unserialize_options', function( $options ) {
     $options['allowed_classes'] = [ 'AllowedClass1', 'AllowedClass2' ]; //
 Define your whitelist.
     return $options;
 });

 }}}

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/37757#comment:15>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list