Skip to content

fix ASP.NET viewstate CLI argument handling - #436

Open
liquidsec wants to merge 1 commit into
devfrom
fix/viewstate-cli-args
Open

fix ASP.NET viewstate CLI argument handling#436
liquidsec wants to merge 1 commit into
devfrom
fix/viewstate-cli-args

Conversation

@liquidsec

Copy link
Copy Markdown
Collaborator

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 truncated the 4th positional

check_all_modules slices args[0:x.check_secret_args], and ASPNET_Viewstate declared 3. But check_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:

vs+gen+userkey      : SecretFound      ← works (3 args)
vs+gen+url+userkey  : NO SECRET        ← 4th arg silently discarded

Raised to 4.

Generator matching was uppercase-only

_generator_pattern was ^[A-F0-9]{8}$. A lowercase generator didn't merely fail to parse — it fell through to the ViewStateUserKey branch, leaving the generator at its "0000" default and checking the wrong thing entirely, then reporting No secrets found :(:

gen='9BD98A7D'  →  ('9BD98A7D', None, None)     crack: True
gen='9bd98a7d'  →  ('0000', None, '9bd98a7d')   crack: False

Now case-insensitive, with resolve_args canonicalizing to uppercase so downstream path brute-forcing and result strings agree. This fixes the carve path too — _carve_re_normal captures 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 IsolateApps mixes 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 --url succeeds where passing the viewstate and generator alone does not, since the CLI's No 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).

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-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.47%. Comparing base (5a4ebdf) to head (4a0fb21).

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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants