Skip to content
Report library
Purpose / Development

Golang Context Skill Security Audit

What the author says it does (original text)

Idiomatic context.Context usage in Golang — propagation through API boundaries, cancellation, timeouts and deadlines, request-scoped values, context.WithoutCancel for background work outliving requests. Apply when designing context propagation across layers, debugging leaked or unexpired contexts, choosing between context.Background/TODO/WithoutCancel, or storing values in context. Not for code th

Independent security check

Security risks found

Files checked
5
Risks found
3
Could it run dangerous commands?Looks for programs run straight after downloading, remote control of your computer, and hidden commands.No risks found
Could it expose your files or keys?Looks for uploads of files containing passwords or keys, and keys written directly in the code.No risks found
Could it delete files or keep running?Looks for broad file deletion, disk overwrites, and programs set to start automatically.No risks found
Could it bypass safety checks?Looks for skipped website security checks, excessive file access, or actions that skip your approval.Risks found: 3
Medium risk

Declared permissions exceed what a context-programming guide normally needs

Source references: 2
What we found

The Skill requests editing, writing, unrestricted `go`, `golangci-lint`, and `git` subcommands, plus agent creation. Its stated scope includes design and debugging, while the body does not require these broad permissions. If enforced literally, `git:*` can include commands that change history, branches, or remotes, and `go:*` can compile or execute repository code.

Why this matters

An agent guided by this Skill could modify Go files, execute project code, or alter local or remote Git state. The actual impact depends on the commands selected and credentials available.

The risk is supported as potential capability, not evidence that any command ran. The Skill covers Go context design and debugging but declares file writes, every go/golangci-lint/git subcommand, and Agent. If a host grants these literally, it could modify the project, while unrestricted git commands could affect branches, history, or remotes. A user can ask the author to restrict permissions to specific necessary commands and require host confirmation for writes and Git operations.

SKILL.md:3In the instructionsOpen original file
name: golang-contextdescription: "Idiomatic context.Context usage in Golang — propagation through API boundaries, cancellation, timeouts and deadlines, request-scoped values, context.WithoutCancel for background work outliving requests. Apply when designing context propagation across layers, debugging leaked or unexpired contexts, choosing between context.Background/TODO/WithoutCancel, or storing values in context. Not for code that merely accepts ctx as first parameter."user-invocable: true
Show 1 other places
SKILL.md:17In the instructionsOpen original file
    install: []allowed-tools: Read Edit Write Glob Grep Bash(go:*) Bash(golangci-lint:*) Bash(git:*) Agentpaths:  - "**/*.go"---
Medium risk

The asynchronous audit example has neither a timeout nor a completion guarantee

Source references: 4
What we found

The example launches the audit call as a fire-and-forget goroutine using `WithoutCancel`. It escapes request cancellation but adds no new timeout, completion wait, error handling, or durable queue, so the comment that it “must complete” is not enforced. Retained context values also remain reachable while a call is stuck.

Why this matters

A blocked audit service can retain goroutines and request-scoped data indefinitely. A process exit or failed call can lose an important audit record without notifying the caller.

The recommended example launches the audit in a goroutine detached from request cancellation, with no deadline, error handling, completion acknowledgment, or durable queue. `WithoutCancel` only prevents parent cancellation; it cannot ensure completion if the process exits, the service hangs, or the call fails. Preserved context values also remain reachable until the goroutine ends. Users can ask for a bounded timeout and a durable, retryable, acknowledged job mechanism when completion is mandatory.

references/cancellation.md:165In the instructionsOpen original file
Creates a child context that is not cancelled when the parent is. Use this for background work that must continue after the request completes — like async logging, audit trails, or enqueuing follow-up tasks.```gofunc (h *Handler) CreateOrder(w http.ResponseWriter, r *http.Request) {    ctx := r.Context()    order, err := h.orderService.Create(ctx, req)    if err != nil {        // handle error        return    }    // Audit log must complete even if the client disconnects.    // WithoutCancel preserves context values (trace_id) but detaches cancellation.    auditCtx := context.WithoutCancel(ctx)    go h.auditService.LogOrderCreated(auditCtx, order)
Show 3 other places
references/cancellation.md:186In the instructionsOpen original file
Without `WithoutCancel`, you'd have to choose between `ctx` (which gets cancelled when the handler returns, killing your background work) and `context.Background()` (which loses trace_id and other values). `WithoutCancel` gives you the best of both: values are preserved, but cancellation is detached.
references/values-tracing.md:35In the instructionsOpen original file
| Data | Context value? | Why || --- | --- | --- || trace_id, span_id, request_id | Yes | Request-scoped metadata for observability || Authenticated user/tenant | Yes | Request-scoped, crosses API boundaries || Database connection | No | Infrastructure dependency, pass explicitly || Feature flags | No | Configuration, pass explicitly or inject || Function arguments (user ID, order data) | No | Business logic parameters, pass as arguments || Logger | Depends | OK if enriched with request-scoped fields (trace_id); otherwise pass explicitly |
references/cancellation.md:177In the instructionsOpen original file
    // Audit log must complete even if the client disconnects.    // WithoutCancel preserves context values (trace_id) but detaches cancellation.    auditCtx := context.WithoutCancel(ctx)    go h.auditService.LogOrderCreated(auditCtx, order)
Medium risk

Tracing middleware trusts and propagates caller-supplied identifiers

Source references: 2
What we found

The example directly accepts incoming `X-Trace-ID` and `X-Span-ID`, writes them into the response, and forwards them downstream without validating format, length, uniqueness, or trusted origin. A caller can therefore choose these identifiers.

Why this matters

If logs, alerts, or audit investigations treat the values as reliable correlation identifiers, an attacker can reuse IDs from other requests and cause confusing or incorrect attribution. Oversized values may also increase logging and downstream processing load.

The recommended middleware accepts `X-Trace-ID` and `X-Span-ID` from the request, generates replacements only when absent, then returns and forwards those values. Caller-controlled identifiers can confuse logs/traces or falsely correlate requests; oversized values can also increase logging or header costs. No validation or trust boundary is shown. Users can ask whether only a trusted proxy may supply these headers and require format/length checks or fresh internal identifiers at the boundary.

references/http-services.md:43In the instructionsOpen original file
func TracingMiddleware(next http.Handler) http.Handler {    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {        traceID := r.Header.Get("X-Trace-ID")        if traceID == "" {            traceID = generateTraceID()        }        spanID := r.Header.Get("X-Span-ID")        if spanID == "" {            spanID = generateSpanID()        }        ctx := context.WithValue(r.Context(), traceIDKey, traceID)        ctx = context.WithValue(ctx, spanIDKey, spanID)        w.Header().Set("X-Trace-ID", traceID)        w.Header().Set("X-Span-ID", spanID)        next.ServeHTTP(w, r.WithContext(ctx))    })
Show 1 other places
references/http-services.md:63In the instructionsOpen original file
// Propagate trace context to downstream servicesfunc (c *HTTPClient) Do(ctx context.Context, method, url string, body io.Reader) (*http.Response, error) {    req, err := http.NewRequestWithContext(ctx, method, url, body)    if err != nil {        return nil, fmt.Errorf("creating request: %w", err)    }    if traceID, ok := ctx.Value(traceIDKey).(string); ok {        req.Header.Set("X-Trace-ID", traceID)    }    if spanID, ok := ctx.Value(spanIDKey).(string); ok {        req.Header.Set("X-Span-ID", spanID)    }    return c.client.Do(req)}
Could it mislead the AI or hide text?Checks the skill instructions for requests to ignore you, influence the report, or hide text in invisible characters.No risks found
Could it change links or payment recipients without asking?Looks for forced referral or payment changes combined with instructions to hide the change.No risks found

Inside this skill

6 instruction sections

This Skill is a Go `context.Context` programming guide covering propagation, cancellation, timeouts, and request-scoped values. The provided content consists of instructions and examples rather than an automatically executed installer.

View source
SKILL.md:16In the instructionsOpen original file
        - go    install: []allowed-tools: Read Edit Write Glob Grep Bash(go:*) Bash(golangci-lint:*) Bash(git:*) Agent
SKILL.md:24In the instructionsOpen original file
# Go context.Context Best Practices`context.Context` is Go's mechanism for propagating cancellation signals, deadlines, and request-scoped values across API boundaries and between goroutines. Think of it as the "session" of a request — it ties together every operation that belongs to the same unit of work.

It recommends carrying the same request context through HTTP, database, and external-service calls so client disconnection or timeout can cancel downstream work.

View source
SKILL.md:30In the instructionsOpen original file
1. Propagate the same context through the entire request lifecycle: HTTP handler → service → DB → external APIs — any link that starts a fresh context keeps working after the client is gone.2. Take `ctx` as the first parameter, named `ctx context.Context` — the fixed position is what makes context-aware APIs recognizable at a glance and what linters check.3. Pass context through function parameters instead of storing it in a struct — the struct outlives the request that filled it, so later calls reuse a context that is already cancelled or belongs to someone else.4. Pass `context.TODO()` rather than a `nil` context — `nil` panics on the first `Done()` or `Value()` call, far from the caller that passed it.5. Call `cancel()` on all control-flow paths for `WithCancel`/`WithTimeout`/`WithDeadline`, unless ownership of the context and cancel function is explicitly returned or transferred — an uncalled `cancel()` keeps the child attached to its parent and leaks its timer until the parent finishes.6. Create `context.Background()` only at top-level entry points (main, init, tests). Deeper in the call chain — especially mid-request — it detaches the work from the caller's deadline and cancellation, the propagation break shown below.7. Use `context.TODO()` as a placeholder when a context is needed but none exists yet — it marks the gap for a later fix instead of hiding it behind a `Background()` that looks deliberate.
references/http-services.md:80In the instructionsOpen original file
## Context in Calls to Other ServicesContext MUST be propagated to all HTTP clients and databases using context-aware APIs: `http.NewRequestWithContext`, `QueryContext`, `ExecContext`, and `QueryRowContext`. This ensures that client disconnections cancel all downstream operations.

It also recommends `WithoutCancel` for background work detached from request cancellation and explicitly notes that values from the request context are retained.

View source
references/cancellation.md:163In the instructionsOpen original file
## `context.WithoutCancel` (Go 1.21+)Creates a child context that is not cancelled when the parent is. Use this for background work that must continue after the request completes — like async logging, audit trails, or enqueuing follow-up tasks.
references/cancellation.md:177In the instructionsOpen original file
    // Audit log must complete even if the client disconnects.    // WithoutCancel preserves context values (trace_id) but detaches cancellation.    auditCtx := context.WithoutCancel(ctx)    go h.auditService.LogOrderCreated(auditCtx, order)
Start here · InstructionsSKILL.md
golang-context
Lines connect the instruction file to its sections, not an observed execution order. Select a section to read the source.

File reference map

References: 3
Files making referencesReferenced content
Lines show actual file references, not execution order. Select a node to highlight its connections and inspect the files and source locations. Dashed lines include files that still need locating.
Files and check records5 files

Coverage and gaps

Content covered in each file

These are the source ranges included in this check, not a guarantee that every issue has been resolved.

  • SKILL.mdFull text included
  • references/cancellation.mdFull text included
  • references/http-services.mdFull text included
  • references/values-tracing.mdFull text included
  • evals/evals.jsonFull text included

This report is for the version above. We read the available code and instructions without running the skill or checking extra packages it installs. This is not a promise of safety: a different version or setup may behave differently.

  • SKILL.mdInstructions
  • evals/evals.jsonSupporting file
  • references/cancellation.mdSupporting file
  • references/http-services.mdSupporting file
  • references/values-tracing.mdSupporting file

Operations mentioned in code and instructions

Connect to websites
SKILL.md:3In the instructionsOpen original file
name: golang-contextdescription: "Idiomatic context.Context usage in Golang — propagation through API boundaries, cancellation, timeouts and deadlines, request-scoped values, context.WithoutCancel for background work outliving requests. Apply when designing context propagation across layers, debugging leaked or unexpired contexts, choosing between context.Background/TODO/WithoutCancel, or storing values in context. Not for code that merely accepts ctx as first parameter."user-invocable: true
SKILL.md:12In the instructionsOpen original file
    emoji: "🔗"    homepage: https://github.com/samber/cc-skills-golang    requires:
references/cancellation.md:49In the instructionsOpen original file
// ✗ Bad — cancel is never called, resources leakfunc fetch(ctx context.Context) error {    ctx, _ = context.WithTimeout(ctx, 5*time.Second)
Run commands
SKILL.md:17In the instructionsOpen original file
    install: []allowed-tools: Read Edit Write Glob Grep Bash(go:*) Bash(golangci-lint:*) Bash(git:*) Agentpaths:
Lines read
608
File checksum (to compare versions)
78f84a073eda0ae81d7e458181f569cc34d8fef6ffd38356c92d655db60c4451