-
-
Notifications
You must be signed in to change notification settings - Fork 490
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature Request] XSS/EscapeOutput: add ability to pass (auto)escaped Methods #1176
Comments
@paulschreiber Without looking at the code in detail, the property expects to receive function names, not class or namespace names. Try passing it |
@jrfnl I'd tried that. When |
I have come across issues with |
Ok, this will need further investigation. Related to #764 |
#933 is the one I was thinking of. |
This looks just like #933. |
This doesn't seem to be fixed, or I'm doing something wrong. I have a code like echo Components::render(
'modal',
array_merge(
$attributes,
[
'modalContent' => Components::render('video', $attributes),
'modalId' => $buttonModalId,
'modalCarouselHeader' => true
]
)
);
echo Components::classnames(['hello']); And in my ruleset, I tried adding <rule ref="WordPress.Security.EscapeOutput">
<properties>
<property name="customAutoEscapedFunctions" type="array">
<element value="render" />
<element value="Components::render" />
</property>
</properties>
</rule> But this doesn't work. What does work (kinda) is: <rule ref="WordPress.Security.EscapeOutput">
<properties>
<property name="customAutoEscapedFunctions" type="array">
<element value="Components" />
</property>
</properties>
</rule> I say kinda because only the Also, I think the related issue is #413. With phpcsutils, how hard would be to add static calls to auto escaped list? |
I kinda had to dig through the sniff and I think the issue is that the check for
part of loop through echo'd components. So the function name that is 'extracted' out inside this conditional only ever evaluates to the first string token found. In my case that is So a problem is a bit deeper, and could probably touch some other sniffs (as it usually ends up). We'd need to have a utility to recognize the static method calls. I think this could be added in the part of #764. I could try to modify the existing sniff to handle static methods. Roughly it would be adding this in the loop if ($this->tokens[$i]['code'] === T_STRING) {
$colon = $this->phpcsFile->findNext(Tokens::$emptyTokens, ($i + 1), null, true);
if ($this->tokens[$colon]['code'] === T_DOUBLE_COLON) {
$methodName = $this->phpcsFile->findNext(T_STRING, ($colon + 1));
if ($this->tokens[$methodName]['code'] === T_STRING) {
// Static method call.
}
}
} Then, inside we could check the if (
$is_formatting_function
|| isset( $this->autoEscapedFunctions[ $functionName ] )
|| isset( $this->escapingFunctions[ $functionName ] )
) {
continue;
} Am I on the right track? |
@dingo-d Good analysis, however IMO the bigger problem with this is not so much how to detect these methods being used, but how to allow them to be passed via a custom ruleset ? Currently the property contains no keys and the function names as values. If we would implement this ability to recognize methods, we would need to be able to distinguish between functions and methods to make sure that a method call using the same name as a global function from the "escaped list "doesn't cause a false negative and visa versa. To that end, we'd need for methods to either have the class name or object name passed as well. The logical choice would be to add those as the array keys, however, a class could contain multiple escaping methods and if those would all use the same "key", then only the last method would actually be registered. See the problem ? |
Yeah, tricky. Could we add a new public property That would have a Something like <rule ref="WordPress.Security.EscapeOutput">
<properties>
<property name="customAutoEscapedMethods" type="array" value="ClassName">
<element value="custom_method_1"/>
<element value="custom_method_2"/>
<element value="custom_method_3"/>
</property>
</properties>
</rule> Not sure if something like that would work 🤷🏼♂️ Then we'd have a public property $customAutoEscapedMethods = [
'ClassName' => [
'custom_method_1',
'custom_method_2',
'custom_method_3',
]
] Again, not sure if this is doable at all 🤷🏼♂️ |
@dingo-d 1) That is not an allowed format in PHPCS (the extra value in the I've been thinking along the lines of: <rule ref="WordPress.Security.EscapeOutput">
<properties>
<property name="customAutoEscapedMethods" type="array">
<element key="custom_method_1" value="ClassName"/>
<element key="custom_method_2 value="ClassName""/>
<element key="custom_method_3" value="$objectName"/>
</property>
</properties>
</rule> Still fiddly and still wouldn't allow for multiple methods with the same name in different classes, but could become workable. |
Yeah, so it's a limitation from the upstream. Are there any chances the configuration can be modified in v4 of phpcs? |
Not really. More than anything, it's a limitation of the PHP array format which (rightfully) can not work with duplicate keys - or rather overwrites those. |
What I thought was: is there a way to provide properties that will be parsed in the sniff as $customAutoEscapedMethods = [
'ClassName' => [
'custom_method_1',
'custom_method_2',
'custom_method_3',
],
'OtherClassName' => [
'custom_method_1',
'custom_method_2',
'custom_method_3',
]
] That way, every class is a separate key, and values are methods that are escaped (so nothing gets overwritten). |
@dingo-d Well, we could make the value a comma-separated list of method names and then handle the exploding of that within the sniff. Does make it fiddly for ruleset configurators, but then again, it's advanced functionality. <rule ref="WordPress.Security.EscapeOutput">
<properties>
<property name="customAutoEscapedMethods" type="array">
<element key="ClassName" value="method_1,method2"/>
<element key="OtherClassName" value="method_1,method_b"/>
</property>
</properties>
</rule> |
Considering the limitations you've mentioned, I feel like this solution is still good in spite of its drawbacks. It is better than what we currently have. I would vote in favor of something like this. |
In version <rule ref="WordPress.Security.EscapeOutput">
<properties>
<property name="customEscapingFunctions" type="array">
<element value="Helpers"/>
</property>
</properties>
</rule> I've added the ignore to each. Or is there a better workaround? |
@janw-me IIRC nothing changed regarding that property in v3, so to get a feel for what you are seeing we'd need more information. Also not sure if this is the right issue for your issue. |
I'll double check tomorrow. |
@jrfnl I've recreated the bug in a test repo: https://github.com/janw-me/wpcs I've tried to keep everything the same while strapping down the the unnecessary parts. |
@dingo-d It changes the output of the error to:
Now it includes both the class and method, which is great :) I've tried the following extra xml: <rule ref="WordPress.Security.EscapeOutput">
<properties>
<property name="customEscapingFunctions" type="array">
<element value="wpcs_esc_str_rev"/>
<element value="Helpers"/>
<element value="Helpers::wpcs_esc_str_rev"/>
<element value="Helpers\:\:wpcs_esc_str_rev"/>
<element key="Helpers" value="wpcs_esc_str_rev"/>
</property>
</properties>
</rule> I still get the error. PS I'm available all afternoon (on slack) for testing. |
I'll probably take a look tomorrow. Maybe there's something in the sniff I need to modify to take the static methods into account. |
Please no pressure, this can wait, there is no rush. If I can help with testing to relieve some pressure. I'm glad to. |
I think I found the issue and will try to see how to solve it in my PR, I just need to get feedback from the rest of the maintainers on the best way forward (I have a quick solution in mind, just need to see if this is an ok approach). |
@janw-me I've updated the branch with some modifications, can you test it? You should be able to pass the static methods with their respective classes now in the For instance, putting |
@janw-me please wait on updating the wiki, as the PR is not merged yet. |
@dingo-d The fix for static customEscapingFunctions is not in 3.0.1, it's still unreleased, right? |
@Luc45 nope, the PR is still open, waiting for a review. |
@dingo-d Thanks for pointing me to that PR. I think it would work. I believe that the issue that @janw-me and me are facing are caused by the Essentially, I had to replace: <property name="customEscapingFunctions" type="array">
<element value="MyHelpers"/>
<element value="my_custom_escaping_function"/>
</property> With: <property name="customEscapingFunctions" type="array">
<element value="myhelpers"/> <!-- Lowercased here -->
<element value="my_custom_escaping_function"/>
</property> check_code_is_escaped parses Your PR should work, as it lowercases all the |
PHPCS 3.1, WPCS 0.13.0, PHP 5.6.30
A backslash used to indicate the global namespace prevents customAutoEscapedFunctions from being recognized.
I have a ruleset like this:
And some code like this:
which generates this error:
If I drop the backslash (
\
):Then PHPCS no longer finds the error.
The text was updated successfully, but these errors were encountered: