[GH-ISSUE #6252] [Bug] CLI parser diagnostics repeat literals declared with --sensitive-value #3799

Closed
opened 2026-10-31 00:44:11 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @coygeek on GitHub (Oct 22, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/6252

Originally assigned to: @kaoru0822-kitauji on GitHub.

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

CLI

Observed behavior

Parser failures in inspect-web-network-capture repeat a literal declared with --sensitive-value. A malformed negated flag reproduces with valid JSON output, independently of output-format selection. Invalid global format and token-limit values also repeat the declaration. The command's normal file-read failure and an ordinary unknown flag omit the same literal.

Each of the three failing variants was run twice, once in the initial isolated probe and once through the reproduction block below. All six emitted the declared literal to stdout, exited 1, and produced empty stderr. Both controls ran twice and omitted the literal from stdout and stderr. No TTY run or published-package rerun was performed by this reviewer.

Reproduction

From the source checkout, after installing its locked dependencies and running npm run build:cached, select the Node version stated below and run this Python block. It invokes the public executable with captured stdout, isolated HOME/DSH_HOME/XDG/TMPDIR directories, a nonexistent capture, and a harmless synthetic literal. No target, external endpoint, provider, or real credential is required.

python3 - <<'PY'
from pathlib import Path
import os
import shutil
import subprocess
import tempfile

entry = Path('scripts/rea.mjs').resolve()
node = shutil.which('node')
marker = 'SYNTHETIC_CAPTURE_LITERAL_83A4'
common = ['inspect-web-network-capture', 'missing.har', 'har',
          '--sensitive-value', marker]
cases = [
    ('negated-unknown', common + ['--no-unknown-option=' + marker, '--json']),
    ('invalid-format', common + ['--format', marker]),
    ('invalid-token-limit', common + ['--token-limit', marker]),
    ('ordinary-unknown', common + ['--unknown-option=' + marker, '--json']),
    ('service-failure', ['inspect-web-network-capture', marker + '.har', 'har',
                         '--sensitive-value', marker, '--json']),
]
with tempfile.TemporaryDirectory() as temporary:
    root = Path(temporary)
    env = {'PATH': os.defpath, 'NO_COLOR': '1'}
    for key in ['HOME', 'DSH_HOME', 'XDG_CONFIG_HOME', 'XDG_CACHE_HOME',
                'XDG_DATA_HOME', 'XDG_STATE_HOME', 'XDG_RUNTIME_DIR', 'TMPDIR']:
        directory = root / key
        directory.mkdir()
        env[key] = str(directory)
    for name, arguments in cases:
        result = subprocess.run([node, str(entry), *arguments], cwd=root,
                                env=env, capture_output=True, text=True, timeout=30)
        print(name, 'exit=', result.returncode,
              'declared_literal_in_stdout=', marker in result.stdout,
              'stderr_empty=', result.stderr == '')
        if name == 'negated-unknown':
            print(result.stdout, end='')
PY

Expected behavior

The capture documentation explicitly applies CLI --sensitive-value declarations to failure messages and diagnostics, and the repository redaction rule requires redaction of explicitly marked sensitive values. The named input contract includes diagnostic text in the excluded outputs. For a valid declaration on the supported inspection command, a parser rejection should retain a useful error and failure status without repeating that literal. No new confidential input channel or pattern-based secret detection is requested.

Impact and scope

P2: a bounded violation of the existing explicit diagnostic exclusion rule. The observed failure is an existing caller-selected redaction rule being skipped before command dispatch. The caller receives its own declared literal in stdout for the three malformed invocations. If that output is recorded or shared, the literal remains present in it. No real secret, shared log, unauthorized recipient, attacker-controlled victim invocation, or transmission was used or demonstrated. Correctly parsed file-read failure diagnostics do redact the literal. No claim of a confirmed exploitable vulnerability is made.

No practical workaround preserving malformed-input diagnostics was verified. TTY behavior, other platforms, real-secret use, and real shared-log access remain untested.

REA version

REA 6.7.0, freshly built from source commit bd5d189a8f8aeea669bcb93e68af6c046b567939, with lockfile-pinned Incur 0.6.1.

Runtime and platform

Node.js v24.22.0 on macOS 27.0.1 arm64. The repository pins Node.js v24.18.0; that exact version was not found in the checked installed locations. The executed Node version satisfies the package engines range but differs from the development pin. No provider was used. GitHub releases and the npm latest tag both identify 6.7.0 as the current published version. The published package was not independently rerun in this review.

Target and artifact context

No target was opened. A nonexistent capture pathname exercises parsing and the file-read failure control; the only declared value is a synthetic literal.

Interface

CLI

Earliest failure stage

Request parsing or validation

Relevant output or evidence

Output from the independently executed reproduction block:

negated-unknown exit= 1 declared_literal_in_stdout= True stderr_empty= True
{
  "code": "UNKNOWN",
  "message": "Unknown flag: --no-unknown-option=SYNTHETIC_CAPTURE_LITERAL_83A4"
}
invalid-format exit= 1 declared_literal_in_stdout= True stderr_empty= True
invalid-token-limit exit= 1 declared_literal_in_stdout= True stderr_empty= True
ordinary-unknown exit= 1 declared_literal_in_stdout= False stderr_empty= True
service-failure exit= 1 declared_literal_in_stdout= False stderr_empty= True

The initial isolated probe independently retained the same literal and failure status for the three parser failures. The two controls omitted it in both runs. The previous candidate supplied the lead; the counts above describe this review's own executions.

Typed outcome or recovery expected

Retain rejection, failure status, and a useful malformed-option diagnostic while excluding accepted explicit-sensitive declarations from stdout and stderr. Keep the negated-flag case's valid JSON and both controls' existing exclusion behavior. A fix has not been implemented or verified.

Analysis or suspected cause

Source-derived: the CLI declaration mapping passes declarations to the application only after command parsing; the service failure redaction applies them to application failures. Incur's pinned parser throws on an unknown --no-... token before its ordinary equals-value branch, including the whole token in that diagnostic (node_modules/incur/src/Parser.ts:24-36). Its global option parser also interpolates invalid format and token-limit values (node_modules/incur/src/Cli.ts:2809-2813,2836-2839). This locates the early diagnostic gap without prescribing a repair.

Additional context

Prepared with AI assistance and independently verified through the public CLI. Issue #5531 concerns output-format selection; this report's primary negated-flag case already emits valid JSON. Bounded open/closed issue and PR searches found no same-failure report. PR #2477 corrected explicit exclusions in capture byte counts rather than CLI parsing; #4398 and #5485 request new export/support audits. Those reports have different closure signals.

Originally created by @coygeek on GitHub (Oct 22, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/6252 Originally assigned to: @kaoru0822-kitauji on GitHub. ### Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area CLI ### Observed behavior Parser failures in `inspect-web-network-capture` repeat a literal declared with `--sensitive-value`. A malformed negated flag reproduces with valid JSON output, independently of output-format selection. Invalid global format and token-limit values also repeat the declaration. The command's normal file-read failure and an ordinary unknown flag omit the same literal. Each of the three failing variants was run twice, once in the initial isolated probe and once through the reproduction block below. All six emitted the declared literal to stdout, exited 1, and produced empty stderr. Both controls ran twice and omitted the literal from stdout and stderr. No TTY run or published-package rerun was performed by this reviewer. ### Reproduction From the source checkout, after installing its locked dependencies and running `npm run build:cached`, select the Node version stated below and run this Python block. It invokes the public executable with captured stdout, isolated HOME/DSH_HOME/XDG/TMPDIR directories, a nonexistent capture, and a harmless synthetic literal. No target, external endpoint, provider, or real credential is required. ```sh python3 - <<'PY' from pathlib import Path import os import shutil import subprocess import tempfile entry = Path('scripts/rea.mjs').resolve() node = shutil.which('node') marker = 'SYNTHETIC_CAPTURE_LITERAL_83A4' common = ['inspect-web-network-capture', 'missing.har', 'har', '--sensitive-value', marker] cases = [ ('negated-unknown', common + ['--no-unknown-option=' + marker, '--json']), ('invalid-format', common + ['--format', marker]), ('invalid-token-limit', common + ['--token-limit', marker]), ('ordinary-unknown', common + ['--unknown-option=' + marker, '--json']), ('service-failure', ['inspect-web-network-capture', marker + '.har', 'har', '--sensitive-value', marker, '--json']), ] with tempfile.TemporaryDirectory() as temporary: root = Path(temporary) env = {'PATH': os.defpath, 'NO_COLOR': '1'} for key in ['HOME', 'DSH_HOME', 'XDG_CONFIG_HOME', 'XDG_CACHE_HOME', 'XDG_DATA_HOME', 'XDG_STATE_HOME', 'XDG_RUNTIME_DIR', 'TMPDIR']: directory = root / key directory.mkdir() env[key] = str(directory) for name, arguments in cases: result = subprocess.run([node, str(entry), *arguments], cwd=root, env=env, capture_output=True, text=True, timeout=30) print(name, 'exit=', result.returncode, 'declared_literal_in_stdout=', marker in result.stdout, 'stderr_empty=', result.stderr == '') if name == 'negated-unknown': print(result.stdout, end='') PY ``` ### Expected behavior The [capture documentation](https://github.com/morluto/rea/blob/bd5d189a8f8aeea669bcb93e68af6c046b567939/docs/web-network-captures.md#L274-L289) explicitly applies CLI `--sensitive-value` declarations to failure messages and diagnostics, and the [repository redaction rule](https://github.com/morluto/rea/blob/bd5d189a8f8aeea669bcb93e68af6c046b567939/AGENTS.md#L13) requires redaction of explicitly marked sensitive values. The [named input contract](https://github.com/morluto/rea/blob/bd5d189a8f8aeea669bcb93e68af6c046b567939/src/domain/webNetworkCapture.ts#L64-L69) includes diagnostic text in the excluded outputs. For a valid declaration on the supported inspection command, a parser rejection should retain a useful error and failure status without repeating that literal. No new confidential input channel or pattern-based secret detection is requested. ### Impact and scope P2: a bounded violation of the existing explicit diagnostic exclusion rule. The observed failure is an existing caller-selected redaction rule being skipped before command dispatch. The caller receives its own declared literal in stdout for the three malformed invocations. If that output is recorded or shared, the literal remains present in it. No real secret, shared log, unauthorized recipient, attacker-controlled victim invocation, or transmission was used or demonstrated. Correctly parsed file-read failure diagnostics do redact the literal. No claim of a confirmed exploitable vulnerability is made. No practical workaround preserving malformed-input diagnostics was verified. TTY behavior, other platforms, real-secret use, and real shared-log access remain untested. ### REA version REA 6.7.0, freshly built from source commit `bd5d189a8f8aeea669bcb93e68af6c046b567939`, with lockfile-pinned Incur 0.6.1. ### Runtime and platform Node.js v24.22.0 on macOS 27.0.1 arm64. The repository pins Node.js v24.18.0; that exact version was not found in the checked installed locations. The executed Node version satisfies the package engines range but differs from the development pin. No provider was used. GitHub releases and the npm latest tag both identify 6.7.0 as the current published version. The published package was not independently rerun in this review. ### Target and artifact context No target was opened. A nonexistent capture pathname exercises parsing and the file-read failure control; the only declared value is a synthetic literal. ### Interface CLI ### Earliest failure stage Request parsing or validation ### Relevant output or evidence Output from the independently executed reproduction block: ```text negated-unknown exit= 1 declared_literal_in_stdout= True stderr_empty= True { "code": "UNKNOWN", "message": "Unknown flag: --no-unknown-option=SYNTHETIC_CAPTURE_LITERAL_83A4" } invalid-format exit= 1 declared_literal_in_stdout= True stderr_empty= True invalid-token-limit exit= 1 declared_literal_in_stdout= True stderr_empty= True ordinary-unknown exit= 1 declared_literal_in_stdout= False stderr_empty= True service-failure exit= 1 declared_literal_in_stdout= False stderr_empty= True ``` The initial isolated probe independently retained the same literal and failure status for the three parser failures. The two controls omitted it in both runs. The previous candidate supplied the lead; the counts above describe this review's own executions. ### Typed outcome or recovery expected Retain rejection, failure status, and a useful malformed-option diagnostic while excluding accepted explicit-sensitive declarations from stdout and stderr. Keep the negated-flag case's valid JSON and both controls' existing exclusion behavior. A fix has not been implemented or verified. ### Analysis or suspected cause Source-derived: the [CLI declaration mapping](https://github.com/morluto/rea/blob/bd5d189a8f8aeea669bcb93e68af6c046b567939/src/cli/webNetworkCaptureCommands.ts#L57-L78) passes declarations to the application only after command parsing; the [service failure redaction](https://github.com/morluto/rea/blob/bd5d189a8f8aeea669bcb93e68af6c046b567939/src/application/WebNetworkCaptureService.ts#L49-L57) applies them to application failures. Incur's pinned parser throws on an unknown `--no-...` token before its ordinary equals-value branch, including the whole token in that diagnostic (`node_modules/incur/src/Parser.ts:24-36`). Its global option parser also interpolates invalid format and token-limit values (`node_modules/incur/src/Cli.ts:2809-2813,2836-2839`). This locates the early diagnostic gap without prescribing a repair. ### Additional context Prepared with AI assistance and independently verified through the public CLI. [Issue #5531](https://github.com/morluto/rea/issues/5531) concerns output-format selection; this report's primary negated-flag case already emits valid JSON. Bounded open/closed issue and PR searches found no same-failure report. [PR #2477](https://github.com/morluto/rea/pull/2477) corrected explicit exclusions in capture byte counts rather than CLI parsing; #4398 and #5485 request new export/support audits. Those reports have different closure signals.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#3799
No description provided.