T09 · Insecure Skill Coding Practices
- Location
- scripts/backup.py:56
- Finding
- Credential-bearing configuration is archived and uploaded without encryption<![CDATA[ ## Vulnerability Details **File Location**: `scripts/backup.py:56-62`, `scripts/backup.py:270-299`, `scripts/backup.py:488-505` **Vulnerability Type**: Plaintext storage and transmission of sensitive configuration **Risk Level**: High ### Vulnerable Code ```python { 'path': os.path.join(OPENCLAW_ROOT, 'openclaw.json'), 'arcname': 'openclaw/openclaw.json', 'required': False, 'label': '主配置 openclaw.json', }, ``` ```python with tarfile.open(backup_path, 'w:gz') as tar: if include_defaults and not source_dir: print('🧩 使用默认备份清单:workspace + 基础配置') manifest = [] for item in DEFAULT_BACKUP_ITEMS: item_path = Path(item['path']).expanduser() if item_path.exists(): added = add_path_to_tar( tar, item_path, item['arcname'], DEFAULT_EXCLUDE_PATTERNS ) ``` ```python remote_url = WEBDAV_URL.rstrip('/') + '/' + remote_name ensure_webdav_directory() opener = create_webdav_opener() try: with open(local_file, 'rb') as f: data = f.read() req = urllib.request.Request( remote_url, data=data, method='PUT' ) req.add_header('Content-Type', 'application/octet-stream') ``` ### Technical Analysis The default backup set includes `~/.openclaw/openclaw.json`. The Skill documentation also recommends storing `WEBDAV_URL`, `WEBDAV_USERNAME`, and `WEBDAV_PASSWORD` in that file. As a result, a default backup can contain the same credentials used to access its remote backup destination, along with other sensitive OpenClaw configuration. The archive uses gzip compression but no encryption. It is retained locally or uploaded as an ordinary `tar.gz` file. Anyone who obtains the archive can extract its contents without an additional secret. The code does not explicitly restrict local archive permissions to owner-only access. Effective permissions therefore d ...[truncated 1637 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not archive the live `openclaw.json` by default when it may contain credentials. 2. Generate a sanitized configuration copy that removes passwords, tokens, cookies, private keys, and other secret fields before adding it to the archive. 3. Add an explicit opt-in option for including secrets, accompanied by a clear warning. 4. Encrypt every archive before local retention or upload using authenticated encryption. Obtain the encryption key from a separate secret source rather than storing it in the archived configuration. 5. Create local archives with owner-only permissions, such as mode `0600`, and verify that the output directory is not accessible to other users. 6. Reject non-HTTPS WebDAV URLs unless the host is a verified loopback address and the user explicitly permits local cleartext transport. 7. Recommend a dedicated, least-privilege WebDAV account restricted to the backup directory. 8. Document that exposure of an existing backup containing credentials requires immediate credential rotation. ]]>
