Back to skill

Security audit

Toingg Ops Toolkit

Security checks for vulnerabilities and agentic risk

Overview

The skill is coherent Toingg automation, but it needs review because it can upload contact data and trigger calls or WhatsApp broadcasts with weak consent and retention safeguards.

Install only if you are authorized to use the Toingg account and to contact the recipients. Use a limited Toingg token, verify recipient opt-in and applicable messaging/calling rules before bulk sends, avoid committing or broadly sharing contact exports and analytics, and store generated files in access-controlled locations with short retention.

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

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:28
Finding
Plaintext Contact Exports Recommended for Version Control or Shared Storage<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:28`; `scripts/xlsx_to_contacts.py:59-64, 82-85`; `references/contact-workflow.md:31-37` **Vulnerability Type**: Sensitive data exposure through insecure storage guidance **Risk Level**: Medium ### Complete Code Snippet From `SKILL.md:28`: ```markdown 3. Keep payloads (campaign JSON, analytics snapshots, contact exports) in version control or shared storage per your security rules. ``` From `scripts/xlsx_to_contacts.py:59-64, 82-85`: ```python contacts.append( { "name": name, "phone": phone, "extraParams": {"context": context}, } ) contacts = sheet_to_contacts(Path(args.xlsx)) with open(args.output, "w", encoding="utf-8") as fh: json.dump(contacts, fh, indent=2) fh.write("\n") ``` The documented output format in `references/contact-workflow.md:31-37` confirms that the generated files contain personal data: ```json [ {"name": "Abhinav", "phone": "918179259307", "extraParams": {"context": "PGAGI"}}, {"name": "Bibin", "phone": "918179259307", "extraParams": {"context": "PGAGI"}} ] ``` ### Technical Analysis The contact conversion workflow writes names, international telephone numbers, and free-form contextual information to an unencrypted JSON file. The output file is created using the process's default permissions, which depend on the current umask and may permit access by unintended local users. More importantly, the Skill documentation recommends retaining contact exports, campaign payloads, and analytics snapshots in version control or shared storage. Version-control systems preserve historical objects even after a file is deleted from the working tree. Shared storage can similarly expose data through overly broad access-control lists, synchronization clients, backups, or public-link configuration. The network transfer of these contact records to the fixed HTTPS Toingg API is necessary for the declared upload and messaging workflow. The unneces ...[truncated 1498 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the recommendation to store contact exports or raw analytics in version control. 2. Explicitly prohibit committing files containing names, phone numbers, message context, call records, or raw API responses. 3. Add generated contact, payload, response, and analytics paths to `.gitignore`. 4. Create sensitive output files with owner-only permissions, such as mode `0600`, rather than relying on the ambient umask. 5. Store required exports in encrypted, access-controlled storage with least-privilege ACLs. 6. Minimize exported fields and omit free-form context unless it is required for the requested campaign. 7. Define retention periods and securely delete temporary exports after successful upload. 8. Redact sensitive fields before logging or sharing API responses. 9. Replace realistic phone-number examples with clearly fictional reserved values. 10. Add an explicit confirmation step before retaining or sharing any generated data. ]]>

T08 · Insecure Dependencies

Note
Location
SKILL.md:24
Finding
Unpinned Third-Party Dependency Installation<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:24-26`; `references/contact-workflow.md:25-28` **Vulnerability Type**: Mutable and unverifiable third-party dependency resolution **Risk Level**: Low ### Complete Code Snippet From `SKILL.md:24-26`: ```markdown 2. Install Python deps once if you will ingest Excel files: ```bash pip install openpyxl requests ``` ``` From `references/contact-workflow.md:25-28`: ```markdown The script requires `openpyxl`. Install once if missing: ```bash pip install openpyxl ``` ``` ### Technical Analysis The installation commands resolve mutable package versions from pip's configured package index without version constraints or cryptographic hash verification. Consequently, two installations performed at different times can retrieve different code. The package names are consistent with the imports used by the project, and the audit found no evidence of typosquatting, dependency confusion, or a currently malicious package. The risk is that a future compromised upstream release, package-index compromise, malicious mirror, or incompatible update could be installed without review. Python packages can execute code during installation and whenever imported. In this project, `requests` is imported by all network-facing scripts, while `openpyxl` is imported immediately by `xlsx_to_contacts.py`. A malicious resolved package would therefore run with the permissions of the user or automation account invoking the workflow. ### Attack Path 1. An operator follows the documented `pip install` command. 2. pip resolves the latest package versions from the configured index or mirror. 3. A compromised release, malicious mirror response, or otherwise unreviewed version is downloaded. 4. Package installation or a subsequent import executes attacker-controlled Python code. 5. That code runs with the privileges and environment access of the invoking user, potentially including access to `TOINGG_API_TOKEN`, contact files ...[truncated 952 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Provide a reviewed dependency lock file with exact versions. 2. Include cryptographic hashes and install with: ```bash python -m pip install --require-hashes -r requirements.txt ``` 3. Install dependencies inside an isolated virtual environment rather than a system-wide interpreter. 4. Pin both direct and transitive dependencies using a reproducible locking tool. 5. Review and deliberately update dependency versions instead of resolving the latest releases during setup. 6. Use a trusted package index or controlled internal mirror with integrity and access controls. 7. Run dependency vulnerability and provenance scanning in CI. 8. Avoid installing or running the Skill as root or another privileged system account. 9. Restrict the runtime account's access to only the Toingg token and files required for the requested operation. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (17)

Tainted flow: 'headers' from os.getenv (line 46, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
"Accept": "application/json",
        "Content-Type": "application/json",
    }
    response = requests.post(url, headers=headers, json=contacts, timeout=60)
    try:
        response.raise_for_status()
    except requests.HTTPError as exc:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'headers' from os.getenv (line 39, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
"Content-Type": "application/json",
    }

    response = requests.post(API_URL, headers=headers, json=payload, timeout=60)
    try:
        response.raise_for_status()
    except requests.HTTPError as exc:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'headers' from os.getenv (line 32, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Content
"sort": sort,
    }

    response = requests.get(API_URL, headers=headers, params=params, timeout=60)
    try:
        response.raise_for_status()
    except requests.HTTPError as exc:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'headers' from os.getenv (line 29, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Content
"Authorization": f"Bearer {token}",
        "Accept": "application/json",
    }
    response = requests.get(API_URL, headers=headers, timeout=60)
    try:
        response.raise_for_status()
    except requests.HTTPError as exc:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'headers' from os.getenv (line 31, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
"extraParams": {},
    }

    response = requests.post(API_URL, headers=headers, json=payload, timeout=60)
    try:
        response.raise_for_status()
    except requests.HTTPError as exc:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'headers' from os.getenv (line 44, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
"Accept": "application/json",
        "Content-Type": "application/json",
    }
    response = requests.post(API_URL, headers=headers, params=params, json=payload, timeout=60)
    try:
        response.raise_for_status()
    except requests.HTTPError as exc:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The skill explicitly enables bulk WhatsApp outreach from uploaded Excel contact sheets, but it does not require any consent check, lawful-basis verification, recipient opt-in confirmation, or warning about privacy, spam, and data-protection obligations. In context, this makes misuse easier by operationalizing mass messaging against real contact data while normalizing storage and processing of personal information.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The workflow instructs users to upload names and phone numbers to an external messaging service and send WhatsApp templates, but it omits any guidance on consent, lawful basis, data minimization, retention, or secure handling of contact data. This creates a real privacy and compliance risk because operators may process personal data improperly or disclose it to third parties without adequate safeguards.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
This markdown template documents a payload that includes a real notification phone field, lead notifications enabled, and outbound calling enabled, but it does not warn users that using these settings may place calls or send alerts affecting external parties. For markdown files, the skill description should disclose behaviors that can affect user data, privacy, or system integrity.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
This JSON config hard-codes the language to "english" for the campaign, and similar fixed language settings appear in other campaign entries as well. Per the policy, forcing a specific language without offering a user choice or documenting a justified locale constraint is a natural-language policy violation.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The configuration explicitly fixes the campaign language to "english-us". Because the file does not show any opt-in, fallback, or documented justification for this locale constraint, it violates the language/locale policy criteria.

External Transmission

Medium
Category
Data Exfiltration
Content
"Accept": "application/json",
        "Content-Type": "application/json",
    }
    response = requests.post(url, headers=headers, json=contacts, timeout=60)
    try:
        response.raise_for_status()
    except requests.HTTPError as exc:
Confidence
80% 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
"Content-Type": "application/json",
    }

    response = requests.post(API_URL, headers=headers, json=payload, timeout=60)
    try:
        response.raise_for_status()
    except requests.HTTPError as exc:
Confidence
80% 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
"Content-Type": "application/json",
    }

    response = requests.post(API_URL, headers=headers, json=payload, timeout=60)
    try:
        response.raise_for_status()
    except requests.HTTPError as exc:
Confidence
80% 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
"Accept": "application/json",
        "Content-Type": "application/json",
    }
    response = requests.post(API_URL, headers=headers, params=params, json=payload, timeout=60)
    try:
        response.raise_for_status()
    except requests.HTTPError as exc:
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
85% confidence
Finding
This code performs a network POST to an external API using campaign, contact-list, and payload data, but there is no confirmation prompt, explicit log message at send time, or warning comment/docstring explaining that user-provided data will be transmitted. For a code file, network calls that transmit user or system data should have some visible disclosure unless the warning is clearly documented elsewhere in the skill.

Natural-Language Policy Violations

Low
Confidence
93% confidence
Finding
The example payload sets the language to "english" and the surrounding text does not indicate that language is optional, user-selectable, or required for a documented regional reason. This can be read as forcing a specific language by default without user opt-in.

Static analysis

No suspicious patterns detected.