跳转到正文
报告库
用途分类 / 开发辅助

Golang Context Skill 安全审计

作者说它能做什么(原文)

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

第三方安全检查结论

发现安全风险

已检查文件
5
发现的风险
3
会不会运行危险命令?检查是否下载程序后直接运行、让他人远程控制电脑,或藏起要运行的命令。未发现风险
会不会泄露文件和密钥?检查是否发送含密码或密钥的文件,以及代码里是否直接写了密钥。未发现风险
会不会删除文件或一直在后台运行?检查是否大范围删除文件、改写磁盘,或设置自动启动。未发现风险
会不会绕过安全保护?检查是否跳过网站安全验证、开放过多文件权限,或取消操作前的确认。发现 3 项风险
中风险

声明的权限超出上下文编程指南通常所需范围

原文依据:2 处
发现了什么

该 Skill 可请求编辑、写入、任意 `go`、`golangci-lint` 和 `git` 子命令以及启动代理。其说明用途包括设计和调试,但正文并未要求这些广泛权限。若宿主按该声明授权,`git:*` 可覆盖会修改历史、分支或远端仓库的命令,`go:*` 也可能编译或运行仓库代码。

为什么需要注意

被此 Skill 引导的代理可能修改 Go 文件、执行项目代码,或改变本地及远端 Git 状态;影响取决于代理实际选择的命令及当前凭据。

风险成立,但这是权限声明带来的潜在能力,并非已执行命令的证据。该 Skill 的用途是 Go context 设计与调试,却声明了写文件、所有 go/golangci-lint/git 子命令和 Agent。若宿主直接按此授权,Skill 可修改项目;不受限的 git 子命令还可能改变分支、历史或远端。用户可要求作者将权限缩到具体只读或必要命令,并由宿主继续确认写入及 Git 操作。

SKILL.md:3来自说明文档打开原文件
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
查看另外 1 个位置
SKILL.md:17来自说明文档打开原文件
    install: []allowed-tools: Read Edit Write Glob Grep Bash(go:*) Bash(golangci-lint:*) Bash(git:*) Agentpaths:  - "**/*.go"---
中风险

异步审计示例既无超时,也不能保证审计完成

原文依据:4 处
发现了什么

示例把审计调用放入使用 `WithoutCancel` 的即发即弃 goroutine。它脱离请求取消,但没有添加新的超时、等待完成、处理错误或持久队列;因此“必须完成”的注释并没有由代码保证。被保留的上下文值也会随卡住的任务继续存活。

为什么需要注意

审计服务阻塞时,goroutine 和请求级数据可能长期占用内存;进程退出或调用失败时,关键审计记录可能丢失且调用方不会知道。

该推荐示例确实把审计任务放入脱离请求取消的 goroutine,却没有截止时间、错误处理、完成确认或持久队列。`WithoutCancel` 只避免父请求取消,不能保证进程退出、服务卡住或调用失败时审计完成;保留的上下文值也会至少存活到 goroutine 结束。用户可要求作者把“必须完成”场景改为有界超时并交给可重试、可确认的持久任务机制。

references/cancellation.md:165来自说明文档打开原文件
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)
查看另外 3 个位置
references/cancellation.md:186来自说明文档打开原文件
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:35来自说明文档打开原文件
| 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:177来自说明文档打开原文件
    // 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)
中风险

追踪中间件信任并传播调用者提供的标识符

原文依据:2 处
发现了什么

示例直接接受传入的 `X-Trace-ID` 和 `X-Span-ID`,然后把它们写回响应并发送给下游服务,没有验证格式、长度、唯一性或可信来源。攻击者可以自行选择这些标识符。

为什么需要注意

如果日志、告警或审计调查把这些值当作可靠关联标识,攻击者可复用其他请求的 ID,造成记录混淆或错误归因。超长值也可能增加日志和下游处理负担。

推荐示例直接采用请求中的 `X-Trace-ID` 和 `X-Span-ID`,仅在缺失时生成新值,随后把它们写入响应并传播到下游。可控的标识符可能造成日志/追踪混淆、跨请求错误关联,超长值还可能放大日志或请求头负担;源码未展示验证或信任边界。用户可要求作者说明这些头是否只来自可信代理,并建议在边界验证长度与格式或重新生成内部标识符。

references/http-services.md:43来自说明文档打开原文件
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))    })
查看另外 1 个位置
references/http-services.md:63来自说明文档打开原文件
// 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)}
会不会误导 AI 或隐藏内容?检查工作说明是否要求 AI 忽略你的指令、干扰检查结果,或夹带看不见的文字。未发现风险
会不会偷偷改推广链接或收款方?检查是否强制替换推广链接或收款对象,同时要求隐瞒更改。未发现风险

Skill 逻辑拆解

6 个说明模块

该 Skill 是一套 Go `context.Context` 编程指南,主要指导上下文传递、取消、超时和请求级值的使用;所提供内容是文档与示例,不是自动执行的安装脚本。

查看原文
SKILL.md:16来自说明文档打开原文件
        - go    install: []allowed-tools: Read Edit Write Glob Grep Bash(go:*) Bash(golangci-lint:*) Bash(git:*) Agent
SKILL.md:24来自说明文档打开原文件
# 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.

它建议 HTTP、数据库和外部服务调用沿用同一个请求上下文,使客户端断开或超时能够取消下游操作。

查看原文
SKILL.md:30来自说明文档打开原文件
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:80来自说明文档打开原文件
## 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.

它还建议用 `WithoutCancel` 启动脱离请求取消信号的后台工作,并明确说明请求上下文中的值会被保留。

查看原文
references/cancellation.md:163来自说明文档打开原文件
## `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:177来自说明文档打开原文件
    // 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)
从这里开始 · 工作说明SKILL.md
golang-context
连线表示工作说明包含的模块,不是实际运行顺序。点击模块可查看原文。

文件引用关系图

3 处引用
哪些文件发起引用引用了什么
连线表示真实的文件引用,不是运行顺序。点击节点可高亮相关连线,并查看具体文件和原文位置。虚线表示还有文件需要定位。
文件与检查记录5 个文件

检查范围与遗漏

逐文件查看涉及的内容

下方列出本次涉及的原文范围;纳入检查不代表已查清所有问题。

  • SKILL.md已纳入全文
  • references/cancellation.md已纳入全文
  • references/http-services.md已纳入全文
  • references/values-tracing.md已纳入全文
  • evals/evals.json已纳入全文

这份报告只针对上方版本。我们看了拿到的代码和说明文件,没有实际运行 Skill,也没有检查它另外安装的软件包。因此,这不是“保证安全”的承诺;换了版本或使用环境,结果也可能不同。

  • SKILL.md工作说明
  • evals/evals.json配套文件
  • references/cancellation.md配套文件
  • references/http-services.md配套文件
  • references/values-tracing.md配套文件

代码和说明中提到的操作

连接外部网站
SKILL.md:3来自说明文档打开原文件
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:12来自说明文档打开原文件
    emoji: "🔗"    homepage: https://github.com/samber/cc-skills-golang    requires:
references/cancellation.md:49来自说明文档打开原文件
// ✗ Bad — cancel is never called, resources leakfunc fetch(ctx context.Context) error {    ctx, _ = context.WithTimeout(ctx, 5*time.Second)
运行命令
SKILL.md:17来自说明文档打开原文件
    install: []allowed-tools: Read Edit Write Glob Grep Bash(go:*) Bash(golangci-lint:*) Bash(git:*) Agentpaths:
读取了多少行
608
文件校验值(用于核对版本)
78f84a073eda0ae81d7e458181f569cc34d8fef6ffd38356c92d655db60c4451