T09 · Insecure Skill Coding Practices
- Location
scripts/fetch_dingtalk_messages.py:40- Finding
Externally Controlled Endpoints Can Receive DingTalk Credentials
- Content
View full analysis
Vulnerability Details
File Location:
scripts/fetch_dingtalk_messages.py, lines 40–41, 52–55, and 65–67
Vulnerability Type: Credential disclosure through unrestricted network destinations
Risk Level: HighVulnerable Code
python ap.add_argument( '--token-url', default='https://api.dingtalk.com/v1.0/oauth2/accessToken' ) ap.add_argument( '--messages-url', default=os.getenv('DINGTALK_MESSAGES_API_URL', ''), help='Your message query API URL' ) token_resp = post_json(args.token_url, { 'appKey': args.client_id, 'appSecret': args.client_secret, }) data_resp = post_json(args.messages_url, payload, headers={ 'x-acs-dingtalk-access-token': access_token, })The underlying request function sends the supplied data and headers using
urllib.request.urlopen:python def post_json(url, data, headers=None): body = json.dumps(data).encode('utf-8') req = urllib.request.Request(url, data=body, method='POST') req.add_header('Content-Type', 'application/json') if headers: for k, v in headers.items(): req.add_header(k, v) with urllib.request.urlopen(req) as resp: return json.loads(resp.read().decode('utf-8'))Technical Analysis
The script sends two sensitive credentials to externally controllable destinations:
--token-urlreceives the long-lived DingTalk client ID and client secret.--messages-url, or itsDINGTALK_MESSAGES_API_URLenvironment-variable equivalent, receives the OAuth access token in an HTTP header.
No validation requires HTTPS, pins the token endpoint to the official DingTalk origin, restricts the message endpoint to an administrator-approved host, or rejects URLs containing user information. The use of
urllib.request.urlopenalso permits default redirect handling without an explicit same-origin restriction for credential-bearing requests.A configurable enterprise message endpoint is consistent with the declared functionality b ...[truncated 1956 chars]
- Remediation
View remediation
Remediation Suggestions
- Remove the
--token-urloption and pin the authentication endpoint to the official DingTalk HTTPS URL. If endpoint customization is operationally unavoidable, enforce an exact administrator-controlled allowlist of schemes, hosts, ports, and paths. - Require
httpsfor every endpoint that receives credentials. Reject plaintext HTTP and unexpected URL schemes. - Validate
--messages-urlandDINGTALK_MESSAGES_API_URLagainst an explicit administrator-managed host allowlist before attaching the access token. - Reject URLs containing embedded user information and, unless explicitly required, destinations resolving to loopback, link-local, private, multicast, or cloud-metadata address ranges. Revalidate after DNS resolution to reduce SSRF and DNS-rebinding risks.
- Disable redirects for credential-bearing requests, or permit only explicitly approved same-origin redirects. Never forward secrets or authorization headers across origins.
- Display the validated destination origin and require explicit approval before sending a token to a newly configured host.
- Apply least-privilege permissions to the DingTalk application and rotate both the client secret and active tokens if exposure is suspected.
- Add tests verifying rejection of HTTP URLs, unapproved hosts, cross-origin redirects, loopback addresses, link-local addresses, and cloud metadata endpoints.
- Avoid reporting complete authentication responses in errors, because provider responses may contain sensitive material. Return a sanitized error containing only the status and a non-sensitive provider error code.
- Remove the
