T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/dt_helper.sh:79
- Finding
- Insecure File Permissions for Stored DingTalk Credentials and Access Tokens<![CDATA[ ## Vulnerability Details **File Location**: `scripts/dt_helper.sh:8`, `scripts/dt_helper.sh:79-88`, `scripts/dt_helper.sh:140-141`, and `scripts/dt_helper.sh:198-199` **Vulnerability Type**: Plaintext sensitive-data storage with permissions inherited from the process environment **Risk Level**: Medium ### Vulnerable Code ```bash CONFIG="${DINGTALK_CONFIG:-$HOME/.dingtalk-skills/config}" ``` ```bash cfg_set() { local key="$1" local value="$2" mkdir -p "$(dirname "$CONFIG")" touch "$CONFIG" if grep -q "^${key}=" "$CONFIG" 2>/dev/null; then sed -i "s|^${key}=.*|${key}=${value}|" "$CONFIG" else echo "${key}=${value}" >> "$CONFIG" fi } ``` ```bash cfg_set DINGTALK_ACCESS_TOKEN "$token" cfg_set DINGTALK_TOKEN_EXPIRY "$((now + expire_in - 200))" ``` ```bash cfg_set DINGTALK_OLD_TOKEN "$token" cfg_set DINGTALK_OLD_TOKEN_EXPIRY "$((now + expires_in - 200))" ``` ### Technical Analysis The helper stores the DingTalk application secret and reusable access tokens in a plaintext configuration file. When the file and its parent directory are created, the script does not set a restrictive `umask`, assign explicit permissions, or verify the security of an existing configuration path. Consequently, the effective permissions depend on the environment in which the script runs. For example, under a conventional `umask 022`, `touch "$CONFIG"` can create a file readable by other local users. The parent directory may likewise be created without owner-only access. The stored values include: - `DINGTALK_APP_SECRET` - `DINGTALK_ACCESS_TOKEN` - `DINGTALK_OLD_TOKEN` These values can authorize calls to DingTalk document, workspace, contact, or other APIs according to the permissions granted to the application. ### Attack Path 1. A user or Agent invokes `dt_helper.sh --set` or a token command in an environment with permissive default file-creation permissions. 2. `cfg_set` creates `$HOME/.dingtalk-skills/config` using `touch`, without applying owne ...[truncated 1153 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Apply restrictive permissions before creating any credential file: ```bash umask 077 mkdir -p -m 700 "$(dirname "$CONFIG")" touch "$CONFIG" chmod 600 "$CONFIG" ``` 2. Validate existing paths before using them: - Reject symbolic links. - Confirm that the configuration is a regular file. - Confirm that the file and parent directory are owned by the current user. - Reject group-readable or world-readable permissions. 3. Write configuration changes atomically: - Create a temporary file in the same protected directory. - Set mode `600`. - Write and validate the complete configuration. - Atomically rename it over the original file. 4. Prefer an operating-system credential store or dedicated secret manager for the application secret and long-lived credentials. 5. Minimize token lifetime and cached scope where DingTalk supports it. Clear cached tokens when they are no longer required. ]]>
