T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/mihomo-cli.sh:82
- Finding
- Bearer Secret Transmitted over Plaintext HTTP to a Configurable Controller<![CDATA[ ## Vulnerability Details **File Location**: `scripts/mihomo-cli.sh`, lines 82-96 **Vulnerability Type**: Plaintext transmission of sensitive authentication credentials **Risk Level**: High ### Vulnerable Code ```bash api_request() { local method="${1:-GET}" local endpoint="$2" local data="${3:-}" local url="http://$MIHOMO_API_HOST$endpoint" local curl_args=(-s) [ -n "$MIHOMO_SECRET" ] && curl_args+=(-H "Authorization: Bearer $MIHOMO_SECRET") if [ "$method" = "GET" ]; then curl "${curl_args[@]}" "$url" else curl "${curl_args[@]}" -X "$method" -H "Content-Type: application/json" "$url" ${data:+-d "$data"} fi } ``` Related controller and credential inputs are accepted from the environment near lines 13-15: ```bash MIHOMO_CONFIG_PATH="${MIHOMO_CONFIG:-}" MIHOMO_API_HOST="${MIHOMO_HOST:-127.0.0.1:9090}" MIHOMO_SECRET="${MIHOMO_SECRET:-}" ``` The controller may also be supplied through command-line options near lines 228-231: ```bash -h|--host) MIHOMO_API_HOST="$2" shift 2 ;; ``` ### Technical Analysis Every API URL is constructed with the fixed `http://` scheme. When a Mihomo secret is available, the script adds it to the request as an `Authorization: Bearer` header. This is reasonably safe from passive network interception when the destination is strictly a loopback interface, but the script does not enforce that restriction. `MIHOMO_API_HOST` may be populated from the `MIHOMO_HOST` environment variable, the `--host` command-line option, or an `external-controller` value extracted from a detected configuration file. Consequently, the bearer secret can be sent over an unencrypted network connection to a non-loopback controller. There is no HTTPS support, certificate verification policy, non-loopback warning, or refusal to transmit credentials over plaintext HTTP. Reading and using the secret is necessary for authenticated Mihomo administration, but transmitting it without transpor ...[truncated 1825 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Enforce a loopback destination by default.** Accept only `127.0.0.1`, `localhost`, or `[::1]` unless the user explicitly enables remote-controller access. 2. **Refuse plaintext credential transmission to non-loopback hosts.** If a secret is configured and the destination is remote, terminate with an error rather than sending the bearer header over HTTP. 3. **Support HTTPS for remote controllers.** Allow a complete controller URL or a separate scheme setting, and retain curl's certificate and hostname verification defaults. 4. **Do not introduce insecure TLS bypasses.** Avoid `curl -k` or `--insecure`. If private certificate authorities are required, provide an explicit CA-file option. 5. **Require explicit remote-access consent.** Add a clearly named option such as `--allow-remote-controller`, ideally combined with mandatory HTTPS. 6. **Validate controller input.** Parse and validate the scheme, host, port, and allowed characters instead of concatenating an unrestricted value into a URL. 7. **Document the trust boundary.** State that environment variables, command-line controller values, and `external-controller` configuration entries determine where the bearer credential is sent. 8. **Reduce command-line secret exposure.** Prefer protected configuration files, standard input, or a credential store over `--secret`, since command-line arguments may be visible in shell history or process listings. ]]>
