Fix quadratic backtracking in rule DS440011 (long cipher-name runs hang scans) - #789
Open
Syed Muhammad Nafay Hassan Rizvi (Darkslayer3324j) wants to merge 1 commit into
Conversation
The middle [A-Z0-9\-]+-? group backtracked from every cipher-name prefix in a long run of cipher-name characters, so a 100 KB line took ~13 s and a 400 KB line minutes. Bound the run to 64 characters and drop the redundant -?. Add must-match/must-not-match self-tests and a regression test. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Author
|
@microsoft-github-policy-service agree |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Rule DS440011 (OpenSSL cipher-suite names) takes quadratic time on a long run of cipher-name characters, so a scan can hang on a single long line. With the default rules on
const char *s = "AES-AES-AES-...";:Only DS440011 is affected: running each rule alone with
--rule-idson the 100 KB line gave DS440011 13.5 s, and DS440010, DS440000 and an empty no-op rule about 1.5 s (that is DevSkim's own baseline for a line this size).The pattern is
(AES|DH|...|PSK)[A-Z0-9\-]+-?(SHA|MD|GOST)[A-Z0-9\-]*. In a run with many cipher-name prefixes but noSHA/MD/GOST, every prefix occurrence starts a match whose[A-Z0-9\-]+runs to the end of the run and then backtracks all the way back. Theruleruns its regex before itsopensslcondition, so ordinary minified or generated files, or a hostile file in a scanned repo, can stall a whole scan.Fix
[A-Z0-9\-]{1,64}. The longest real cipher-suite names are well under 64 characters.-?, which was redundant because-is already in the character class.I compared the old and new pattern on all 158 cipher names from
openssl ciphers -V 'ALL:COMPLEMENTOFALL'plus 10 other names (TLS 1.3, PSK, GOST, EXP, IDEA), each in 6 contexts (bare, quoted, in aSSL_CTX_set_cipher_listcall, in aciphers = ...:HIGH:!aNULLstring, embedded, and in a command line): 1008 cases, identical match spans.devskim analyzeoutput on a small file with a real cipher string is unchanged.Tests
must-match(SSL_CTX_set_cipher_list(ctx, "ECDHE-RSA-AES256-GCM-SHA384"); // openssl) and amust-not-match("AES-128-CBC");devskim verifyandValidateDefaultRulespass.HardcodedOpenSslCipherRuleDoesNotBacktrackOnLongRuns: analyzes a 200 KBAES-line with the default rules and asserts under 15 s. It fails onmain(50.99 s) and passes with the change.dotnet test -f net8.0: 301 passed (300 without the new test); the suite went from 73 s to 24 s.Changelog.mdupdated;devskim --versionon this branch reports 1.0.99, matching the heading.I noticed while investigating that the same regex text does not exist in DS440010 (its cipher-constant pattern uses
_separators) and that DS440010 stays fast on the same input.Found by timing every regex rule against adversarial input; my first pass used a different regex engine and over-reported, so I re-measured with the real .NET engine before filing. Drafted with AI assistance (Claude Code).