You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
PHPSniffer managed to run forever analyzing a certain CSS file. (I discovered later, 'practically forever', as in longer than the heat death of the universe, but still it theoretically would complete in a finite time).
After the verbose mode created a 17-gigabyte log, I cut it off.
The section of the CSS file that causes the problem is this bit of code.
The issue is a very gross inefficiency on the part of PHPSniffer, it seems to scale as O(2^n).
For each line of "#available_widgets", it appears that the entire file is scanned again, recursively. This creates an exponential amount of work.
To reproduce
Run the following on the command line:
php /usr/src/phpSniffer/phpcs.phar -p test.css --standard=PHPCompatibilityWP -vvv | tee test.txt
Expected behaviour
The analysis completes in a reasonable amount of time
If a bug in a sniff causes the analysis to take inordinately long, cut off the output at a reasonable point. For example, a restriction of 100M iterations could at least force the execution to skip te file after ~30 seconds, instead of stalling until the server's disk/memory limit is reached and the OOMkiller crashes it / PHP memory limit causes an exception.
Actual behaviour:
A little interesting experiment that really exposes the behaviour is to take the initial block of CSS only, then add the #available-widgets lines block by block. I started at a random position in the middle /* dashicons-admin-users */, and added blocks one by one, then looked at the execution time. I didn't do a lot of sampling so there's quite a bit of statistical error here. The exponential behaviour is pretty clear after a few iterations of adding more lines to the file.
t ~ 23.383e(0.325L) where t = time in ms, L = number of '#available-widgets' lines is a least-squares exponential fit to this data.
Versions (please complete the following information)
Operating System: Debian 12.
PHP version
8.3
PHP_CodeSniffer version
master
Standard
PHPCompatibilityWP
Install type
PHAR / Git clone.
Additional context
This can cause the viability of Denial-of-service attacks if PHPCodeSniffer / PHPCompatibilityWP is provided as a service and may be a security issue in this context.
Please confirm:
I have searched the issue list and am not opening a duplicate issue.
[o] I do not confirm that this bug is a bug in PHP_CodeSniffer and not in one of the external standards. It can be argued either way and depends on if PHP_Codesniffer takes responsibility for run-time length, it also depends on whether PHP_CodeSniffer does iteration or if external standards can do iteration over symbols (what does the looping?) or can run code. I merely observed the behaviour and didn't step through each line of code.
[x ] I have verified the issue still exists in the master branch of PHP_CodeSniffer.
The text was updated successfully, but these errors were encountered:
Based on the information you provide this seems like a very contrived example. You suggest it is a potential vector for a denial-of-service attack but only in the situation where:
Someone is providing PHPCodeSniffer as a service in production
There are no limits on the request to protect
They are allowing CSS to be fed into a static analysis tool for PHP
This seems like a totally unrealistic example and nowhere near the normal use case for PHPCodeSniffer. Why are you feeding CSS into a tool for PHP?
Describe the bug
PHPSniffer managed to run forever analyzing a certain CSS file. (I discovered later, 'practically forever', as in longer than the heat death of the universe, but still it theoretically would complete in a finite time).
After the verbose mode created a 17-gigabyte log, I cut it off.
The section of the CSS file that causes the problem is this bit of code.
The issue is a very gross inefficiency on the part of PHPSniffer, it seems to scale as O(2^n).
For each line of "#available_widgets", it appears that the entire file is scanned again, recursively. This creates an exponential amount of work.
To reproduce
Run the following on the command line:
Expected behaviour
Actual behaviour:
A little interesting experiment that really exposes the behaviour is to take the initial block of CSS only, then add the
#available-widgets
lines block by block. I started at a random position in the middle/* dashicons-admin-users */
, and added blocks one by one, then looked at the execution time. I didn't do a lot of sampling so there's quite a bit of statistical error here. The exponential behaviour is pretty clear after a few iterations of adding more lines to the file.t ~ 23.383e(0.325L) where t = time in ms, L = number of '#available-widgets' lines is a least-squares exponential fit to this data.
Versions (please complete the following information)
Additional context
This can cause the viability of Denial-of-service attacks if PHPCodeSniffer / PHPCompatibilityWP is provided as a service and may be a security issue in this context.
Please confirm:
master
branch of PHP_CodeSniffer.The text was updated successfully, but these errors were encountered: