Back to skill

Security audit

Go Patterns

Security checks for vulnerabilities and agentic risk

Overview

This is a Go best-practices reference skill with no executable payload, persistence, or hidden data access, though one HTTP example should be copied with size limits added.

This skill is reasonable to install as Go reference material. Treat its snippets as starting points, especially the HTTP client sample: add status checks, response-size limits, and real timeout/client configuration before using it in production.

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 (1)

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:41
Finding

Unbounded HTTP Response Buffering Can Cause Memory Exhaustion

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 41–47
Vulnerability Type: Unbounded resource consumption
Risk Level: Medium

Vulnerable Code:

go
func FetchData(ctx context.Context, url string) ([]byte, error) {
    req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
    if err != nil { return nil, err }
    resp, err := http.DefaultClient.Do(req)
    if err != nil { return nil, err }
    defer resp.Body.Close()
    return io.ReadAll(resp.Body)
}

Technical Analysis

The example is presented as a production-ready HTTP pattern but passes resp.Body directly to io.ReadAll. This operation continues allocating memory until the response reaches EOF or an error occurs, with no application-level maximum response size.

A context deadline limits how long the request may run, but it does not establish a memory limit. A malicious or compromised server can transmit a large response rapidly enough to exhaust substantial memory before the deadline. The example also does not inspect the HTTP status or declared Content-Length before buffering the body.

Because this is documentation rather than executable project code, exploitation requires a downstream application to adopt the pattern and request an attacker-controlled, compromised, or redirectable endpoint.

Attack Path

  1. A downstream application implements the documented FetchData pattern.
  2. The application requests a URL controlled by an attacker, or an otherwise trusted endpoint is compromised or redirects to an attacker-controlled server.
  3. The server responds with a very large or continuously generated body.
  4. io.ReadAll(resp.Body) repeatedly expands its in-memory buffer without enforcing a size ceiling.
  5. The process experiences elevated memory consumption and may be terminated by the operating system or become unavailable.

Impact Assessment

Successful exploitation can cause application-level den ...[truncated 360 chars]

Remediation
View remediation

Remediation Suggestions

Enforce an application-specific response-size limit before fully buffering the body:

  1. Check Content-Length when present and reject values above the configured maximum.
  2. Wrap the response body with io.LimitReader, using maxSize + 1 so the application can detect overflow.
  3. Return an explicit error when the response exceeds the limit.
  4. Validate the HTTP status code before reading the response body.
  5. Retain context deadlines and configure an http.Client with appropriate transport and timeout settings.

Example hardened pattern:

go
const maxResponseSize int64 = 10 << 20 // 10 MiB

func FetchData(ctx context.Context, url string) ([]byte, error) {
    req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
    if err != nil {
        return nil, fmt.Errorf("create request: %w", err)
    }

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        return nil, fmt.Errorf("perform request: %w", err)
    }
    defer resp.Body.Close()

    if resp.StatusCode &lt; 200 || resp.StatusCode &gt;= 300 {
        return nil, fmt.Errorf("unexpected HTTP status: %s", resp.Status)
    }
    if resp.ContentLength &gt; maxResponseSize {
        return nil, fmt.Errorf("response exceeds %d-byte limit", maxResponseSize)
    }

    data, err := io.ReadAll(io.LimitReader(resp.Body, maxResponseSize+1))
    if err != nil {
        return nil, fmt.Errorf("read response: %w", err)
    }
    if int64(len(data)) &gt; maxResponseSize {
        return nil, fmt.Errorf("response exceeds %d-byte limit", maxResponseSize)
    }
    return data, nil
}
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 (1)

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 53)May include surrounding context.

// Caller controls the timeout ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() data, err := FetchData(ctx, "https://api.example.com/data")

text

### errgroup for Concurrent Tasks

Static analysis

No suspicious patterns detected.