T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/push-to-crm.sh:93
- Finding
- Credential and Lead Data Disclosure Through Pipedrive Endpoint Injection<![CDATA[ ## Vulnerability Details **File Location**: `scripts/push-to-crm.sh:93-107` **Vulnerability Type**: Unvalidated endpoint construction and sensitive-data disclosure **Risk Level**: High ### Vulnerable Code ```python api_key = crm_config.get("api_key") or os.environ.get("PIPEDRIVE_API_KEY", "") domain = crm_config.get("domain") or os.environ.get("PIPEDRIVE_DOMAIN", "") if not api_key or not domain: print(f" ⚠️ PIPEDRIVE_API_KEY/DOMAIN not set") return False try: resp = requests.post( f"https://{domain}.pipedrive.com/api/v1/persons", params={"api_token": api_key}, json={ "name": f"{first_name} {last_name}".strip() or company, "email": [{"value": email, "primary": True}], "org_id": None, }, timeout=10, ) ``` ### Technical Analysis The Pipedrive domain is read from `config.json` or `PIPEDRIVE_DOMAIN` and interpolated directly into a URL without validating that it is a simple Pipedrive tenant identifier. URL delimiters such as `/`, `?`, and `#` can cause the resulting URL to be interpreted with a host other than the intended `*.pipedrive.com` host. The request contains two sensitive data classes: - The Pipedrive API token is included in the query string. - Lead names and email addresses are included in the JSON body. Consequently, a malicious or corrupted domain value can cause both the credential and lead data to be sent to an unintended server. Sending lead information to the selected CRM is required by the Skill's functionality, but permitting the destination host to be changed through unrestricted string interpolation exceeds the minimum privilege required. ### Attack Path 1. An attacker who can influence `config.json`, `PIPEDRIVE_DOMAIN`, or the automation environment supplies a crafted domain containing URL delimiters. 2. A user or scheduled workflow invokes `push-to-crm.sh`. 3. The script concatenates the unvalidated value into the request URL. 4. ...[truncated 541 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Restrict the tenant value to a strict slug format, for example `^[A-Za-z0-9-]+$`. - Construct the URL with a URL-building library instead of string interpolation. - Parse the final URL and verify that its hostname is either `pipedrive.com` or ends exactly with `.pipedrive.com`. - Reject embedded credentials, path separators, query delimiters, fragments, and nonstandard ports. - Disable redirects or validate the destination hostname and resolved address before every redirect. - Avoid placing API credentials in query strings where possible; use the service's supported authorization header. - Store allowed CRM hosts in code rather than accepting an arbitrary host from configuration. ]]>
