Skip to content

Conversation

rodrigoprimo
Copy link
Collaborator

The sniff was incorrectly treating function names as case-sensitive when checking for nonce verification functions. This led to false positives when developers used valid nonce verification functions with mixed or uppercase letters.

The fix ensures function names are properly converted to lowercase before comparing against the allowed nonce verification functions list, respecting PHP's case-insensitive function name behavior.

The sniff was incorrectly treating function names as case-sensitive when checking for
nonce verification functions. This led to false positives when developers used valid
nonce verification functions with mixed or uppercase letters.

The fix ensures function names are properly converted to lowercase before comparing
against the allowed nonce verification functions list, respecting PHP's case-insensitive
function name behavior.
Copy link
Member

@jrfnl jrfnl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch.

... respecting PHP's case-insensitive function name behavior.

PHP isn't completely case-insensitive for function names. Only for the ASCII characters and as this sniff allows for end-users to provide a list of customNonceVerificationFunctions via a public property, we cannot rely on all nonce-verification functions we need to check against being completely ASCII-based.

In other words, if someone would add a custom nonce verification function called déjà_vu(), this function would now never be recognized as a valid nonce verification function.

So, we can only use strtolower() to compare the names case-insensitively if we have a known list of functions we compare against and we are 100% sure all those function names are ASCII-based names.

When the list of functions to compare against is not known in advance and/or doesn't consist of all ASCII-based functions we need to loop through all "allowed functions" using the PHPCSUtils NamingConventions::isEqual() method - which does a comparison between two names in a way which is similar to how PHP does it.

@rodrigoprimo
Copy link
Collaborator Author

In other words, if someone would add a custom nonce verification function called déjà_vu(), this function would now never be recognized as a valid nonce verification function.

I might be missing something, but I believe the sniff would handle déjà_vu() correctly. strtolower() ignores multibyte characters/non-ASCII characters. Is this not similar to what we discussed in a call and resulted in PHPCSStandards/PHP_CodeSniffer#372 (comment)?

Here is how I'm checking this:

// phpcs:set WordPress.Security.NonceVerification customNonceVerificationFunctions[] déjà_vu
function non_ascii_characters() {
    déjà_vu( 'something' ); // Ok.

    update_post_meta( (int) $_POST['id'], 'a_key', $_POST['a_value'] );
}

function non_ascii_characters() {
    DéJà_VU( 'something' ); // Ok.

    update_post_meta( (int) $_POST['id'], 'a_key', $_POST['a_value'] );
}

function non_ascii_characters() {
    dÉjÀ_vu( 'something' ); // Error, but that is correct as déjà_vu and dÉjÀ_vu are different function names.

    update_post_meta( (int) $_POST['id'], 'a_key', $_POST['a_value'] );
}

That being said, one thing that I realize only after seeing your comment is that if a function, even one with just ASCII characters, is added to customNonceVerificationFunctions using uppercase letters, this could lead to false positives:

// phpcs:set WordPress.Security.NonceVerification customNonceVerificationFunctions[] UPPERCASE_NAME
function non_ascii_characters() {
    UPPERCASE_NAME( 'something' ); // Should be ok, but the sniff generates an error.

    update_post_meta( (int) $_POST['id'], 'a_key', $_POST['a_value'] );
}

Maybe using NamingConventions::isEqual() will be necessary anyway to handle this case? Or do you have a different suggestion?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants