Skip to content

fix(android): validate launch component names and guard the executor override - #3366

Merged
thymikee merged 3 commits into
mainfrom
security/2026-10-10-android-component-hardening
Oct 10, 2026
Merged

thymikee merged 3 commits into
mainfrom
security/2026-10-10-android-component-hardening

Conversation

@thymikee

@thymikee thymikee commented Oct 10, 2026 •

Copy link
Copy Markdown
Member

Summary

Defense-in-depth hardening for Android and HarmonyOS app launch. Device-shell words were already quoted; this adds input validation and closes the one adb executor that skipped the device-shell guard.

  • Android activity overrides must match the am start -n grammar: <package>/<Class>, .<Class>, or <Class>. Package segments start with a letter; class segments are Java identifiers. Anything else, empty included, is refused with INVALID_ARGS / invalid-android-activity-component before any adb call. openAndroidApp and openAndroidAppWithAdb share one androidActivityComponent.
  • HarmonyOS --activity must be a module.json5 ability name; otherwise invalid-harmony-ability-name before any hdc call.
  • The provider-scope executor override now goes through guardDeviceShell. To support this, serializeAndroidAdbInvocation keeps a checked command recognised when it prepends -P/-s, using the new kernel helper relayDeviceShellArgvWithOptions.
  • --activity help lists the accepted forms.

17 files. Scope extends to @agent-device/kernel (the relay helper) and five test recorders adjusted for the readonly argv.

Validation

  • pnpm check:affected --run on 43cafaa7e: passed (735 files, 6290 tests).
  • Mutation checks: removing the override guard fails the override refusal test; removing activity validation fails the Android open and app-control tests.
  • No live device run. Malformed input is refused before anything reaches the device, and existing provider-backed integration tests still cover valid launches.

🤖 Generated with Claude Code

thymikee and others added 2 commits October 10, 2026 13:23
…override

Refuse an Android `--activity` value outside the `am start -n` component
grammar and a HarmonyOS ability name outside the module.json5 grammar with
typed INVALID_ARGS reasons before any device call. Route the provider-scope
command executor override through the same device-shell guard as the other
adb executors.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The provider-scope executor override now refuses an unminted device-shell
argv. Lowering a typed invocation to argv prepends its `-P`/`-s` addressing,
so serialization relays the minted command through
`relayDeviceShellArgvWithOptions` instead of copying it, and the host route's
argv reaches the override still minted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Size Report

Metric Base Current Diff
Installed (including dependencies) 5.15 MB 5.15 MB -2.0 kB
Package (unpacked) 5.15 MB 5.15 MB -2.0 kB
Package (download) 1.55 MB 1.55 MB -641 B

Startup median (7 runs, lower is better):

Scenario Base Current Diff
CLI --version 28.8 ms 27.5 ms -1.3 ms
CLI --help 83.4 ms 85.7 ms +2.2 ms

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 15 files

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

Comment thread packages/platform-android/src/app-lifecycle.ts Outdated
Comment thread packages/platform-harmonyos/src/app-lifecycle.ts Outdated
Comment thread packages/platform-android/src/adb-provider-scope.ts
Comment thread packages/platform-android/src/app-lifecycle.ts Outdated
Comment thread packages/command-registry/src/flag-definitions-target.ts Outdated
Both Android launch paths now build the `am start -n` component through one
`androidActivityComponent`, so `openAndroidAppWithAdb` refuses a malformed
activity the same way `openAndroidApp` does. The grammar checks identifier
segments, and an explicitly empty activity or HarmonyOS ability is refused
rather than treated as absent.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@thymikee

Copy link
Copy Markdown
Member Author

This PR is ready at 43cafaa. The change looks correct, and all 19 checks pass on that commit. There are no conflicts, and nothing else needs to happen before merge.

Not blocking: no test sends a minted command through serializeAndroidAdbInvocation into the guarded override, so reverting line 359 to [...serialized, ...command] would probably keep every test green while leased-provider shell commands get refused (a test in adb-transport.test.ts that passes the serialized and managed -P forms of a minted shell id through assertDeviceShellArgv would close it), and relayDeviceShellArgvWithOptions mints any words prepended, so its options could stay typed to transport options or the doc could say callers pass only those; take or leave both.

The cubic-dev-ai threads on empty or malformed package segments (r4237483992), the HarmonyOS !== undefined check (r4237483998), the empty --activity check (r4237484003) and the activity flag help text (r4237484006) are fixed at this head, so you can resolve them. The thread on pull shell out (r4237484001) does not apply, because src/platform-runtime-android-adb-host.ts already refuses it before runCmd reaches the override, so you can resolve it too.

I read the code and did not run it. I did not run a mutation, so the revert claim above comes from reading the tests. There was no live run: valid launches emit the same bytes as before, and the one new failure mode on the override route is mint propagation, which I checked by reading. A leased Limrun run would confirm it end to end. Two behavior changes may deserve a CHANGELOG line, which I did not check for: an empty --activity is now refused instead of ignored, and an invalid activity on a deep-link open now reports invalid-android-activity-component instead of the activity-not-supported error. Activity names with Unicode Java identifiers are now refused. That is rare, and I did not check it against real apps.

@thymikee thymikee added the ready-for-human Valid work that needs human implementation, judgment, or maintainer merge label Oct 10, 2026
@thymikee
thymikee merged commit 98a7d82 into main Oct 10, 2026
19 checks passed
@thymikee
thymikee deleted the security/2026-10-10-android-component-hardening branch October 10, 2026 13:33
@github-actions

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-10-10 13:34 UTC

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

Labels

ready-for-human Valid work that needs human implementation, judgment, or maintainer merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant