T09 · Insecure Skill Coding Practices
- Location
jobs/shopee-client.js:17- Finding
User-Controlled GraphQL Injection in Shopee Product Search
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill has a coherent Shopee-to-Notion sync purpose, but it uses unsafe command/input handling and reads credentials from a fixed external workspace path.
Review before installing. Use only isolated, least-privilege Shopee and Notion credentials, fix the hardcoded .env path, validate and safely pass keyword/limit/target arguments, and add an explicit preview or confirmation before Notion writes.
jobs/shopee-client.js:17User-Controlled GraphQL Injection in Shopee Product Search
SKILL.md:15Unsafe Shell Command Template Permits Command Injection
jobs/config.js:3Fixed External Environment File Breaks Workspace Credential Isolation
jobs/sync-shopee-notion.js:17Sensitive Database Identifier and Excessive API Error Details Exposed in Logs
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
│ └── shopee-to-notion/ │ └── SKILL.md ├── package.json └── .env
---
The skill claims a local-only Notion sync workflow, but the described behavior includes external network access, credentialed API use, and functionality that does not match the stated sync purpose. This mismatch can mislead users and orchestrators into approving a workflow they believe is local and low-risk while it actually performs authenticated outbound requests and data handling.
Referenced artifact was not completely inspected
`node jobs/sync-shopee-notion.js "<keyword>" <limit> <target>`
Referenced artifact was not completely inspected
`node jobs/sync-shopee-notion.js "<keyword>" <limit> <target>`
Referenced artifact was not completely inspected
`node jobs/sync-shopee-notion.js "<keyword>" <limit> <target>`
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
console.log("=== USANDO SCRIPT NODE SHOPEE->NOTION ===");
require("dotenv").config({ path: "/data/.openclaw/workspace-sales/.env" });
const targets = {
shopee_produtos: process.env.NOTION_DATABASE_ID
The lockfile pins axios to 1.14.0, and the finding cites multiple advisories including SSRF-related proxy bypass and prototype-pollution-adjacent issues. In a skill that synchronizes data between external services using HTTP requests, a vulnerable HTTP client materially increases risk because attacker-controlled endpoints, redirects, or environment-driven proxy behavior may be reachable during normal operation.
form-data 4.0.5 is reported as vulnerable to CRLF injection via unescaped multipart field names and filenames. This is only exploitable if the application builds multipart requests using attacker-controlled field metadata, but because this package is present and may be used indirectly by axios, it represents a real dependency risk that could enable header/body injection in specific upload flows.
axios is flagged with multiple known advisories, including SSRF-related and prototype-pollution/MITM-related issues. In a skill that syncs Shopee data to Notion and likely performs outbound HTTP requests with credentials or tokens, a vulnerable HTTP client is especially risky because it may enable request manipulation, proxy bypass, credential leakage, or access to unintended internal resources depending on how requests are constructed.
The README instructs users to run a workflow that queries Shopee and writes data into Notion, but it does not clearly disclose the data-flow and side effects up front. This can mislead operators into invoking a skill that sends requests to external services and modifies persistent third-party state without an explicit warning or confirmation model.
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
- Search products on Shopee using a keyword.
- Sync results into a configured Notion database.
- Create new products or update existing ones.
- Uses a local Node.js workflow for predictable execution.
- Supports configurable targets for different Notion databases.
The skill exposes code-execution capability expectations without declaring an explicit tool scope or permission boundary. In practice, this makes it harder to constrain what the skill may access at runtime and increases the chance that environment variables or other local capabilities are used implicitly without user awareness.
The skill instructs syncing and updating data in Notion but does not warn that it may modify external records. Users may think they are only retrieving product information, when the workflow could create or update entries in a connected workspace, creating integrity and operational risks.
The trigger conditions are broad enough to activate on many ordinary shopping or product requests, which can cause the agent to invoke a side-effecting workflow too aggressively. Because the skill may perform external calls and modify records, overbroad activation increases the risk of unintended execution and data changes without clear user intent.
The manifest describes syncing Shopee products into Notion using a local Node.js workflow, which justifies using Shopee and Notion credentials but does not itself justify reading them from an arbitrary fixed filesystem path. Hard-coding access to /data/.openclaw/workspace-sales/.env adds a local file-access capability beyond the stated business purpose of syncing data.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
async function buscarPaginaExistentePorId(databaseId, itemId) {
const response = await axios.post(
`https://api.notion.com/v1/databases/${databaseId}/query`,
{
filter: {
property: "id",
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
async function buscarPaginaExistentePorId(databaseId, itemId) {
const response = await axios.post(
`https://api.notion.com/v1/databases/${databaseId}/query`,
{
filter: {
property: "id",
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
async function buscarPaginaExistentePorId(databaseId, itemId) {
const response = await axios.post(
`https://api.notion.com/v1/databases/${databaseId}/query`,
{
filter: {
property: "id",
This code creates and updates pages in a Notion database via HTTP calls, which modifies user-controlled remote data. There is no visible confirmation prompt, logging, comment, or docstring in this file disclosing that product data will be written to Notion.
This code transmits the user-provided keyword to an external Shopee API and includes an Authorization header derived from application credentials. There is no confirmation prompt, logging, comment, or other visible disclosure in this file warning that user input and authenticated requests are sent to a third-party service.
The mandated response fields include Portuguese-only labels such as "keyword usada," "criados," and "falhas," which effectively impose a specific language. There is no opt-in, user language selection, or documented justification for restricting output to Portuguese.
follow-redirects is a transitive dependency of axios and the cited issue involves leaking custom authentication headers across cross-domain redirects. This is relevant here because the skill likely uses API tokens for Shopee and Notion; if a request follows a malicious or unexpected redirect, sensitive authorization headers could be exposed to another host.
The dependency uses a caret range (^1.14.0) rather than an exact version pin, which allows different installs to resolve to different package versions over time. This weakens build reproducibility and can unexpectedly introduce a compromised or vulnerable release through normal dependency resolution.
"license": "ISC",
"description": "",
"dependencies": {
"axios": "^1.14.0",
"dotenv": "^17.4.1"
}
}
The dotenv dependency is also specified with a caret range, so installations are not fully deterministic and may pull newer transitive code than originally reviewed. While this is a supply-chain hygiene issue rather than an immediate exploit by itself, it increases exposure to accidental or malicious upstream changes.
"description": "",
"dependencies": {
"axios": "^1.14.0",
"dotenv": "^17.4.1"
}
}
No suspicious patterns detected.