T09 · Insecure Skill Coding Practices
- Location
SKILL.md:39- Finding
OAuth authorization flow does not generate or validate a session-bound state value
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This TikTok integration is purpose-aligned, but it needs review because it stores long-lived TikTok credentials in a local plaintext file and can publish public content.
Install only if you are comfortable granting TikTok OAuth scopes that can read account data and publish videos. Use the minimum scopes needed, secure ~/.config/tiktok-page/credentials.json with owner-only permissions, avoid shared machines, and revoke or rotate TikTok tokens immediately if the file or host may have been exposed. Treat public posting actions as high impact and confirm the target account, video, caption, and privacy level before running them.
SKILL.md:39OAuth authorization flow does not generate or validate a session-bound state value
SKILL.md:59Credential file permissions are not enforced on macOS and Linux
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
---
name: tiktok-page
description: "TikTok manager: post videos, list content & check account stats. Requires: powershell/pwsh. Reads ~/.config/tiktok-page/credentials.json (TIKTOK_ACCESS_TOKEN, TIKTOK_REFRESH_TOKEN, TIKTOK_CLIENT_KEY, TIKTOK_CLIENT_SECRET, TIKTOK_OPEN_ID). Tokens expire every 24h — auto-refresh via TIKTOK_REFRESH_TOKEN. Grant minimal permissions only. Rotate immediately if host is compromised. No data forwarded; all calls go to open.tiktokapis.com only."
metadata: {"openclaw":{"emoji":"[tt]","requires":{"anyBins":["powershell","pwsh"]}}}
---
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
---
name: tiktok-page
description: "TikTok manager: post videos, list content & check account stats. Requires: powershell/pwsh. Reads ~/.config/tiktok-page/credentials.json (TIKTOK_ACCESS_TOKEN, TIKTOK_REFRESH_TOKEN, TIKTOK_CLIENT_KEY, TIKTOK_CLIENT_SECRET, TIKTOK_OPEN_ID). Tokens expire every 24h — auto-refresh via TIKTOK_REFRESH_TOKEN. Grant minimal permissions only. Rotate immediately if host is compromised. No data forwarded; all calls go to open.tiktokapis.com only."
metadata: {"openclaw":{"emoji":"[tt]","requires":{"anyBins":["powershell","pwsh"]}}}
---
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
---
name: tiktok-page
description: "TikTok manager: post videos, list content & check account stats. Requires: powershell/pwsh. Reads ~/.config/tiktok-page/credentials.json (TIKTOK_ACCESS_TOKEN, TIKTOK_REFRESH_TOKEN, TIKTOK_CLIENT_KEY, TIKTOK_CLIENT_SECRET, TIKTOK_OPEN_ID). Tokens expire every 24h — auto-refresh via TIKTOK_REFRESH_TOKEN. Grant minimal permissions only. Rotate immediately if host is compromised. No data forwarded; all calls go to open.tiktokapis.com only."
metadata: {"openclaw":{"emoji":"[tt]","requires":{"anyBins":["powershell","pwsh"]}}}
---
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
---
name: tiktok-page
description: "TikTok manager: post videos, list content & check account stats. Requires: powershell/pwsh. Reads ~/.config/tiktok-page/credentials.json (TIKTOK_ACCESS_TOKEN, TIKTOK_REFRESH_TOKEN, TIKTOK_CLIENT_KEY, TIKTOK_CLIENT_SECRET, TIKTOK_OPEN_ID). Tokens expire every 24h — auto-refresh via TIKTOK_REFRESH_TOKEN. Grant minimal permissions only. Rotate immediately if host is compromised. No data forwarded; all calls go to open.tiktokapis.com only."
metadata: {"openclaw":{"emoji":"[tt]","requires":{"anyBins":["powershell","pwsh"]}}}
---
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
---
name: tiktok-page
description: "TikTok manager: post videos, list content & check account stats. Requires: powershell/pwsh. Reads ~/.config/tiktok-page/credentials.json (TIKTOK_ACCESS_TOKEN, TIKTOK_REFRESH_TOKEN, TIKTOK_CLIENT_KEY, TIKTOK_CLIENT_SECRET, TIKTOK_OPEN_ID). Tokens expire every 24h — auto-refresh via TIKTOK_REFRESH_TOKEN. Grant minimal permissions only. Rotate immediately if host is compromised. No data forwarded; all calls go to open.tiktokapis.com only."
metadata: {"openclaw":{"emoji":"[tt]","requires":{"anyBins":["powershell","pwsh"]}}}
---
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
---
name: tiktok-page
description: "TikTok manager: post videos, list content & check account stats. Requires: powershell/pwsh. Reads ~/.config/tiktok-page/credentials.json (TIKTOK_ACCESS_TOKEN, TIKTOK_REFRESH_TOKEN, TIKTOK_CLIENT_KEY, TIKTOK_CLIENT_SECRET, TIKTOK_OPEN_ID). Tokens expire every 24h — auto-refresh via TIKTOK_REFRESH_TOKEN. Grant minimal permissions only. Rotate immediately if host is compromised. No data forwarded; all calls go to open.tiktokapis.com only."
metadata: {"openclaw":{"emoji":"[tt]","requires":{"anyBins":["powershell","pwsh"]}}}
---
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
---
name: tiktok-page
description: "TikTok manager: post videos, list content & check account stats. Requires: powershell/pwsh. Reads ~/.config/tiktok-page/credentials.json (TIKTOK_ACCESS_TOKEN, TIKTOK_REFRESH_TOKEN, TIKTOK_CLIENT_KEY, TIKTOK_CLIENT_SECRET, TIKTOK_OPEN_ID). Tokens expire every 24h — auto-refresh via TIKTOK_REFRESH_TOKEN. Grant minimal permissions only. Rotate immediately if host is compromised. No data forwarded; all calls go to open.tiktokapis.com only."
metadata: {"openclaw":{"emoji":"[tt]","requires":{"anyBins":["powershell","pwsh"]}}}
---
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
---
name: tiktok-page
description: "TikTok manager: post videos, list content & check account stats. Requires: powershell/pwsh. Reads ~/.config/tiktok-page/credentials.json (TIKTOK_ACCESS_TOKEN, TIKTOK_REFRESH_TOKEN, TIKTOK_CLIENT_KEY, TIKTOK_CLIENT_SECRET, TIKTOK_OPEN_ID). Tokens expire every 24h — auto-refresh via TIKTOK_REFRESH_TOKEN. Grant minimal permissions only. Rotate immediately if host is compromised. No data forwarded; all calls go to open.tiktokapis.com only."
metadata: {"openclaw":{"emoji":"[tt]","requires":{"anyBins":["powershell","pwsh"]}}}
---
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
---
name: tiktok-page
description: "TikTok manager: post videos, list content & check account stats. Requires: powershell/pwsh. Reads ~/.config/tiktok-page/credentials.json (TIKTOK_ACCESS_TOKEN, TIKTOK_REFRESH_TOKEN, TIKTOK_CLIENT_KEY, TIKTOK_CLIENT_SECRET, TIKTOK_OPEN_ID). Tokens expire every 24h — auto-refresh via TIKTOK_REFRESH_TOKEN. Grant minimal permissions only. Rotate immediately if host is compromised. No data forwarded; all calls go to open.tiktokapis.com only."
metadata: {"openclaw":{"emoji":"[tt]","requires":{"anyBins":["powershell","pwsh"]}}}
---
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
---
name: tiktok-page
description: "TikTok manager: post videos, list content & check account stats. Requires: powershell/pwsh. Reads ~/.config/tiktok-page/credentials.json (TIKTOK_ACCESS_TOKEN, TIKTOK_REFRESH_TOKEN, TIKTOK_CLIENT_KEY, TIKTOK_CLIENT_SECRET, TIKTOK_OPEN_ID). Tokens expire every 24h — auto-refresh via TIKTOK_REFRESH_TOKEN. Grant minimal permissions only. Rotate immediately if host is compromised. No data forwarded; all calls go to open.tiktokapis.com only."
metadata: {"openclaw":{"emoji":"[tt]","requires":{"anyBins":["powershell","pwsh"]}}}
---
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
---
name: tiktok-page
description: "TikTok manager: post videos, list content & check account stats. Requires: powershell/pwsh. Reads ~/.config/tiktok-page/credentials.json (TIKTOK_ACCESS_TOKEN, TIKTOK_REFRESH_TOKEN, TIKTOK_CLIENT_KEY, TIKTOK_CLIENT_SECRET, TIKTOK_OPEN_ID). Tokens expire every 24h — auto-refresh via TIKTOK_REFRESH_TOKEN. Grant minimal permissions only. Rotate immediately if host is compromised. No data forwarded; all calls go to open.tiktokapis.com only."
metadata: {"openclaw":{"emoji":"[tt]","requires":{"anyBins":["powershell","pwsh"]}}}
---
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
---
name: tiktok-page
description: "TikTok manager: post videos, list content & check account stats. Requires: powershell/pwsh. Reads ~/.config/tiktok-page/credentials.json (TIKTOK_ACCESS_TOKEN, TIKTOK_REFRESH_TOKEN, TIKTOK_CLIENT_KEY, TIKTOK_CLIENT_SECRET, TIKTOK_OPEN_ID). Tokens expire every 24h — auto-refresh via TIKTOK_REFRESH_TOKEN. Grant minimal permissions only. Rotate immediately if host is compromised. No data forwarded; all calls go to open.tiktokapis.com only."
metadata: {"openclaw":{"emoji":"[tt]","requires":{"anyBins":["powershell","pwsh"]}}}
---
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
---
name: tiktok-page
description: "TikTok manager: post videos, list content & check account stats. Requires: powershell/pwsh. Reads ~/.config/tiktok-page/credentials.json (TIKTOK_ACCESS_TOKEN, TIKTOK_REFRESH_TOKEN, TIKTOK_CLIENT_KEY, TIKTOK_CLIENT_SECRET, TIKTOK_OPEN_ID). Tokens expire every 24h — auto-refresh via TIKTOK_REFRESH_TOKEN. Grant minimal permissions only. Rotate immediately if host is compromised. No data forwarded; all calls go to open.tiktokapis.com only."
metadata: {"openclaw":{"emoji":"[tt]","requires":{"anyBins":["powershell","pwsh"]}}}
---
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
---
name: tiktok-page
description: "TikTok manager: post videos, list content & check account stats. Requires: powershell/pwsh. Reads ~/.config/tiktok-page/credentials.json (TIKTOK_ACCESS_TOKEN, TIKTOK_REFRESH_TOKEN, TIKTOK_CLIENT_KEY, TIKTOK_CLIENT_SECRET, TIKTOK_OPEN_ID). Tokens expire every 24h — auto-refresh via TIKTOK_REFRESH_TOKEN. Grant minimal permissions only. Rotate immediately if host is compromised. No data forwarded; all calls go to open.tiktokapis.com only."
metadata: {"openclaw":{"emoji":"[tt]","requires":{"anyBins":["powershell","pwsh"]}}}
---
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
---
name: tiktok-page
description: "TikTok manager: post videos, list content & check account stats. Requires: powershell/pwsh. Reads ~/.config/tiktok-page/credentials.json (TIKTOK_ACCESS_TOKEN, TIKTOK_REFRESH_TOKEN, TIKTOK_CLIENT_KEY, TIKTOK_CLIENT_SECRET, TIKTOK_OPEN_ID). Tokens expire every 24h — auto-refresh via TIKTOK_REFRESH_TOKEN. Grant minimal permissions only. Rotate immediately if host is compromised. No data forwarded; all calls go to open.tiktokapis.com only."
metadata: {"openclaw":{"emoji":"[tt]","requires":{"anyBins":["powershell","pwsh"]}}}
---
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
---
name: tiktok-page
description: "TikTok manager: post videos, list content & check account stats. Requires: powershell/pwsh. Reads ~/.config/tiktok-page/credentials.json (TIKTOK_ACCESS_TOKEN, TIKTOK_REFRESH_TOKEN, TIKTOK_CLIENT_KEY, TIKTOK_CLIENT_SECRET, TIKTOK_OPEN_ID). Tokens expire every 24h — auto-refresh via TIKTOK_REFRESH_TOKEN. Grant minimal permissions only. Rotate immediately if host is compromised. No data forwarded; all calls go to open.tiktokapis.com only."
metadata: {"openclaw":{"emoji":"[tt]","requires":{"anyBins":["powershell","pwsh"]}}}
---
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
---
name: tiktok-page
description: "TikTok manager: post videos, list content & check account stats. Requires: powershell/pwsh. Reads ~/.config/tiktok-page/credentials.json (TIKTOK_ACCESS_TOKEN, TIKTOK_REFRESH_TOKEN, TIKTOK_CLIENT_KEY, TIKTOK_CLIENT_SECRET, TIKTOK_OPEN_ID). Tokens expire every 24h — auto-refresh via TIKTOK_REFRESH_TOKEN. Grant minimal permissions only. Rotate immediately if host is compromised. No data forwarded; all calls go to open.tiktokapis.com only."
metadata: {"openclaw":{"emoji":"[tt]","requires":{"anyBins":["powershell","pwsh"]}}}
---
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
| Field | Purpose |
|---|---|
| TIKTOK_ACCESS_TOKEN | OAuth2 access token — used for all API calls |
| TIKTOK_REFRESH_TOKEN | Used to refresh access token when expired |
| TIKTOK_CLIENT_KEY | App Client Key from TikTok Developer Portal |
| TIKTOK_CLIENT_SECRET | App Client Secret — for token refresh only |
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
| Field | Purpose |
|---|---|
| TIKTOK_ACCESS_TOKEN | OAuth2 access token — used for all API calls |
| TIKTOK_REFRESH_TOKEN | Used to refresh access token when expired |
| TIKTOK_CLIENT_KEY | App Client Key from TikTok Developer Portal |
| TIKTOK_CLIENT_SECRET | App Client Secret — for token refresh only |
The skill writes access tokens, refresh tokens, and especially the client secret into a plaintext JSON file under the user's home directory. While local storage is common, storing long-lived secrets unencrypted on disk materially increases the chance of credential theft from local compromise, backups, or accidental file exposure.
TIKTOK_CLIENT_KEY = $clientKey TIKTOK_CLIENT_SECRET = $clientSecret TIKTOK_OPEN_ID = $r.open_id } | ConvertTo-Json | Set-Content "$HOME/.config/tiktok-page/credentials.json" -Encoding UTF8
**Restrict file permissions immediately after saving:**
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
TikTok access tokens expire after 24 hours. Refresh before making calls if needed:
$cfg = Get-Content "$HOME/.config/tiktok-page/credentials.json" -Raw | ConvertFrom-Json
The refreshed access and refresh tokens are persisted back to the same plaintext credentials file, prolonging reliance on locally stored bearer material. If that file is exposed, an attacker can reuse valid tokens and potentially continue refreshing them, enabling account access until revoked.
$cfg.TIKTOK_ACCESS_TOKEN = $r.access_token $cfg.TIKTOK_REFRESH_TOKEN = $r.refresh_token $cfg | ConvertTo-Json | Set-Content "$HOME/.config/tiktok-page/credentials.json" -Encoding UTF8 Write-Host "Tokens refreshed."
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
| Code | Meaning | Fix |
|---|---|---|
| access_token_invalid | Token revoked or invalid | Re-run OAuth2 setup in STEP 1 |
| access_token_expired | Access token expired (24h TTL) | Run token refresh in STEP 2 |
| spam_risk_too_many_requests | Rate limited | Wait and retry; reduce request frequency |
| scope_not_authorized | Missing OAuth scope | Re-authorize with the required scope (see below) |
| video_not_found | Video ID invalid or deleted | Verify the video ID |
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
- Never write extra fields to the credentials file.
- All API calls go to open.tiktokapis.com only. No external forwarding, no third-party services.
- Construct API calls inline from user intent — do not look for script files.
- Access tokens expire after 24 hours. If a call returns access_token_expired, run STEP 2 first then retry.
- On any error: parse error.code, map to the table above, tell the user exactly what to do.
- If a scope is missing: name it, link to developers.tiktok.com, say to re-authorize.
- OS detection: env:OS eq Windows_NT -> powershell; otherwise -> pwsh.
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
icacls "$HOME/.config/tiktok-page/credentials.json" /inheritance:r /grant:r "$($env:USERNAME):(R,W)"
> Never commit this file to version control. It contains long-lived secrets.
No suspicious patterns detected.