T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/invoke_vnstock.py:58
- Finding
- Unrestricted Dynamic Invocation Enables Arbitrary Local Command Execution<![CDATA[ ## Vulnerability Details **File Location**: `scripts/invoke_vnstock.py:58-94` **Vulnerability Type**: Unrestricted dynamic import and method invocation **Risk Level**: Critical ### Vulnerable Code ```python parser.add_argument("--module", default="vnstock", help="Module path containing class, default vnstock") parser.add_argument("--class-name", required=True, help="vnstock exported class name, e.g. Quote") parser.add_argument("--init-kwargs", default="{}", help="JSON object for class initialization kwargs") parser.add_argument("--method", required=True, help="Method name to call") parser.add_argument("--method-args", default="[]", help="JSON array for positional method args") parser.add_argument("--method-kwargs", default="{}", help="JSON object for method kwargs") parser.add_argument("--outdir", default="./outputs", help="Output directory") parser.add_argument("--min-interval-sec", type=float, default=3.2, help="Optional pacing for free-tier safety") parser.add_argument("--api-key", default="", help="Optional VNStock API key override") args = parser.parse_args() init_kwargs = parse_json_arg(args.init_kwargs, "init-kwargs") method_args = parse_json_list_arg(args.method_args, "method-args") method_kwargs = parse_json_arg(args.method_kwargs, "method-kwargs") configure_vnstock_api_key(args.api_key or None) mod = importlib.import_module(args.module) if not hasattr(mod, args.class_name): raise AttributeError(f"Class not found in module {args.module}: {args.class_name}") cls = getattr(mod, args.class_name) client = cls(**init_kwargs) if not hasattr(client, args.method): raise AttributeError(f"Method not found on {args.class_name}: {args.method}") method = getattr(client, args.method) limiter = RateLimiter(min_interval_sec=args.min_interval_sec) limiter.wait() result = method(*method_args, **method_kwargs) ``` ### Technical Analysis The command-line caller controls the imported module, selected class, constructor arguments, method name, ...[truncated 1887 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove the `--module` option and import only the expected `vnstock` package. 2. Define explicit allowlists of supported VNStock classes and methods, for example: - `Quote`: `history` - `Listing`: approved listing methods - `Company`: approved company-information methods - `Finance`: approved financial-statement methods 3. Reject private members, inherited utility methods, and all methods absent from the allowlist. 4. Validate constructor and method arguments against per-method schemas rather than accepting arbitrary JSON objects and arrays. 5. Reject callable objects that do not originate from approved `vnstock` modules. 6. Run provider operations in a sandboxed subprocess with restricted filesystem access, network destinations, environment variables, and resource limits. 7. Add negative tests confirming that modules such as `subprocess`, `os`, `pathlib`, and `builtins` cannot be imported or invoked. ]]>
