Back to skill

Security audit

Apple Search Ads

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a coherent Apple Ads management guide, but its provided mutation scripts can change live ad spend without enforcing the confirmation gate the skill promises.

Review before installing if you plan to use API automation. Treat the provided mutation scripts as unsafe until they add explicit confirmations, JSON-safe payload construction, input validation, and safer defaults such as creating campaigns paused. Keep Apple private keys, client secrets, and access tokens in a secure secret store, not in the skill workspace, shell history, logs, or source control.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts.md:114
Finding
Campaign Mutation Scripts Bypass the Promised Confirmation Gate<![CDATA[ ## Vulnerability Details **File Location**: `scripts.md`, lines 114-142 **Vulnerability Type**: `T09: Insecure Skill Coding Practices` **Risk Level**: High ### Vulnerable Code ```bash # Environment variables accessed: ASA_ACCESS_TOKEN, ASA_ORG_ID # External endpoints called: https://api.searchads.apple.com/api/v5/campaigns # Local files written: none : "${ASA_ACCESS_TOKEN:?Set ASA_ACCESS_TOKEN}" : "${ASA_ORG_ID:?Set ASA_ORG_ID}" # Arguments NAME="${1:?Usage: $0 <name> <adam_id> <country> <daily_budget>}" ADAM_ID="${2:?Missing adam_id}" COUNTRY="${3:?Missing country}" DAILY_BUDGET="${4:?Missing daily_budget}" curl -s -X POST "https://api.searchads.apple.com/api/v5/campaigns" \ -H "Authorization: Bearer $ASA_ACCESS_TOKEN" \ -H "X-AP-Context: orgId=$ASA_ORG_ID" \ -H "Content-Type: application/json" \ -d '{ "name": "'"$NAME"'", "adamId": '"$ADAM_ID"', "countriesOrRegions": ["'"$COUNTRY"'"], "budgetAmount": {"amount": "10000", "currency": "USD"}, "dailyBudgetAmount": {"amount": "'"$DAILY_BUDGET"'", "currency": "USD"}, "supplySources": ["APPSTORE_SEARCH_RESULTS"], "billingEvent": "TAPS", "status": "ENABLED" }' | jq ``` Equivalent immediate-mutation behavior also appears in the pause, add-keyword, and add-negative scripts at `scripts.md:153-168`, `scripts.md:181-203`, and `scripts.md:216-235`. ### Technical Analysis The Skill states that every mutation script respects `confirm_before_push`, and `SKILL.md` defines that setting as the approval gate for changes affecting bids, budgets, campaign status, and keywords. However, the mutation scripts neither read `config.yaml` nor inspect `confirm_before_push`. They also do not display a proposed change or prompt the operator before sending the authenticated request. The campaign creation example is particularly consequential because it creates the campaign with `"status": "ENABLED"`. Once invoked with valid credentials, the script immediately sends the request to Ap ...[truncated 1288 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Implement a shared confirmation function used by every mutation script. - Read `confirm_before_push` from the documented configuration file and default to `true` if the file or setting is absent. - Before sending a request, print the target organization, endpoint, resource identifiers, and exact normalized payload. - Require an explicit approval response such as `yes`; reject empty input and all other responses. - For non-interactive use, require a deliberate option such as `--yes` or `--unattended`, rather than silently detecting a non-interactive terminal. - Keep destructive operations such as deletion subject to confirmation even when unattended changes are otherwise enabled. - Consider creating new campaigns in a paused state by default and requiring a separate confirmation to enable them. - Add tests that mock `curl` and verify no mutation request is sent before approval. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts.md:122
Finding
Untrusted Arguments Are Concatenated Directly into JSON Mutation Payloads<![CDATA[ ## Vulnerability Details **File Location**: `scripts.md`, lines 122-142 **Vulnerability Type**: `T09: Insecure Skill Coding Practices` **Risk Level**: High ### Vulnerable Code ```bash NAME="${1:?Usage: $0 <name> <adam_id> <country> <daily_budget>}" ADAM_ID="${2:?Missing adam_id}" COUNTRY="${3:?Missing country}" DAILY_BUDGET="${4:?Missing daily_budget}" curl -s -X POST "https://api.searchads.apple.com/api/v5/campaigns" \ -H "Authorization: Bearer $ASA_ACCESS_TOKEN" \ -H "X-AP-Context: orgId=$ASA_ORG_ID" \ -H "Content-Type: application/json" \ -d '{ "name": "'"$NAME"'", "adamId": '"$ADAM_ID"', "countriesOrRegions": ["'"$COUNTRY"'"], "budgetAmount": {"amount": "10000", "currency": "USD"}, "dailyBudgetAmount": {"amount": "'"$DAILY_BUDGET"'", "currency": "USD"}, "supplySources": ["APPSTORE_SEARCH_RESULTS"], "billingEvent": "TAPS", "status": "ENABLED" }' | jq ``` The same construction pattern is used for keyword input at `scripts.md:189-203` and `scripts.md:224-235`: ```bash -d '[{ "text": "'"$KEYWORD"'", "matchType": "'"$MATCH_TYPE"'", "bidAmount": {"amount": "'"$BID"'", "currency": "USD"}, "status": "ACTIVE" }]' | jq ``` ### Technical Analysis Values supplied through command-line arguments are inserted into JSON through shell string concatenation. The script does not apply JSON encoding and does not validate expected types or formats. A value containing quotation marks, backslashes, arrays, objects, or other JSON syntax can terminate its intended string or scalar context and alter the surrounding request body. For example, a crafted campaign name can inject additional JSON properties. Numeric fields such as `ADAM_ID` are inserted without quotation marks, making them especially sensitive to malformed or attacker-controlled JSON fragments. This is JSON injection rather than shell command injection: shell metacharacters introduced through ordinary variable expansion are not automatically reparsed as s ...[truncated 1458 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Construct all payloads with a JSON-aware tool instead of shell concatenation. For example: ```bash payload=$( jq -n \ --arg name "$NAME" \ --argjson adamId "$ADAM_ID" \ --arg country "$COUNTRY" \ --arg budget "$DAILY_BUDGET" \ '{ name: $name, adamId: $adamId, countriesOrRegions: [$country], budgetAmount: {amount: "10000", currency: "USD"}, dailyBudgetAmount: {amount: $budget, currency: "USD"}, supplySources: ["APPSTORE_SEARCH_RESULTS"], billingEvent: "TAPS", status: "PAUSED" }' ) curl --fail-with-body --silent --show-error \ -X POST "https://api.searchads.apple.com/api/v5/campaigns" \ -H "Authorization: Bearer $ASA_ACCESS_TOKEN" \ -H "X-AP-Context: orgId=$ASA_ORG_ID" \ -H "Content-Type: application/json" \ --data-binary "$payload" ``` Additional hardening should include: - Validate IDs with a strict numeric expression. - Validate countries against the supported country-code format. - Use a fixed allowlist for match types and currencies. - Validate monetary values as positive decimal values within configured limits. - Reject control characters and enforce documented length limits. - Use `curl --fail-with-body --silent --show-error` and inspect HTTP status codes. - Display the safely encoded payload during the confirmation step. - Add tests containing quotes, backslashes, newlines, and attempted JSON fragments. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
ios-integration.md:397
Finding
Debugging Example Logs a Substantial Portion of a Live Attribution Token<![CDATA[ ## Vulnerability Details **File Location**: `ios-integration.md`, lines 397-408 **Vulnerability Type**: `T09: Insecure Skill Coding Practices` **Risk Level**: Medium ### Vulnerable Code ```swift // Add debug logging func fetchAttribution() async { do { let token = try AAAttribution.attributionToken() print("[ASA] Token: \(token.prefix(50))...") let attribution = try await fetchAttributionData(token: token) print("[ASA] Attribution: \(attribution)") } catch { print("[ASA] Error: \(error)") } } ``` ### Technical Analysis The example prints the first 50 characters of the AdServices attribution token. Truncation does not make credential logging safe: the fragment remains sensitive, may expose token structure or identifying material, and can be correlated with attribution requests and device activity. Application output can be retained or forwarded by: - Xcode and device console logs - Unified logging facilities - Crash and diagnostic collection systems - CI or automated test logs - Third-party observability platforms - Support bundles shared outside the development team The network transmission of the complete token to `https://api-adservices.apple.com/api/v1/` is necessary for the declared attribution functionality. The vulnerability is the additional disclosure to logs, not the Apple API request. The same example also prints the complete decoded attribution response, which can contain organization, campaign, ad-group, keyword, click-date, and regional information. Although this is less sensitive than the token, it should still be treated as advertising analytics data. ### Attack Path 1. A developer copies the documented debugging sample into an application. 2. The application generates an attribution token during first launch. 3. Fifty token characters and the decoded attribution response are emitted to application logs. 4. Logs are retained locally or forwarded to a logging, ...[truncated 680 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove all logging of attribution-token contents, including prefixes and suffixes. - Log only a constant success message, such as `AdServices token generated`. - If request correlation is essential, generate a separate random, non-secret request identifier. - Avoid printing the complete attribution response; log only fields necessary for diagnosis and redact campaign identifiers where possible. - Ensure diagnostic logging is compiled only into debug builds: ```swift #if DEBUG print("[ASA] Attribution request started") #endif ``` - Configure production logging and crash-reporting SDKs to redact token-like values. - Document that attribution tokens must never be copied into bug reports, screenshots, analytics events, or support logs. - Add automated source scanning that rejects log statements referencing variables named `token`, `secret`, or `Authorization`. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
api-reference.md:41
Finding
Authentication Guidance Recommends Storing a Long-Lived Client-Secret JWT Without Storage Protections<![CDATA[ ## Vulnerability Details **File Location**: `api-reference.md`, lines 41-58 **Vulnerability Type**: `T09: Insecure Skill Coding Practices` **Risk Level**: Medium ### Vulnerable Code ```bash curl -X POST "https://appleid.apple.com/auth/oauth2/token" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=client_credentials" \ -d "client_id=${ASA_CLIENT_ID}" \ -d "client_secret=${CLIENT_SECRET}" \ -d "scope=searchadsorg" ``` ```text Access tokens are valid 1 hour — cache and reuse across calls; minting a fresh token per request is the usual cause of auth throttling. The client secret JWT may set `exp` up to 180 days out: generate it once and store it, not per run. ``` ### Technical Analysis The client-secret JWT is a bearer credential used to obtain Apple Campaign Management API access tokens. The guide recommends generating a JWT with a validity period of up to 180 days and storing it, but does not require an operating-system keychain, dedicated secret manager, encryption, restrictive permissions, or rotation. If followed literally, a user may store the JWT in the Skill workspace, a shell script, a plaintext configuration file, or another location included in backups or accessible to unrelated local processes. This guidance conflicts with the Skill's security statements that API secrets are not stored in plaintext and that secrets travel only through environment variables. Environment variables are not durable secure storage, and generating the token once implies persistence somewhere beyond process memory. ### Attack Path 1. A user follows the instruction to generate a 180-day client-secret JWT once and store it. 2. The credential is saved in a plaintext file, script, workspace, shell history, or inadequately protected cache. 3. A local process, another user, a backup reader, or a repository consumer obtains the JWT. 4. Before expiration, the attacker submits it with the associated client ID to Apple's OAuth token end ...[truncated 977 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Prefer generating a short-lived client-secret JWT immediately before token exchange rather than storing a 180-day bearer credential. - Keep the private `.p8` key in an operating-system keychain, hardware-backed key store, or managed secret service. - If JWT caching is necessary, require encrypted secret storage and prohibit storage in the Skill workspace, source repositories, shell profiles, temporary directories, and ordinary configuration files. - Apply restrictive filesystem permissions where file-based key storage is unavoidable, such as owner-only access. - Document credential rotation, revocation, expiry monitoring, and incident-response procedures. - Avoid passing secrets directly on command lines where process inspection or verbose logs could expose them. - Ensure `curl` debugging and shell tracing are disabled around token exchange. - Align `SKILL.md`, `memory-template.md`, and `api-reference.md` so they provide one consistent policy for secret generation, storage, and lifecycle management. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (51)

Credential Access

High
Category
Privilege Escalation
Content
}
```

Access tokens are valid 1 hour — cache and reuse across calls; minting a fresh token per request is the usual cause of auth throttling. The client secret JWT may set `exp` up to 180 days out: generate it once and store it, not per run.

## Base URL & Headers
Confidence
75% confidence
Finding
The guidance says the client secret JWT may be generated once and stored for up to 180 days, but it does not pair that recommendation with strong storage constraints. Long-lived bearer-style authentication material materially increases blast radius if copied from disk, backups, CI logs, or developer machines, especially in automation-heavy ad operations.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
### Delete Campaign

```bash
DELETE /campaigns/{campaignId}
```

## Ad Groups
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Hidden Instructions

High
Category
Prompt Injection
Content
## Apps

<!-- Add each app being advertised -->
### App Name
- Adam ID: 123456789
- Category: Health & Fitness
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
## Learnings

<!-- What's working, what's not -->
- Brand keywords: CPA consistently under $4
- Generic keywords: Only "meditation app" profitable
- Competitor keywords: Not working, paused
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Credential Access

High
Category
Privilege Escalation
Content
### get-token.sh

Generate OAuth access token.

```bash
#!/usr/bin/env bash
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
### get-token.sh

Generate OAuth access token.

```bash
#!/usr/bin/env bash
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
### get-token.sh

Generate OAuth access token.

```bash
#!/usr/bin/env bash
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
| Error | Causes in order | Fix |
|---|---|---|
| 401 UNAUTHORIZED | Access token >1h old · client secret JWT malformed (wrong `aud`, missing `kid`, not ES256) · JWT `exp` passed | Mint a new token; regenerate the client secret only if the token exchange itself fails (`api-reference.md` → Authentication) |
| 403 FORBIDDEN | `X-AP-Context: orgId=` missing or pointing at an org this user can't touch (multi-org accounts) · API access not granted to this user/key in account settings · resource belongs to another org | `GET /acls` lists the orgs and roles your credentials actually hold — compare against the orgId you are sending |
| 404 NOT_FOUND | Wrong campaign/adgroup/keyword ID, or right ID under the wrong org context | Re-list the parent to confirm the ID exists under this orgId |
| INVALID_FIELD | Payload shape drift — commonly money objects (`{"amount":"5.00","currency":"USD"}` with amount as string) or a phased-out field | Compare against the request bodies in `api-reference.md` |
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
| report_timezone | UTC \| ORTZ | UTC | Passed as `timeZone` in every report request — one value everywhere, never mixed (Traps) |
| ltv_divisor | number (3-5) | 4 | Target CPA = LTV / `ltv_divisor`; 3 = aggressive payback, 5 = conservative (`strategy.md`) |
| mmp | none \| appsflyer \| adjust \| singular \| kochava \| branch | none | With an MMP set, it owns AdServices and SKAN integration and cross-channel truth (`ios-integration.md`, `measurement.md`) |
| confirm_before_push | bool | true | Every API mutation (bids, budgets, status, keywords) is listed and confirmed before pushing; false = push and log without asking. Setting it to false means real ad spend changes without a prompt: only do it for campaigns you own and can afford to have moved unattended; campaign DELETE stays confirmed either way |
| naming_pattern | text | App - Country - Intent | Template for every campaign name in create payloads, scripts, and memory logs; parsing reports assumes this pattern |

Preference areas to record as the user reveals them:
Confidence
91% confidence
Finding
The skill allows `confirm_before_push` to be set to false, which permits spend-changing API mutations to execute without an interactive confirmation. In an advertising tool, that can directly alter bids, budgets, statuses, and keywords, creating financial loss or large unintended campaign changes if the agent misinterprets instructions or operates on stale data.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
This markdown file includes examples for reading a private key from disk, accessing credential environment variables, generating a long-lived client secret, and exchanging it over HTTP, but it does not warn users that these values are sensitive secrets that must be protected. Because SQP-2 applies to markdown files, documentation describing secret use and transmission should disclose privacy and system-integrity implications.

External Transmission

Medium
Category
Data Exfiltration
Content
### Token Exchange

```bash
curl -X POST "https://appleid.apple.com/auth/oauth2/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=${ASA_CLIENT_ID}" \
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
All endpoints below are relative to the base URL.

```
Base URL: https://api.searchads.apple.com/api/v5
Headers:
  Authorization: Bearer {ACCESS_TOKEN}
  X-AP-Context: orgId={ORG_ID}
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
All endpoints below are relative to the base URL.

```
Base URL: https://api.searchads.apple.com/api/v5
Headers:
  Authorization: Bearer {ACCESS_TOKEN}
  X-AP-Context: orgId={ORG_ID}
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
All endpoints below are relative to the base URL.

```
Base URL: https://api.searchads.apple.com/api/v5
Headers:
  Authorization: Bearer {ACCESS_TOKEN}
  X-AP-Context: orgId={ORG_ID}
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
All endpoints below are relative to the base URL.

```
Base URL: https://api.searchads.apple.com/api/v5
Headers:
  Authorization: Bearer {ACCESS_TOKEN}
  X-AP-Context: orgId={ORG_ID}
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
All endpoints below are relative to the base URL.

```
Base URL: https://api.searchads.apple.com/api/v5
Headers:
  Authorization: Bearer {ACCESS_TOKEN}
  X-AP-Context: orgId={ORG_ID}
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
All endpoints below are relative to the base URL.

```
Base URL: https://api.searchads.apple.com/api/v5
Headers:
  Authorization: Bearer {ACCESS_TOKEN}
  X-AP-Context: orgId={ORG_ID}
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
All endpoints below are relative to the base URL.

```
Base URL: https://api.searchads.apple.com/api/v5
Headers:
  Authorization: Bearer {ACCESS_TOKEN}
  X-AP-Context: orgId={ORG_ID}
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
All endpoints below are relative to the base URL.

```
Base URL: https://api.searchads.apple.com/api/v5
Headers:
  Authorization: Bearer {ACCESS_TOKEN}
  X-AP-Context: orgId={ORG_ID}
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
All endpoints below are relative to the base URL.

```
Base URL: https://api.searchads.apple.com/api/v5
Headers:
  Authorization: Bearer {ACCESS_TOKEN}
  X-AP-Context: orgId={ORG_ID}
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
All endpoints below are relative to the base URL.

```
Base URL: https://api.searchads.apple.com/api/v5
Headers:
  Authorization: Bearer {ACCESS_TOKEN}
  X-AP-Context: orgId={ORG_ID}
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
All endpoints below are relative to the base URL.

```
Base URL: https://api.searchads.apple.com/api/v5
Headers:
  Authorization: Bearer {ACCESS_TOKEN}
  X-AP-Context: orgId={ORG_ID}
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
All endpoints below are relative to the base URL.

```
Base URL: https://api.searchads.apple.com/api/v5
Headers:
  Authorization: Bearer {ACCESS_TOKEN}
  X-AP-Context: orgId={ORG_ID}
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
All endpoints below are relative to the base URL.

```
Base URL: https://api.searchads.apple.com/api/v5
Headers:
  Authorization: Bearer {ACCESS_TOKEN}
  X-AP-Context: orgId={ORG_ID}
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
All endpoints below are relative to the base URL.

```
Base URL: https://api.searchads.apple.com/api/v5
Headers:
  Authorization: Bearer {ACCESS_TOKEN}
  X-AP-Context: orgId={ORG_ID}
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
api-reference.md:17