T09 · Insecure Skill Coding Practices
- Location
scripts/save.sh:30- Finding
Unescaped URL Input Allows JSON Request-Body Injection
- Content
View full analysis
Vulnerability Details
File Location:
scripts/save.sh, lines 30–33
Vulnerability Type: Improper JSON construction using untrusted input
Risk Level: MediumVulnerable Code
bash RESPONSE=$(curl -s -X POST "${READECK_URL}/api/bookmarks" \ -H "Authorization: Bearer ${READECK_API_TOKEN}" \ -H "Content-Type: application/json" \ -d "{\"url\": \"$URL\"}")Technical Analysis
The script directly interpolates the user-supplied
$URLvalue into a JSON string without applying JSON encoding. A value containing quotation marks, backslashes, or control characters can escape the intendedurlstring and alter the structure of the request body.For example, an input resembling:
text https://example.test/","title":"Injectedproduces a request body resembling:
json {"url": "https://example.test/","title":"Injected"}This permits injection of additional JSON properties. Other crafted values can produce malformed JSON and cause request failure. The shell quotes around
$URLprevent this flaw from directly becoming shell command injection; exploitation is confined to manipulation of the JSON sent to the configured Readeck API.Attack Path
- An attacker supplies or influences the article URL passed to
scripts/save.sh. - The agent invokes the script with that crafted URL as its first argument.
- The script inserts the value directly into the JSON body without escaping it.
- The resulting request contains malformed JSON or attacker-added properties.
- The configured Readeck server processes any injected fields that its API recognizes, using the authority of
READECK_API_TOKEN.
Impact Assessment
An attacker able to control the URL can manipulate the body of an authenticated bookmark-creation request. The practical effect depends on which additional fields the Readeck API accepts and may include alteration of bookmark attributes or denial of the reque ...[truncated 292 chars]
- An attacker supplies or influences the article URL passed to
- Remediation
View remediation
Remediation Suggestions
Construct the request body with a JSON-aware encoder rather than string interpolation:
bash PAYLOAD=$(jq -n --arg url "$URL" '{url: $url}') RESPONSE=$(curl -sS -X POST "${READECK_URL}/api/bookmarks" \ -H "Authorization: Bearer ${READECK_API_TOKEN}" \ -H "Content-Type: application/json" \ --data-binary "$PAYLOAD")Additionally:
- Validate that the supplied value is a well-formed URL.
- Restrict accepted schemes to those required by the workflow, normally
httpandhttps. - Reject control characters and unexpected multiline input.
- Keep the API token scoped to the minimum Readeck permissions necessary to create bookmarks.
- Use
curl -sS --fail-with-bodyand inspect the HTTP status code separately from the JSON response body so transport and server failures are handled reliably.
