Back to skill

Security audit

Automation Workflow

Security checks for vulnerabilities and agentic risk

Overview

This automation skill matches its general purpose, but it needs review because it can run unattended network workflows while exposing environment secrets and weakening HTTPS protection.

Install only after reviewing and constraining workflow files. Treat workflows as trusted code: do not run workflows from untrusted sources, avoid daemon mode until scheduling is fixed, do not expose broad environment variables, and require HTTPS verification plus explicit allowlists for network destinations before using this with secrets or business data.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/workflow.py:73
Finding

TLS Certificate and Hostname Verification Disabled

Content
View full analysis

Vulnerability Details

File Location: scripts/workflow.py:73-109
Vulnerability Type: Improper certificate validation
Risk Level: High

Vulnerable Code

python
try:
    ctx = ssl.create_default_context()
    ctx.check_hostname = False
    ctx.verify_mode = ssl.CERT_NONE
    
    req = Request(url, headers=headers, method=method)
    
    # Handle request body
    if 'body' in config:
        req.data = interpolate(config['body'], context).encode()
        
    with urlopen(req, timeout=30, context=ctx) as resp:
        body = resp.read().decode('utf-8', errors='ignore')
        try:
            return json.loads(body)
        except:
            return {'raw': body}
except URLError as e:
    return {'error': str(e)}
python
url = f'https://api.telegram.org/bot{token}/sendMessage'
data = {'chat_id': chat_id, 'text': message}

ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

req = Request(url, data=json.dumps(data).encode(), 
              headers={'Content-Type': 'application/json'})

Technical Analysis

The runner creates a default TLS context but then explicitly disables both certificate verification and hostname checking. This affects generic HTTP actions and Telegram requests.

As a result, the client will accept an expired, self-signed, forged, or otherwise untrusted certificate. HTTPS therefore does not provide reliable server authentication. An attacker able to intercept network traffic can impersonate an API endpoint, inspect request contents, and alter responses.

The Telegram bot token is included in the request URL. Once the attacker terminates the forged TLS connection, that request path and the accompanying message become visible.

Attack Path

  1. A workflow sends an HTTPS request containing an authorization header, body data, or Telegram bot token.
  2. An attacker obtains an on-pa ...[truncated 799 chars]
Remediation
View remediation

Remediation Suggestions

  • Retain the secure settings supplied by ssl.create_default_context().
  • Remove both ctx.check_hostname = False and ctx.verify_mode = ssl.CERT_NONE.
  • Use the operating system's trusted CA store by default.
  • If private certificate authorities must be supported, accept an explicit CA bundle and load it through SSLContext.load_verify_locations().
  • Do not add a general-purpose option for disabling TLS verification.
  • Add automated tests confirming that self-signed, expired, and hostname-mismatched certificates are rejected.
  • Consider using the maintained requests client with certificate verification enabled, while still enforcing timeouts and destination restrictions.

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/workflow.py:146
Finding

Workflow Templates Can Access and Exfiltrate the Entire Process Environment

Content
View full analysis

Vulnerability Details

File Location: scripts/workflow.py:146-152
Vulnerability Type: Excessive secret exposure and least-privilege violation
Risk Level: High

Vulnerable Code

python
workflow = load_yaml(workflow_path)
name = workflow.get('name', 'unnamed')

print(f"[{datetime.now().isoformat()}] Running workflow: {name}")

context = {
    'env': os.environ,
    'workflow': workflow
}

The exposed context can be interpolated into network sinks:

python
def interpolate(template, context):
    """Simple template interpolation."""
    result = template
    for key, val in context.items():
        result = result.replace(f'{{{{{key}}}}}', str(val))
    return result
python
url = interpolate(config.get('url', ''), context)
headers = {k: interpolate(v, context) for k, v in headers.items()}

if 'body' in config:
    req.data = interpolate(config['body'], context).encode()

Technical Analysis

Every workflow receives a direct reference to os.environ, including variables unrelated to the workflow. The interpolation implementation converts context values to strings. Consequently, a template containing {{env}} expands to a textual representation of the complete environment mapping.

That expanded value can be placed in an HTTP URL, header, body, log message, transformation, or Telegram message. The exposure is broader than the documented need to use selected environment variables for workflow credentials.

This also means the implementation does not enforce separation between secrets loaded for one workflow and unrelated credentials inherited from the process, host, CI runner, or cloud environment.

Attack Path

  1. An attacker supplies or modifies a workflow YAML file that a victim is persuaded to execute.
  2. The malicious workflow includes an HTTP action directed to an attacker-controlled server.
  3. Its URL, header, or body contains the templa ...[truncated 721 chars]
Remediation
View remediation

Remediation Suggestions

  • Do not add os.environ directly to the workflow context.
  • Require each workflow to declare the exact environment variables it needs.
  • Construct a new dictionary containing only allowlisted variable names.
  • Resolve individual secret references through a dedicated secret provider rather than permitting whole-object interpolation.
  • Reject interpolation of dictionaries, environment objects, and other aggregate values.
  • Prevent secrets from being interpolated into URLs because URLs may be retained by proxies and logs.
  • Redact sensitive values from verbose output, errors, and log actions.
  • Treat workflow files as executable policy and require trusted ownership, integrity checks, and restrictive filesystem permissions.
  • Document that untrusted workflow files must not be executed.

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/workflow.py:63
Finding

Unrestricted Workflow URLs Enable Server-Side Request Forgery

Content
View full analysis

Vulnerability Details

File Location: scripts/workflow.py:63-89
Vulnerability Type: Server-side request forgery
Risk Level: High

Vulnerable Code

python
def execute_http(action, context):
    """Execute HTTP request."""
    config = action.get('config', {})
    url = interpolate(config.get('url', ''), context)
    method = config.get('method', 'GET').upper()
    headers = config.get('headers', {})
    
    # Interpolate headers
    headers = {k: interpolate(v, context) for k, v in headers.items()}
    
    try:
        ctx = ssl.create_default_context()
        ctx.check_hostname = False
        ctx.verify_mode = ssl.CERT_NONE
        
        req = Request(url, headers=headers, method=method)
        
        # Handle request body
        if 'body' in config:
            req.data = interpolate(config['body'], context).encode()
            
        with urlopen(req, timeout=30, context=ctx) as resp:
            body = resp.read().decode('utf-8', errors='ignore')
            try:
                return json.loads(body)
            except:
                return {'raw': body}
    except URLError as e:
        return {'error': str(e)}

Technical Analysis

The HTTP action accepts an arbitrary workflow-controlled URL and passes it directly to urlopen(). It does not enforce an allowed scheme or host, resolve and inspect the destination address, prohibit private or link-local networks, or validate redirect destinations.

A workflow can therefore cause the host to make requests using its own network position. Potential targets include loopback services, private network interfaces, internal administrative APIs, and cloud instance metadata services. The returned content is retained as an action result and can be sent by a subsequent HTTP or Telegram action.

Because headers and request bodies are also workflow-controlled, the feature can make authenticated or sp ...[truncated 1177 chars]

Remediation
View remediation

Remediation Suggestions

  • Restrict outbound requests to explicitly approved HTTPS origins.
  • Parse URLs before use and reject embedded credentials, malformed hosts, and unsupported schemes.
  • Resolve destination hosts and reject loopback, private, link-local, multicast, unspecified, and reserved IP address ranges for both IPv4 and IPv6.
  • Explicitly block cloud metadata destinations.
  • Disable redirects or validate every redirect target using the same scheme, hostname, and resolved-address policy.
  • Protect against DNS rebinding by connecting only to a validated resolved address while preserving correct TLS hostname validation.
  • Apply separate allowlists for each workflow or action rather than one unrestricted global network permission.
  • Limit response sizes and maintain connection and read timeouts.
  • Run the workflow process in a network sandbox that cannot reach internal management networks or metadata services.

T08 · Insecure Dependencies

Warning
Location
SKILL.md:12
Finding

Unpinned and Unnecessary Runtime Dependency Installation

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:12-15
Vulnerability Type: Uncontrolled third-party dependency resolution
Risk Level: Medium

Vulnerable Code

bash
# Install dependencies
pip install schedule requests

Technical Analysis

The installation command resolves mutable package versions from the configured Python package index without a lockfile, version constraints, or integrity hashes. This makes installation non-reproducible and allows future package releases to alter the code installed on users' systems.

The documented dependencies also do not match the implementation. schedule is not imported, while requests is optional and is not used by the request execution path. Conversely, the script imports yaml, but the documentation does not explicitly declare the required PyYAML distribution. Installing unnecessary packages expands the supply-chain attack surface beyond the minimum needed by the Skill.

No evidence of typosquatting or a known malicious package is present; the risk arises from unsafe and excessive dependency installation practices.

Attack Path

  1. A user follows the documented installation command.
  2. pip resolves the latest available releases from the configured package repository.
  3. A compromised maintainer account, package repository, mirror, or malicious future release supplies altered package content.
  4. Package installation or later import executes the supplied code with the user's permissions.
  5. The malicious dependency can access files, credentials, environment variables, and network resources available to that user.

Impact Assessment

A compromised dependency could execute arbitrary code with the permissions of the installing or running user. This could expose workflow secrets and local files or alter workflow behavior. Unnecessary dependencies increase exposure without contributing to the declared functionality.

Remediation
View remediation

Remediation Suggestions

  • Remove schedule and requests if the implementation does not use them.
  • Explicitly declare the required PyYAML package.
  • Maintain reviewed, exact dependency versions in a lockfile.
  • Require package hashes during installation, such as through a hash-locked requirements file.
  • Use a trusted package index and controlled build environment.
  • Add automated dependency vulnerability and provenance scanning.
  • Regularly update pinned versions through a reviewed process rather than resolving unconstrained versions during installation.
Vulnerability Patterns
  • 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
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (19)

Tainted flow: 'req' from os.environ.get (line 81, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/workflow.py (reported line 87)May include surrounding context.

python
if 'body' in config:
            req.data = interpolate(config['body'], context).encode()
            
        with urlopen(req, timeout=30, context=ctx) as resp:
            body = resp.read().decode('utf-8', errors='ignore')
            try:
                return json.loads(body)

Tainted flow: 'req' from os.environ.get (line 81, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
97% confidence
Finding

The Telegram action reads TELEGRAM_BOT_TOKEN from the environment and embeds it directly into the outbound request URL, causing secret material to be transmitted and potentially exposed via logs, proxies, monitoring tools, or error traces. Because TLS verification is also disabled, a network attacker could intercept the request and recover the bot token, enabling account takeover of the bot.

Content

Scanner excerpt · scripts/workflow.py (reported line 118)May include surrounding context.

python
headers={'Content-Type': 'application/json'})
    
    try:
        with urlopen(req, context=ctx) as resp:
            return json.loads(resp.read())
    except URLError as e:
        return {'error': str(e)}

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/examples.md (reported line 94)May include surrounding context.

python scripts/workflow.py --file examples/daily-report.yaml --daemon

With environment

python scripts/workflow.py --file examples/daily-report.yaml --env .env

text

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

Both HTTP and Telegram actions explicitly disable hostname checking and certificate validation, which removes HTTPS authenticity guarantees. This allows man-in-the-middle interception or tampering of workflow traffic, including API payloads and secrets such as the Telegram bot token, making the automation context especially dangerous because it routinely sends data to external services unattended.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill documents capabilities that involve network access and environment-variable use, but it does not declare any explicit tool scope or permission boundaries. That omission can cause an agent or operator to invoke the skill without clear consent expectations, increasing the risk of unintended outbound requests or secret exposure through workflow actions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill advertises webhook, HTTP, Telegram, email, and storage actions without warning that user data may be sent to third parties or persisted. In an automation context, users may supply payloads, credentials, or business data that are then automatically transmitted or stored, creating privacy, compliance, and data-leakage risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The examples and script usage encourage scheduled and daemonized automation but do not warn that such workflows can run unattended and repeatedly interact with external systems. This increases the blast radius of mistakes, because a misconfigured workflow can continue making requests, sending messages, or altering state without ongoing human review.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 82)May include surrounding context.

md
- type: http
    name: get-sales
    config:
      url: https://api.shop.com/sales
  - type: transform
    name: format
    config:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The examples demonstrate workflows that send data to Telegram and persist data to local storage, but they do not warn users that these actions may disclose sensitive information externally or leave data at rest on disk. In an automation skill, examples are likely to be copied directly, so omission of disclosure and storage cautions can lead to accidental leakage of business or personal data.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 38)May include surrounding context.

md
- name: fetch-metrics
    type: http
    config:
      url: https://api.example.com/metrics
      method: GET
      
  - name: format-report

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · references/examples.md (reported line 15)May include surrounding context.

md
- name: fetch-metrics
    type: http
    config:
      url: https://api.example.com/metrics
      method: GET
      
  - name: format-report

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · references/examples.md (reported line 62)May include surrounding context.

md
- name: fetch-new
    type: http
    config:
      url: https://api.source.com/items?since={{last_sync}}
      
  - name: transform
    type: transform

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The documentation includes a realistic .env file containing a bot token but does not warn users to protect the file, rotate exposed secrets, or avoid committing it to version control. Publishing or reusing example credentials can normalize unsafe secret handling and may directly expose a usable token if the example is real.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The runner loads arbitrary key/value pairs into the process environment and exposes the full os.environ object to workflow template context. In a workflow engine that can make HTTP and Telegram requests, this creates a broad secret-access and exfiltration surface far beyond what is needed for simple automation, because workflows can reference environment values and send them to external endpoints.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The HTTP action builds requests from interpolated workflow context, including headers and optional body content, and transmits them with no confirmation prompt or user-facing notice. Aside from a generic docstring, the code does not disclose that workflow or environment-derived data may be sent to external endpoints.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The Telegram action accesses TELEGRAM_BOT_TOKEN directly from the environment, adding secret-handling capability that is not described in the skill metadata. In this workflow runner, that matters because the same process also evaluates template content and performs outbound network actions, increasing the chance that secrets are misused, leaked, or combined with other workflow data flows.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The Telegram action sends interpolated message content and chat identifiers to the Telegram API, which is a network transmission of workflow-derived data. The function has no confirmation prompt or visible disclosure to the user that external messaging will occur.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · scripts/workflow.py (reported line 107)May include surrounding context.

python
if not token:
        return {'error': 'TELEGRAM_BOT_TOKEN not set'}
    
    url = f'https://api.telegram.org/bot{token}/sendMessage'
    data = {'chat_id': chat_id, 'text': message}
    
    ctx = ssl.create_default_context()

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The code reads the TELEGRAM_BOT_TOKEN environment variable to authenticate outbound Telegram requests, but provides no explicit warning or comment highlighting credential use. For safety-sensitive credential access, the file lacks a user-facing disclosure beyond the variable name itself.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.