GitView CodeAudit: Go security reviews that never leave your laptop
本文为原文前 6,000 字符的节选翻译,完整内容请查看原文。
GitView CodeAudit: Go security reviews that never leave your laptop
Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle Submission 💸 This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle What I Built GitView CodeAudit is a security review for Go backends that runs on your laptop. A static analyzer finds the problems and collects the evidence; an open-weight model, Gemma running on Ollama, explains a finding when you ask, but it never decides one.
Hacktoberfest 开源 AI 挑战赛第 2 周:副业项目提交 💸 这是 Hacktoberfest 开源 AI 挑战赛第 2 周“副业”类别的提交作品。我构建了 GitView CodeAudit,这是一个在笔记本电脑上运行的 Go 后端安全审查工具。静态分析器负责发现问题并收集证据;当您询问时,运行在 Ollama 上的开源权重模型 Gemma 会对发现的问题进行解释,但它从不做出最终判定。
GitView started as my terminal tool for watching Git changes and studying Go code: call graph, data flow, SQL operations and HTTP routes, each with the evidence behind it. This week I built CodeAudit on top of those analyses. Who would pay for it? Freelancers and small agencies that build Go APIs for clients. Clients ask for a security review before a launch, a funding round or a big customer’s due diligence, and they pay for it. But that code usually comes under an NDA, and pasting it into a cloud AI tool is exactly what the contract forbids.
GitView 最初是我用来监控 Git 变更和研究 Go 代码的终端工具:包括调用图、数据流、SQL 操作和 HTTP 路由,每一项都有相应的证据支持。本周,我在这些分析的基础上构建了 CodeAudit。谁会为它买单?那些为客户构建 Go API 的自由职业者和小型代理机构。客户通常会在发布、融资轮次或大型客户尽职调查前要求进行安全审查,并为此付费。但这些代码通常受保密协议(NDA)约束,将其粘贴到云端 AI 工具中恰恰是合同所禁止的。
CodeAudit lets one developer do that review on their own laptop and hand over a real deliverable: an offline HTML report with each finding, the path that reaches it, the evidence, and the reviewer’s decision with its justification. That is the side hustle: the client pays for the review, and producing it costs nothing per token. Every finding answers the questions a client will ask: Where? File, line and function. Why? The rule, and the data that reaches the line, for example c.Query(“q”) → ”… LIKE ’%” + term + ”%’” → db.QueryContext. How is it reached? Every HTTP route that leads there, through each middleware, marking the one that authenticates.
CodeAudit 让开发者可以在自己的笔记本电脑上完成审查,并交付一份真正的成果:一份离线 HTML 报告,其中包含每个发现的问题、到达该问题的路径、证据,以及审查者的决定及其理由。这就是副业:客户为审查付费,而生成报告的 Token 成本为零。每一个发现都能回答客户会问的问题:在哪里?(文件、行号和函数)。为什么?(规则以及到达该行的数据,例如 c.Query(“q”) → ”… LIKE ’%” + term + ”%’” → db.QueryContext)。它是如何被触发的?(通往该处的每一条 HTTP 路由,经过每一个中间件,并标记出负责认证的那一个)。
How sure are we? Severity, confidence and verdict are separate fields. A possible IDOR is shown as Review Required — Authorization Not Established, never as “IDOR confirmed”. How do I fix it, and how do I test the fix? What did we decide? Open → Investigating → Confirmed / False Positive / Accepted Risk / Fixed, with a history of every change: its date, its justification and the commit it refers to.
我们有多确定?严重性、置信度和判定结果是分开的字段。一个可能的 IDOR(不安全直接对象引用)会被显示为“需要审查 — 授权未建立”,绝不会显示为“IDOR 已确认”。我该如何修复它,又该如何测试修复结果?我们决定了什么?状态包括:开启 → 调查中 → 已确认 / 误报 / 接受风险 / 已修复,并附有每次变更的历史记录:日期、理由以及所引用的提交。
Demo GitView is a local tool, so there is no deployed link: everything below runs on your machine. The repository ships a small vulnerable API, with safe variants of each case, that the tests use. You can reproduce these screenshots with it: git clone https://github.com/Darrkkens/gitview && cd gitview && go install . # Go 1.25 gitview audit scan —module internal/audit/testdata/app gitview audit serve —module internal/audit/testdata/app # opens 127.0.0.1 in the browser
演示:GitView 是一个本地工具,因此没有部署链接:以下所有内容都在您的机器上运行。该仓库附带了一个小型易受攻击的 API,以及测试所使用的每种情况的安全变体。您可以使用以下命令重现这些截图:git clone https://github.com/Darrkkens/gitview && cd gitview && go install . # Go 1.25 gitview audit scan —module internal/audit/testdata/app gitview audit serve —module internal/audit/testdata/app # 在浏览器中打开 127.0.0.1
A SQL injection: the route, the middleware chain and the handler lead to the query, and the inspector shows the evidence. The same finding explained by Gemma. Each evidence ID the model cites is checked against the analysis. A possible IDOR is a review, not a verdict. The resource ID comes from the request and the query has no owner or tenant condition, but authorization could live somewhere the static analysis cannot see. The report you hand to the client is a single offline HTML file. It has no network access, a strict CSP, and only bounded, redacted excerpts of the code.
SQL 注入:路由、中间件链和处理程序指向查询,检查器显示了证据。同样的发现由 Gemma 进行了解释。模型引用的每个证据 ID 都会与分析结果进行核对。可能的 IDOR 是一种审查,而非最终判定。资源 ID 来自请求,且查询中没有所有者或租户条件,但授权逻辑可能存在于静态分析无法触及的地方。您交给客户的报告是一个单一的离线 HTML 文件。它没有网络访问权限,具有严格的 CSP(内容安全策略),并且仅包含有限的、经过脱敏的代码片段。
How I Built It Static analysis first. CodeAudit has 18 deterministic rules for injection, authentication, authorization, sensitive data, configuration and dependencies. They run over analyses GitView already had: go/packages, go/types and SSA for the call graph and the data flow, the SQL operations, and the HTTP routes with their middleware chains. Taint: a taint finding is the shortest path in the data flow graph from an HTTP input to a sink. Sanitizers: they only count when their meaning is known. strconv.Atoi neutralizes everything and filepath.Base neutralizes paths; an arbitrary function call is not a sanitizer.
我是如何构建它的:首先是静态分析。CodeAudit 拥有 18 条确定性规则,涵盖注入、认证、授权、敏感数据、配置和依赖项。它们运行在 GitView 已有的分析之上:使用 go/packages、go/types 和 SSA 来处理调用图和数据流、SQL 操作以及带有中间件链的 HTTP 路由。污点分析:污点发现是指数据流图中从 HTTP 输入到接收端(sink)的最短路径。净化器(Sanitizers):只有当其含义已知时才会被计入。strconv.Atoi 可以中和所有内容,filepath.Base 可以中和路径;任意函数调用不被视为净化器。
Checks: an if that dominates the sink and examines the value, like if !allowed(origin), turns “vulnerable” into “review”, because the analyzer cannot prove the check is sufficient. Authorization: a 403 only counts as authorization when the request is already authenticated. A 403 from a CORS filter is shown as a request filter instead. Dependencies: they are checked only against a local copy of the Go vulnerability database (OSV format). Without one, the report says “dependencies not checked” instead of pretending, and a database older than 30 days is flagged as possibly out of date.
检查:如果一个 if 语句支配接收端并检查了值(例如 if !allowed(origin)),它会将“易受攻击”转变为“需要审查”,因为分析器无法证明该检查是充分的。授权:只有当请求已经过认证时,403 错误才会被计为授权。来自 CORS 过滤器的 403 错误则被显示为请求过滤器。依赖项:仅针对本地的 Go 漏洞数据库(OSV 格式)副本进行检查。如果没有该数据库,报告会显示“未检查依赖项”而不是伪造结果,且超过 30 天的数据库会被标记为可能已过期。
Gemma on Ollama, kept on a short leash. Model: by default GitView picks the smallest installed Gemma model (gemma3:4b on my machine). It never downloads one, and it refuses any endpoint that is not on this machine unless you pass —ai-allow-remote. Context: the context sent to the model is built from the analysis, not from a file dump. It holds the finding, its evidence, the route path and the function’s code, within a budget of about 6,000 tokens. Secrets are reda
运行在 Ollama 上的 Gemma,受到严格限制。模型:默认情况下,GitView 会选择安装的最小 Gemma 模型(在我机器上是 gemma3:4b)。它从不下载模型,并且拒绝任何非本地的端点,除非您传入 —ai-allow-remote 参数。上下文:发送给模型的上下文是根据分析结果构建的,而不是文件转储。它包含发现的问题、证据、路由路径和函数代码,总计约 6,000 个 Token。密钥已被脱敏。