T09 · Insecure Skill Coding Practices
Warning
- Location
- SKILL.md:48
- Finding
- Apify API Token Exposed in URL Query Strings<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 48, 69, and 77 **Vulnerability Type**: API credential exposure through URL query parameters **Risk Level**: Medium ### Vulnerable Code ```bash curl --request POST \ --url "https://api.apify.com/v2/acts/harvestapi~linkedin-post-search/runs?token=$APIFY_API_TOKEN" \ --header 'Content-Type: application/json' \ --data '{ "searchQueries": ["<search query>"], "maxPosts": 50, "sortBy": "date", "postedLimit": "month" }' ``` ```bash curl "https://api.apify.com/v2/acts/harvestapi~linkedin-post-search/runs/<RUN_ID>?token=$APIFY_API_TOKEN" ``` ```bash curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=$APIFY_API_TOKEN" ``` ### Technical Analysis The Skill authenticates to Apify by embedding `APIFY_API_TOKEN` in the URL query string. Authentication is necessary for the declared LinkedIn search functionality, and the requests use HTTPS, but placing credentials in URLs creates avoidable exposure. When the shell expands the environment variable, the resulting token-bearing URL may appear in the `curl` process arguments. Depending on the operating system and process-isolation configuration, other local users or processes may be able to inspect those arguments. Full URLs may also be retained by HTTP proxies, API gateways, server access logs, monitoring platforms, tracing systems, or diagnostic output. The same token is included separately in actor-start, run-polling, and dataset-retrieval URLs, increasing the number of places where it may be recorded. This exceeds the minimum exposure necessary because Apify supports bearer-token authentication through an HTTP header. No hardcoded token was found, and no evidence indicates that the Skill sends the credential to a domain other than the declared Apify API. ### Attack Path 1. A user configures a valid `APIFY_API_TOKEN` in the Skill environment. 2. The agent executes one of the documented `curl` commands. 3. The ...[truncated 886 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Use Apify's bearer-token authorization header and remove the token from every URL: ```bash curl --request POST \ --url "https://api.apify.com/v2/acts/harvestapi~linkedin-post-search/runs" \ --header "Authorization: Bearer $APIFY_API_TOKEN" \ --header "Content-Type: application/json" \ --data '{ "searchQueries": ["<search query>"], "maxPosts": 50, "sortBy": "date", "postedLimit": "month" }' ``` Apply the same approach when polling and retrieving results: ```bash curl \ --header "Authorization: Bearer $APIFY_API_TOKEN" \ "https://api.apify.com/v2/acts/harvestapi~linkedin-post-search/runs/<RUN_ID>" ``` ```bash curl \ --header "Authorization: Bearer $APIFY_API_TOKEN" \ "https://api.apify.com/v2/datasets/<DATASET_ID>/items" ``` Additional hardening measures: 1. Grant the token only the minimum Apify permissions required to run this actor and retrieve its output. 2. Use a dedicated token for this Skill rather than a broadly privileged account token. 3. Avoid verbose HTTP logging and ensure authorization headers are redacted from logs and traces. 4. Never print or persist the environment variable in agent responses, command transcripts, or debugging output. 5. Rotate the token if the original URL-based commands have already been used in an environment where process arguments or URLs may have been logged. 6. Configure usage limits and monitor the Apify account for unexpected actor runs, dataset access, or billing activity. ]]>
