Back to skill

Security audit

Google Ads Transparency API - Advertiser Lookup, Live Ad Creatives

Security checks for vulnerabilities and agentic risk

Overview

This skill is a straightforward Scavio API guide for retrieving public Google Ads Transparency data, with expected network calls and API-key use clearly disclosed.

Install only if you are comfortable sending advertiser/domain lookup queries to Scavio and using a SCAVIO_API_KEY that may consume credits. Prefer the direct HTTPS examples or install the SDKs in an isolated, non-privileged environment, and avoid exposing unrelated environment variables.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (1)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:218
Finding

Third-Party SDK Installation Without Integrity Verification

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 218-244
Vulnerability Type: T08: Insecure Dependencies
Risk Level: Medium

Vulnerable Code

bash
pip install scavio==0.15.0
python
from scavio import ScavioClient

client = ScavioClient()  # reads SCAVIO_API_KEY
bash
npm install scavio@0.15.0
js
import { Scavio } from "scavio";

const scavio = new Scavio(); // reads SCAVIO_API_KEY
const ads = await scavio.googleAds.search({ domain: "notion.so", region: "DE", limit: 100 });

Technical Analysis

The Skill recommends installing Python and JavaScript SDKs directly from public package registries. Pinning both packages to version 0.15.0 reduces unintended version drift, but the instructions provide no cryptographic hashes, npm lockfile integrity data, verified source repository, or other mechanism for confirming the downloaded artifacts.

The installed SDKs execute within the agent's local process and automatically read the sensitive SCAVIO_API_KEY environment variable. Consequently, a compromised registry account, malicious package release, or compromised distribution artifact could access the API credential and perform arbitrary actions with the privileges of the process running the Skill.

The direct HTTPS examples elsewhere in the file already support the declared functionality, so installing an SDK with local code-execution capability is not strictly necessary to query the documented API.

Attack Path

  1. An attacker compromises the relevant package, maintainer account, or package-distribution infrastructure.
  2. A user follows the Skill instructions and installs scavio==0.15.0 or scavio@0.15.0.
  3. Package installation hooks, imported modules, or SDK runtime code execute in the user's environment.
  4. The malicious dependency reads SCAVIO_API_KEY, which the documentation explicitly makes available to the SDK.
  5. The dependency exfiltra ...[truncated 1051 chars]
Remediation
View remediation

Remediation Suggestions

  1. Prefer the documented direct HTTPS API integration, which avoids executing an additional third-party SDK locally.
  2. If the SDKs remain supported, link to their verified official source repositories and document how users can validate package provenance.
  3. For Python, distribute a locked requirements file with cryptographic hashes and require hash verification, for example through pip install --require-hashes.
  4. For npm, provide and verify a lockfile containing registry integrity metadata; use npm ci rather than an unconstrained installation workflow.
  5. Audit the exact pinned artifacts before publication and repeat the review whenever versions change.
  6. Install and execute dependencies in a non-privileged, isolated environment with minimal filesystem and network access.
  7. Expose only SCAVIO_API_KEY to the runtime process rather than inheriting all host environment variables.
  8. Apply API-key scoping, usage limits, rotation, and revocation where supported, and avoid using keys with unnecessary account privileges.
  9. Do not run package installation commands with administrative or root privileges.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (5)

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · SKILL.md (reported line 147)May include surrounding context.

md
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

# 1. Resolve the brand to a verified advertiser id - always start here
who = requests.post(f"{BASE}/api/v1/googleads/advertisers", headers=HEADERS,
    json={"query": "Notion", "region": "DE", "limit": 20}).json()

# 2. Every ad they run in Germany. EEA region, so impressions are populated.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · SKILL.md (reported line 151)May include surrounding context.

md
json={"query": "Notion", "region": "DE", "limit": 20}).json()

# 2. Every ad they run in Germany. EEA region, so impressions are populated.
ads = requests.post(f"{BASE}/api/v1/googleads/search", headers=HEADERS,
    json={"advertiser_id": "AR16735076323512287233", "region": "DE",
          "platform": "youtube", "limit": 100}).json()

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · SKILL.md (reported line 156)May include surrounding context.

md
json={"query": "Notion", "region": "DE", "limit": 20}).json()

# 2. Every ad they run in Germany. EEA region, so impressions are populated.
ads = requests.post(f"{BASE}/api/v1/googleads/search", headers=HEADERS,
    json={"advertiser_id": "AR16735076323512287233", "region": "DE",
          "platform": "youtube", "limit": 100}).json()

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · SKILL.md (reported line 172)May include surrounding context.

md
json={"query": "Notion", "region": "DE", "limit": 20}).json()

# 2. Every ad they run in Germany. EEA region, so impressions are populated.
ads = requests.post(f"{BASE}/api/v1/googleads/search", headers=HEADERS,
    json={"advertiser_id": "AR16735076323512287233", "region": "DE",
          "platform": "youtube", "limit": 100}).json()

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · SKILL.md (reported line 160)May include surrounding context.

json={"domain": "notion.so", "region": "DE", "limit": 100}).json()

3. One creative in full - the advertiser_id + creative_id PAIR

creative = requests.post(f"{BASE}/api/v1/googleads/creative", headers=HEADERS, json={"advertiser_id": "AR16735076323512287233", "creative_id": "CR1234567890"}).json()

text

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
SKILL.md:37