Plugin Directory

Changeset 3448278


Ignore:
Timestamp:
01/27/2026 11:48:13 PM (6 weeks ago)
Author:
inc2734
Message:

Version up. v12.0.4

Location:
snow-monkey-forms/trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • snow-monkey-forms/trunk/App/Helper.php

    r3089760 r3448278  
    129129        );
    130130    }
     131
     132    /**
     133     * Return true when form ID format is valid.
     134     *
     135     * @param mixed $form_id Form ID.
     136     * @return boolean
     137     */
     138    protected static function _is_valid_form_id_format( $form_id ) {
     139        if ( ! is_scalar( $form_id ) ) {
     140            return false;
     141        }
     142
     143        $form_id = (string) $form_id;
     144        if ( '' === $form_id || ! preg_match( '/^[0-9]+$/', $form_id ) ) {
     145            return false;
     146        }
     147
     148        $form_id = absint( $form_id );
     149        if ( 0 === $form_id ) {
     150            return false;
     151        }
     152
     153        return true;
     154    }
     155
     156    /**
     157     * Validate and sanitize form ID.
     158     *
     159     * @param mixed $form_id Form ID.
     160     * @return int|false
     161     */
     162    public static function sanitize_form_id( $form_id ) {
     163        if ( false === static::_is_valid_form_id_format( $form_id ) ) {
     164            return false;
     165        }
     166
     167        return absint( $form_id );
     168    }
     169
     170    /**
     171     * Return true when token format is valid.
     172     *
     173     * @param mixed $token Token value.
     174     * @return boolean
     175     */
     176    public static function is_valid_token_format( $token ) {
     177        if ( ! is_scalar( $token ) ) {
     178            return false;
     179        }
     180
     181        $token = (string) $token;
     182        if ( '' === $token ) {
     183            return false;
     184        }
     185
     186        return (bool) preg_match( '|^[a-z0-9]+$|', $token );
     187    }
    131188}
  • snow-monkey-forms/trunk/App/Model/Csrf.php

    r3172643 r3448278  
    77
    88namespace Snow_Monkey\Plugin\Forms\App\Model;
     9
     10use Snow_Monkey\Plugin\Forms\App\Helper;
    911
    1012class Csrf {
     
    2830        }
    2931
    30         if ( ! preg_match( '|^[a-z0-9]+$|', $posted_token ) ) {
     32        if ( ! Helper::is_valid_token_format( $posted_token ) ) {
    3133            return false;
    3234        }
  • snow-monkey-forms/trunk/App/Model/Directory.php

    r3172643 r3448278  
    1212use Snow_Monkey\Plugin\Forms\App\Model\Csrf;
    1313use Snow_Monkey\Plugin\Forms\App\Model\Meta;
     14use Snow_Monkey\Plugin\Forms\App\Helper;
    1415
    1516class Directory {
     
    4647        $saved_token = Csrf::saved_token();
    4748
    48         if ( ! preg_match( '|^[a-z0-9]+$|', $saved_token ) ) {
     49        if ( ! Helper::is_valid_token_format( $saved_token ) ) {
    4950            throw new \RuntimeException(
    5051                sprintf(
     
    5354                )
    5455            );
     56        }
     57
     58        $form_id = Helper::sanitize_form_id( $form_id );
     59        if ( false === $form_id ) {
     60            throw new \RuntimeException( '[Snow Monkey Forms] Invalid form ID.' );
    5561        }
    5662
     
    112118        }
    113119
     120        if ( ! static::_is_within_expected_dir( $dir ) ) {
     121            return false;
     122        }
     123
    114124        return static::_remove_children( $dir, $force );
    115125    }
     
    117127    /**
    118128     * Remove child directories and files.
     129     * Callers should ensure the path is within the upload base directory.
    119130     *
    120131     * @param string  $dir   Target directory.
     
    208219     */
    209220    public static function remove( $file ) {
     221        if ( ! static::_is_within_expected_dir( $file ) ) {
     222            return false;
     223        }
     224
    210225        $fileinfo = new SplFileInfo( $file );
    211226
     
    243258        $survival_time = apply_filters( 'snow_monkey_forms/saved_files/survival_time', 60 * 15 );
    244259        return ! $mtime || time() > $mtime + $survival_time;
     260    }
     261
     262    /**
     263     * Return true when path is inside upload base directory.
     264     *
     265     * @param string $path Target path.
     266     * @return boolean
     267     */
     268    protected static function _is_within_expected_dir( $path ) {
     269        $base_dir = realpath( static::get() );
     270        $realpath = realpath( $path );
     271
     272        if ( false === $base_dir || false === $realpath ) {
     273            return false;
     274        }
     275
     276        $token = Csrf::saved_token();
     277        if ( ! Helper::is_valid_token_format( $token ) ) {
     278            return false;
     279        }
     280
     281        $form_id = Helper::sanitize_form_id( Meta::get_formid() );
     282        if ( false === $form_id ) {
     283            return false;
     284        }
     285
     286        $base_dir = wp_normalize_path( $base_dir );
     287        $realpath = wp_normalize_path( $realpath );
     288
     289        $user_dir       = wp_normalize_path(
     290            path_join(
     291                path_join( $base_dir, $token ),
     292                (string) $form_id
     293            )
     294        );
     295        $user_dir       = untrailingslashit( $user_dir );
     296        $user_dir_slash = trailingslashit( $user_dir );
     297
     298        return $realpath === $user_dir || 0 === strpos( $realpath, $user_dir_slash );
    245299    }
    246300
  • snow-monkey-forms/trunk/App/Rest/Route/View.php

    r3172643 r3448278  
    188188
    189189        if ( 'input' === $method || 'complete' === $method || 'systemerror' === $method ) {
     190            // If the token cannot be verified,
     191            // the file deletion process will not be performed.
     192            if ( ! Csrf::validate( Meta::get_token() ) ) {
     193                return $controller->send();
     194            }
     195
    190196            $user_dirpath = Directory::generate_user_dirpath( $this->setting->get( 'form_id' ), false );
    191197
  • snow-monkey-forms/trunk/changelog.txt

    r3431387 r3448278  
    11*** Changelog ***
     2
     3= 12.0.4 =
     4* Fixed a path traversal vulnerability. We strongly encourage you to update to it immediately.
    25
    36= 12.0.3 =
  • snow-monkey-forms/trunk/readme.txt

    r3431387 r3448278  
    33Donate link: https://www.amazon.co.jp/registry/wishlist/39ANKRNSTNW40
    44Tags: gutenberg, block, blocks, editor, gutenberg blocks, page builder, form, forms, mail, email, contact
    5 Stable tag: 12.0.3
     5Stable tag: 12.0.4
    66Requires at least: 6.8
    77Tested up to: 6.9
  • snow-monkey-forms/trunk/snow-monkey-forms.php

    r3431387 r3448278  
    22/**
    33 * Plugin name: Snow Monkey Forms
    4  * Version: 12.0.3
     4 * Version: 12.0.4
    55 * Description: The Snow Monkey Forms is a mail form plugin for the block editor.
    66 * Author: inc2734
     
    2121use Snow_Monkey\Plugin\Forms\App\Model\Directory;
    2222use Snow_Monkey\Plugin\Forms\App\Model\Meta;
     23use Snow_Monkey\Plugin\Forms\App\Helper;
    2324use Snow_Monkey\Plugin\Forms\App\Rest;
    2425use Snow_Monkey\Plugin\Forms\App\Service\Admin\Admin;
     
    184185
    185186                    // phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
    186                     $form_id = isset( $_SERVER['HTTP_X_SMF_FORMID'] ) ? wp_unslash( $_SERVER['HTTP_X_SMF_FORMID'] ) : false;
     187                    $form_id = isset( $_SERVER['HTTP_X_SMF_FORMID'] )
     188                        ? wp_unslash( $_SERVER['HTTP_X_SMF_FORMID'] )
     189                        : '';
    187190                    // phpcs:enable
    188191
    189                     if ( ! $form_id ) {
     192                    $form_id = Helper::sanitize_form_id( $form_id );
     193                    if ( false === $form_id ) {
    190194                        return new WP_REST_Response( 'Bad request.', 400 );
    191195                    }
     
    221225
    222226                    if ( isset( $data[ Meta::get_key() ] ) ) {
     227                        $raw_form_id = isset( $data[ Meta::get_key() ]['formid'] )
     228                            ? $data[ Meta::get_key() ]['formid']
     229                            : '';
     230
     231                        $raw_form_id = Helper::sanitize_form_id( $raw_form_id );
     232                        if ( false === $raw_form_id ) {
     233                            return new WP_REST_Response( 'Bad request.', 400 );
     234                        }
     235
     236                        $data[ Meta::get_key() ]['formid'] = $raw_form_id;
    223237                        $data[ Meta::get_key() ]['sender'] = wp_get_current_user();
    224238                    }
Note: See TracChangeset for help on using the changeset viewer.