跳到正文
cccskills
免费在 GitHub 公开

go-security-pitfalls

Use when reviewing Go changes - net/http and Fiber handlers, database/sql and GORM queries, os/exec, filepath and os.Root, html/template, crypto, TLS and SSH clients, JSON binding

中文简介正在准备中。当前显示原文说明。

查看安装方法

包含的文件(1)

  • SKILL.md6.0 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

Go Security Pitfalls

Overview

Go removes whole classes of bugs (memory safety, implicit shell, unsafe default deserialization), which makes the remaining ones look innocent: a fmt.Sprintf in a query builder, a HasPrefix path check, a template.HTML conversion. Memory-safety findings in pure Go are excluded; unsafe and cgo are the exception.

1. SQL: database/sql, sqlx, GORM (CWE-89)

// ❌
db.QueryContext(ctx, fmt.Sprintf("SELECT * FROM tasks WHERE owner = '%s'", owner))
// ✅
db.QueryContext(ctx, "SELECT * FROM tasks WHERE owner = $1", owner)

GORM accepts raw SQL in more places than people expect:

// ❌ all of these take SQL text
db.Where(fmt.Sprintf("name = '%s'", name)).Find(&users)
db.Order(r.URL.Query().Get("sort")).Find(&users)   // ORDER BY injection
db.First(&user, r.PathValue("id"))                // a string id is used as an inline condition
db.Raw("SELECT … " + filter).Scan(&rows)
// ✅
db.Where("name = ?", name).Find(&users)
db.Order(clause.OrderByColumn{Column: clause.Column{Name: sortCols[key]}}).Find(&users)
db.First(&user, "id = ?", id)

2. Commands: os/exec (CWE-78, CWE-88)

exec.Command never invokes a shell — unless you pass sh -c. With separate args the risk is argument injection:

// ❌ shell
exec.Command("sh", "-c", "git clone "+repoURL).Run()
// ❌ no shell, but repoURL = "--upload-pack=…" is an option
exec.Command("git", "clone", repoURL, dir).Run()
// ✅
exec.Command("git", "clone", "--", repoURL, dir).Run()

Also check cmd.Env built from request data (NODE_OPTIONS, LD_PRELOAD, GIT_SSH_COMMAND — injection-and-dangerous-sinks).

3. Paths: filepath, os.Root (CWE-22)

// ❌ lexical check: a symlink inside base escapes it, and
//    "/srv/data-other/x" passes HasPrefix(p, "/srv/data")
p := filepath.Join(base, name)
if !strings.HasPrefix(p, base) { … }

// ✅ Go 1.24+: lookups confined to the root, symlinks included
root, err := os.OpenRoot(base)
f, err := root.Open(name)
// ✅ older Go: reject anything non-local before joining
if !filepath.IsLocal(name) { return errBadPath }

http.FileServer(http.Dir(dir)) blocks .. but follows symlinks inside dir and serves dotfiles — a finding when dir is the repo root or an upload directory. Archive extraction: check filepath.IsLocal(hdr.Name) per entry.

4. Templates (CWE-79)

  • html/template escapes by context; text/template does not — rendering HTML with text/template is XSS when data is user-controlled.
  • Conversions switch escaping off: template.HTML(userBio), template.JS(…), template.URL(…), template.HTMLAttr(…) on user data.
  • template.New("x").Parse(userText) — the user writes the template (server-side template injection; with registered funcs that touch the system, worse).

5. JSON Binding (CWE-915)

// ❌ the request decodes straight into the domain type, Role and OrgID included
var u domain.User
json.NewDecoder(r.Body).Decode(&u)
// ✅ a request DTO with only client-settable fields, mapped explicitly
var req struct{ Name, Email string }
json.NewDecoder(r.Body).Decode(&req)

encoding/json matches keys case-insensitively and lets the last duplicate win: a gateway or validator that checks "role" misses "ROLE". Relevant only when a different component validates the raw JSON.

6. Crypto and Transport (CWE-295, CWE-338)

  • math/rand / math/rand/v2 for tokens → crypto/rand (rand.Text() in Go 1.24+).
  • tls.Config{InsecureSkipVerify: true} on a production client.
  • ssh.InsecureIgnoreHostKey() → MITM on every SSH connection (CWE-322).
  • Secret comparison: subtle.ConstantTimeCompare / hmac.Equal (a note at most when missing).

7. HTTP Handlers and Middleware

  • A route added on the bare router/app instead of the authenticated group (security-diff-review-method).
  • http.Redirect(w, r, r.URL.Query().Get("next"), http.StatusFound) — open redirect; high confidence only.
  • Client IP from X-Forwarded-For or a Fiber/Echo/Gin proxy-header setting without a trusted-proxy list, used for an allowlist or an auth decision.
  • An error from the authorization lookup that falls through to the handler (fail open).
  • Outbound http.Client fetching user URLs: use a dialer Control check and Proxy: nil (ssrf-and-url-allowlists).

8. unsafe and cgo

unsafe.Pointer arithmetic, unsafe.Slice/unsafe.String over attacker-sized buffers, and C code reached through cgo are memory-unsafe again — trace sizes and lengths from input (native-memory-safety-and-ffi has the bounds, integer and cgo pointer rules).

Common Mistakes

  • Reporting exec.Command(bin, args...) as shell injection.
  • Reporting db.Query("… $1", v) or GORM Where("x = ?", v) as SQL injection.
  • Reporting gopkg.in/yaml.v3 or encoding/gob as unsafe deserialization — they do not instantiate arbitrary types.
  • Reporting races between goroutines on non-security state, or integer-conversion lint hits (gosec G115) with no attacker-controlled size.

Red Flags

  • fmt.Sprintf feeding Query, Exec, Raw, Where, Order, Group, Having.
  • "sh", "-c" / "bash", "-c" in exec.Command.
  • strings.HasPrefix on a joined path.
  • template.HTML( around anything not a constant.
  • InsecureSkipVerify: true, InsecureIgnoreHostKey(), math/rand near "token" or "secret".

References (names and links only)

Go security best practices · os.Root (Go 1.24) · gosec rules · GORM security · govulncheck

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases

中文简介正在准备中。当前显示原文说明。

makifbaysal/tasktrooper1172026年10月21日 更新

Use when the diff adds or changes an endpoint, resolver, RPC, job or query that takes an object id, a role check, a request binding or a tenant filter - BOLA/IDOR, function-level authorization, mass assignment and tenant scoping

中文简介正在准备中。当前显示原文说明。

makifbaysal/tasktrooper1172026年10月21日 更新

Use on every UI change - semantic HTML, labels for controls, keyboard-navigable dialogs/menus, visible focus, and never color as the only signal

中文简介正在准备中。当前显示原文说明。

makifbaysal/tasktrooper1172026年10月21日 更新

Use when a task changes any screen, form, dialog, menu or control - Lighthouse/axe scan of the changed screens, a keyboard walk, and the thresholds that fail a task

中文简介正在准备中。当前显示原文说明。

makifbaysal/tasktrooper1172026年10月21日 更新

How to work a task returned with review, QA or UAT findings. Use when a task is in need_revision or PR review comments are in your context.

中文简介正在准备中。当前显示原文说明。

makifbaysal/tasktrooper1172026年10月21日 更新

Use when the repository keeps its alerting in code, or a person asks for alerts outside TaskTrooper - PrometheusRule YAML, a Cloud Monitoring alert policy in Terraform, a Datadog monitor, each routed to TaskTrooper's alert ingest URL so it opens an incident here

中文简介正在准备中。当前显示原文说明。

makifbaysal/tasktrooper1172026年10月21日 更新

查看 makifbaysal 的全部技能

报告此技能的问题