fix ASP.NET viewstate CLI argument handling - #436
Open
liquidsec wants to merge 1 commit into
Open
Conversation
Two defects made the positional CLI path silently mishandle valid input, so a viewstate that cracked via --url would report nothing when the same viewstate and generator were passed by hand: - check_secret_args was 3, so the 4th positional was sliced away by check_all_modules. check_secret() accepts (viewstate, generator, url, ViewStateUserKey), but url and userkey could never be supplied together -- the userkey vanished with no error. Raised to 4. - the generator pattern matched uppercase hex only. A lowercase generator fell through to the ViewStateUserKey branch, leaving the generator at its "0000" default and checking the wrong thing, then reporting "No secrets found". Matching is now case-insensitive and resolve_args canonicalizes to uppercase so downstream path brute-forcing and result strings agree. Also document the remaining asymmetry, which is a real constraint rather than a bug: DOTNET45 derives the validation key from the page path via the SP800-108 KDF purposes, and DOTNET40 with IsolateApps mixes in an app-path hash, so neither can be validated without the URL. This is the usual reason --url succeeds where passing the viewstate and generator alone does not.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## dev #436 +/- ##
=======================================
Coverage 99.47% 99.47%
=======================================
Files 31 31
Lines 3231 3231
=======================================
Hits 3214 3214
Misses 17 17 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
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.
Two defects made the positional CLI path silently mishandle valid input, so a viewstate that cracked via
--urlwould report nothing when the same viewstate and generator were passed by hand.check_secret_argstruncated the 4th positionalcheck_all_modulesslicesargs[0:x.check_secret_args], andASPNET_Viewstatedeclared3. Butcheck_secret()accepts(viewstate, generator, url, ViewStateUserKey)— so URL and user key could never be supplied together, and the user key was dropped with no error:Raised to
4.Generator matching was uppercase-only
_generator_patternwas^[A-F0-9]{8}$. A lowercase generator didn't merely fail to parse — it fell through to theViewStateUserKeybranch, leaving the generator at its"0000"default and checking the wrong thing entirely, then reportingNo secrets found :(:Now case-insensitive, with
resolve_argscanonicalizing to uppercase so downstream path brute-forcing and result strings agree. This fixes the carve path too —_carve_re_normalcaptures the generator as(\w+), so a lowercase generator in markup was equally affected.Docs: the URL is a real constraint, not a bug
DOTNET45 derives the validation key from the page path via the SP800-108 KDF purposes, and DOTNET40 with
IsolateAppsmixes in an app-path hash. Neither can be validated without the URL — no code change fixes that. Added a README section covering the four positional arguments and why--urlsucceeds where passing the viewstate and generator alone does not, since the CLI'sNo secrets found :(is identical whether the key genuinely isn't in the list or the URL simply wasn't supplied.Notes
Not a regression — both defects predate the module's move in
6a9ac67(2026-03-01).One tradeoff: an 8-character lowercase hex string intended as a
ViewStateUserKey(e.g.deadbeef) now resolves as a generator. That ambiguity already existed for uppercase and is inherent to detecting arguments by shape; real ASP.NET session IDs are 24 characters, so a collision is unlikely but not impossible.Three regression tests added. Full suite passes (501 tests).