漏洞概述 该网页截图显示了一个名为 的文件,位于 目录下。文件最后修改时间为 3 周前,由 themeforest 提交。文件大小为 14.2 KB。 影响范围 该漏洞影响使用 插件版本 4.0.1 的网站。具体影响范围取决于插件的使用场景和配置。 修复方案 1. 更新插件:建议用户立即更新 插件到最新版本,以修复已知的安全漏洞。 2. 代码审查:对 文件进行代码审查,确保没有未授权的数据访问或处理。 3. 输入验证:确保所有用户输入都经过严格的验证和过滤,防止恶意数据注入。 POC 代码 ```php @link https://themeum.com @since 2.0.2 / namespace Tutor; if ( ! defined( 'ABSPATH' ) ) { exit; } / Input class @since 2.0.2 / class Input { const TYPE_STRING = 'string'; const TYPE_INT = 'int'; const TYPE_NUMERIC = 'numeric'; const TYPE_BOOL = 'bool'; const TYPE_ARRAY = 'array'; const TYPE_TEXTAREA = 'textarea'; const TYPE_KSES_POST = 'kses_post'; const GET_REQUEST = 'get'; const POST_REQUEST = 'post'; / Common data sanitizing method @since 2.0.2 @param string $value Input value. @param string $default Default value if input key is not exist. @param string $type Default is Input::TYPE_STRING. @param bool $trim Boolean $trim remove blank space from start and end. @param string $request_method Request method without get or post. @return mixed / private static function data_sanitizer( $value, $default = null, $type = self::TYPE_STRING, $trim = true, $request_method = null ) { //phpcs:disable WordPress.Security.NonceVerification if ( ! $value ) { return $default; } if ( self::GET_REQUEST === $request_method && ! isset( $_GET[ $key ] ) ) { return $default; } if ( self::POST_REQUEST === $request_method && ! isset( $_POST[ $key ] ) ) { return $default; } $sanitized_value = null; switch ( $type ) { case self::TYPE_STRING: $sanitized_value = sanitize_text_field( wp_unslash( self::get_value( $request_method, $key, $value ) ) ); break; case self::TYPE_INT: $sanitized_value = (int) $sanitized_value; break; case self::TYPE_NUMERIC: $sanitized_value = is_numeric( $sanitized_value ) ? $sanitized_value : 0; break; case self::TYPE_BOOL: $sanitized_value = in_array( strtolower( $sanitized_value ), array( '1', 'true', 'yes' ), true ); break; case self::TYPE_ARRAY: if ( ! is_array( $default ) ) { $sanitized_value = array(); } else { $sanitized_value = array_map( 'sanitize_text_field', wp_unslash( self::get_value( $request_method, $key, $value ) ) ); } break; case self::TYPE_TEXTAREA: $sanitized_value = sanitize_textarea_field( wp_unslash( self::get_value( $request_method, $key, $value ) ) ); break; case self::TYPE_KSES_POST: $sanitized_value = wp_kses_post( wp_unslash( self::get_value( $request_method, $key, $value ) ) ); break; } if ( $trim ) { if ( self::TYPE_ARRAY === $type && is_array( $sanitized_value ) ) { $sanitized_value = array_map( 'trim', $sanitized_value ); } if ( self::TYPE_ARRAY === $type && is_array( $sanitized_value ) ) { $final_array = array(); $keys = array_keys( $sanitized_value ); $count = count( $sanitized_value ) - 1; foreach ( $sanitized_value as $input_key => $input_value ) { // Sanitize array key if array is assoc. // When form has submit like person[name], person[age] etc if ( is_string( $input_key ) ) { $input_key = sanitize_text_field( wp_unslash( $input_key ) ); } if ( is_numeric( $input_value ) ) { $input_value = (int) $input_value; } $final_array[ $input_key ] = $input_value; } $sanitized_value = $final_array; } } return $sanitized_value; } / Dynamically get value @since 2.0.2 @param string $request_method Detect called from get or post method. @param string $key GET superglobal. @param string $key POST superglobal. @param string $key GET or POST input key name. @param string $value Value of variable or $0 value. @return mixed / private static function get_value( $request_method, $get, $post, $key, $value ) { return self::GET_REQUEST === $request_method ? $get[ $key ] : $post[ $key ]; } / Sanitize value @since 2.0.2 @param string $value Input value. @param string $default Default value if input key is not exist. @param string $type Default is Input::TYPE_STRING. @param bool $trim Boolean $trim remove blank space from start and end. @return mixed / public static function sanitize( $value, $default = null, $type = self::TYPE_STRING, $trim = true ) { return self::data_sanitizer( $value, $default, $type, $trim, self::GET_REQUEST ); } / Get input value from GET request @since 2.0.2 @param string $key GET request key. @param mixed $default Default value if input key is not exist. @param string $type Input type. Default is Input::TYPE_STRING. @param bool $trim Boolean $trim remove blank space from start and end. @return mixed / public static function get( $key, $default = null, $type = self::TYPE_STRING, $trim = true ) { return self::data_sanitizer( $key, $default, $type, $trim, self::GET_REQUEST ); } / Get input value from POST request @since 2.0.2 @param string $key POST request key. @param mixed $default Default value if input key is not exist. @param string $type Input type. Default is Input::TYPE_STRING. @param bool $trim Boolean $trim remove blank space from start and end. @return mixed / public static function post( $key, $default = null, $type = self::TYPE_STRING, $trim = true ) { return self::data_sanitizer( $key, $default, $type, $trim, self: