T09 · Insecure Skill Coding Practices
- Location
scripts/beam_transfer.py:394- Finding
Transfer Execution Does Not Enforce the Documented User Confirmation Gate
- Content
View full analysis
Vulnerability Details
File Location:
scripts/beam_transfer.py:394-407
Vulnerability Type: Missing authorization confirmation for a destructive, credit-consuming operation
Risk Level: MediumCode Snippet:
python async def cmd_run(args: argparse.Namespace) -> int: spec = build_spec(args) if args.dry_run: emit("plan", **spec.describe(), name=args.name, timeout_seconds=args.timeout) return EXIT_OK api_key = require_api_key() transfer_id = "" async with beam_client(api_key) as beam: try: try: prepared = await beam.transfers.create_transfer( sources=[spec.source_model], destinations=spec.destination_models, name=args.name, )Technical Analysis
The Skill documentation requires the Agent to disclose the source, all destinations, overwrite risk, object size, and estimated credit cost, and then obtain user agreement before starting a transfer (
SKILL.md:114-117). The executable helper does not enforce that authorization requirement.When the
runsubcommand is invoked without the optional--dry-runflag,cmd_run()immediately constructs the transfer specification, obtainsBEAM_API_KEY, and callsbeam.transfers.create_transfer(). There is no required confirmation flag, approved-plan identifier, interactive prompt, or validation that an estimate was previously shown and accepted.The relevant inputs are the caller-supplied
--sourceand repeated--destarguments. These determine which object is read and which destination objects are written. Because the helper can be invoked directly by an Agent or another local caller, the prose-only confirmation instruction does not form a technical authorization boundary.The presence of
--dry-rundoes not prevent this path: it is optional, and omitting it selects the live transfer path....[truncated 1379 chars]
- Remediation
View remediation
Remediation Suggestions
Enforce authorization in the executable helper rather than relying exclusively on Agent instructions:
- Make live execution require an explicit flag such as
--confirmed. - Have
estimateor--dry-runproduce a cryptographically bound plan containing the normalized source, all normalized destinations, object size, estimated credits, overwrite warning, and a short expiration time. - Require
runto receive the approved plan or its digest and reject execution if the current arguments differ from the approved values. - Display the exact destination keys and overwrite implications before approval.
- Consider an optional maximum-credit limit and reject transfers whose estimate exceeds it.
- Preserve a non-interactive mode for automation only when it supplies an explicit confirmation artifact or policy-approved limit.
- Apply the same authorization design to other consequential operations, while retaining the documented requirement that cancellation occur only at the user's request.
- Make live execution require an explicit flag such as
