T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:23
- Finding
- Bearer Tokens and Private UseMemos Content Can Be Transmitted over Plaintext HTTP<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:23-29`; `README.md:31-38`; network requests in `scripts/create_memo.py:32-44`, `scripts/list_memos.py:30-41`, `scripts/search_memos.py:38-49`, `scripts/memo_comments.py:27-39`, `scripts/upload_attachment.py:40-52`, `scripts/upload_and_link_attachment.py:53-61,76-83,102-110`, and `tests/test_image_upload.py:80-112` **Vulnerability Type**: Plaintext transmission of bearer credentials and private content **Risk Level**: High The documented configuration explicitly permits and demonstrates unencrypted HTTP: ```text Create a `.env` file in the skill directory (`skills/usememos/.env`): ``` ```text USEMEMOS_URL=http://192.168.0.157:5230 USEMEMOS_TOKEN=your_access_token_here ``` The same documentation recommends a token without expiration: ```text Get your `USEMEMOS_TOKEN` from UseMemos instance, login and go to: Settings > My Account > Access Tokens, create one there, do not forget to assign expiration (i use Never to avoid troubles, but hey there are also arguments against that) ``` The scripts then send that bearer token and user data directly to the configured URL without validating its scheme. For example, `scripts/upload_attachment.py:40-52` contains: ```python req = urllib.request.Request( f"{base_url}/api/v1/attachments", data=payload, headers={ 'Authorization': f'Bearer {token}', 'Content-Type': 'application/json', 'Accept': 'application/json' }, method='POST' ) try: with urllib.request.urlopen(req) as resp: data = json.loads(resp.read().decode()) ``` Similarly, the common request logic in `scripts/memo_comments.py:27-39` is: ```python def api_request(base_url, token, path, method='GET', data=None): body = json.dumps(data).encode() if data else None req = urllib.request.Request( f"{base_url}{path}", data=body, headers={ 'Authorization': f'Bearer {token}', 'Content-Type': 'appli ...[truncated 3059 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Require HTTPS by default** - Parse `USEMEMOS_URL` with `urllib.parse.urlsplit`. - Accept only `https` for normal deployments. - Reject missing, malformed, or unsupported URL schemes before constructing requests. 2. **Restrict plaintext HTTP to explicit local exceptions** - If loopback development must remain supported, allow HTTP only for `localhost`, `127.0.0.1`, or `::1`. - For other HTTP destinations, require an explicit option such as `USEMEMOS_ALLOW_INSECURE_HTTP=true`. - Emit a prominent warning when this exception is enabled. 3. **Enforce a safe redirect policy** - Disable automatic redirects for authenticated API requests, or permit them only when the destination retains the original HTTPS scheme, host, and effective port. - Never forward the `Authorization` header across origins. - Reject HTTPS-to-HTTP downgrade redirects. 4. **Improve token guidance** - Remove the recommendation to select a `Never` expiration. - Recommend short-lived, revocable, least-privilege access tokens. - Document token rotation and immediate revocation after suspected exposure. 5. **Protect local token storage** - Advise users to set restrictive permissions, such as `chmod 600 .env`. - Ensure `.env` is excluded from version control and packaged releases. - Prefer a platform secret store or injected environment variable where available. 6. **Update examples** - Replace all non-loopback HTTP examples with `https://` URLs. - Clearly state that Base64 is only an API encoding and does not protect attachment confidentiality. ]]>
