-
Notifications
You must be signed in to change notification settings - Fork 17
Add echo framework support #90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Reviewer's GuideAdds first-class support for the Go Echo web framework by introducing an echo entrypoint collector and shared taint/entrypoint utilities, generalizing Go analyzer import handling, and refactoring existing RESTful and main entrypoint checkers to use the new utilities. Sequence diagram for EchoEntrypointCollectChecker handling Echo route registrationsequenceDiagram
actor Dev
participant GoRuntime
participant Analyzer
participant CheckerManager
participant EchoEntrypointCollectChecker as EchoChecker
participant TaintUtil as processEntryPointAndTaintSource
participant IntroduceTaint
participant EntryPointUtil as completeEntryPoint
Dev->>GoRuntime: Start Echo server (e.g. e.GET("/path", handler, middlewares...))
GoRuntime->>Analyzer: Analyze CallExpression for e.GET
Analyzer->>CheckerManager: checkAtFunctionCallBefore(info with fclos, argvalues)
CheckerManager->>EchoChecker: triggerAtFunctionCallBefore(analyzer, scope, node, state, info)
EchoChecker->>EchoChecker: verify object._qid matches github.com/labstack/echo/v4.New()
EchoChecker->>EchoChecker: switch property.name (e.g. GET)
EchoChecker->>processEntryPointAndTaintSource: with handler argvalues[1], source 0
processEntryPointAndTaintSource->>processEntryPointAndTaintSource: flattenUnionValues([entryPointUnitValue]) and filter fclos
processEntryPointAndTaintSource->>processEntryPointAndTaintSource: deduplicate via processedRouteRegistry
processEntryPointAndTaintSource->>IntroduceTaint: introduceFuncArgTaintBySelfCollection(entryPointFuncValue, state, analyzer, source, GO_INPUT)
processEntryPointAndTaintSource->>completeEntryPoint: completeEntryPoint(entryPointFuncValue)
completeEntryPoint-->>processEntryPointAndTaintSource: entryPoint
processEntryPointAndTaintSource->>Analyzer: push entryPoint into analyzer.entryPoints
EchoChecker->>EchoChecker: handleMiddlewareArgs for remaining middleware args
EchoChecker-->>CheckerManager: return
CheckerManager-->>Analyzer: return
Analyzer-->>GoRuntime: continue analysis
Class diagram for updated Go analyzer and Echo/RESTful entrypoint checkersclassDiagram
class Analyzer {
+processCallExpression(scope, node, state, cachedFclos)
}
class GoAnalyzer {
+static knownPackageName : Record~string, string~
+static registerKnownPackageNames(knownPackageName : Record~string, string~)
+processCallExpression(scope, node, state, fclos)
}
class Checker {
}
class RestfulEntrypointCollectChecker {
+processedRouteRegistry : Set~string~
+constructor(resultManager)
+triggerAtFunctionCallBefore(analyzer, scope, node, state, info)
}
class EchoEntrypointCollectChecker {
+processedRouteRegistry : Set~string~
+constructor(resultManager)
+triggerAtFunctionCallBefore(analyzer, scope, node, state, info)
+triggerAtSymbolInterpretOfEntryPointAfter(analyzer, scope, node, state, info)
+triggerAtAssignment(analyzer, scope, node, state, info)
+handleConfigObjectCollection(analyzer, state, symbol)
+handleKnownEchoMiddlewares(analyzer, state, symbol)
+handleCustomMiddleware(analyzer, scope, state, middlewareFunctionValue)
+handleMiddlewareArgs(analyzer, scope, state, list)
}
class TaintEntryPointUtil {
+flattenUnionValues(list : Array~Unit~) Array~Unit~
+processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry : Set~string~, entryPointUnitValue : Unit, source : string)
}
Analyzer <|-- GoAnalyzer
Checker <|-- RestfulEntrypointCollectChecker
Checker <|-- EchoEntrypointCollectChecker
GoAnalyzer ..> TaintEntryPointUtil : uses
RestfulEntrypointCollectChecker ..> TaintEntryPointUtil : uses
EchoEntrypointCollectChecker ..> TaintEntryPointUtil : uses
GoAnalyzer ..> Checker : interacts
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Summary of ChangesHello @CrackTC, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly expands the analysis capabilities by adding comprehensive support for the Echo Go web framework. It enables the system to automatically detect and analyze potential security vulnerabilities by identifying entry points and taint sources within Echo applications. The changes also include a refactoring of existing entry point collection logic into reusable utilities and enhancements to the core Go analyzer for more accurate package import handling. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey there - I've reviewed your changes - here's some feedback:
- In
flattenUnionValuesandprocessEntryPointAndTaintSource, there are no guards forundefinedor unexpectedvtypes, so calls likeprocessEntryPointAndTaintSource(..., argvalues[2], ...)orflattenUnionValues(list)wherelistcontains non-union/fclos/symbol/object values can throw at runtime; consider short-circuiting on falsy inputs and skipping unknown vtypes instead of throwing. - Several places in the Echo checker (e.g.,
handleKnownEchoMiddlewares,triggerAtAssignment) index intosymbol.arguments[...]or nestedfieldproperties without checking that the argument exists, which can fail for partially-specified calls; adding length/null checks before access would make the logic more robust. - In
handleCustomMiddleware, you assumemiddlewareFunctionValue.fdefis present before callingprocessAndCallFuncDef; it would be safer to check forfdefand skip or log when it is missing to avoid errors on unexpected middleware values.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `flattenUnionValues` and `processEntryPointAndTaintSource`, there are no guards for `undefined` or unexpected `vtype`s, so calls like `processEntryPointAndTaintSource(..., argvalues[2], ...)` or `flattenUnionValues(list)` where `list` contains non-union/fclos/symbol/object values can throw at runtime; consider short-circuiting on falsy inputs and skipping unknown vtypes instead of throwing.
- Several places in the Echo checker (e.g., `handleKnownEchoMiddlewares`, `triggerAtAssignment`) index into `symbol.arguments[...]` or nested `field` properties without checking that the argument exists, which can fail for partially-specified calls; adding length/null checks before access would make the logic more robust.
- In `handleCustomMiddleware`, you assume `middlewareFunctionValue.fdef` is present before calling `processAndCallFuncDef`; it would be safer to check for `fdef` and skip or log when it is missing to avoid errors on unexpected middleware values.
## Individual Comments
### Comment 1
<location> `src/checker/taint/go/util.ts:10-19` </location>
<code_context>
+ *
+ * @param list
+ */
+export function flattenUnionValues(list: Array<Unit>): Array<Unit> {
+ return list.flatMap((unit) => {
+ switch (unit.vtype) {
+ case 'union':
+ return flattenUnionValues(unit.value)
+ case 'fclos':
+ case 'symbol':
+ case 'object':
+ return [unit]
+ default:
+ throw new Error(`flattenUnionValues: Unknown type ${unit.vtype}`)
+ }
</code_context>
<issue_to_address>
**issue:** flattenUnionValues throws on unknown vtype, which can make the whole analysis brittle.
Because this helper throws on any unrecognised `unit.vtype`, the checker can crash whenever union values contain other valid types (e.g. literals, `UndefinedValue`) or when new vtypes are added. Instead of throwing, consider ignoring non-relevant vtypes (or logging and skipping them) so union flattening degrades gracefully and the echo/restful detection remains robust as the value lattice evolves.
</issue_to_address>
### Comment 2
<location> `src/checker/taint/go/util.ts:37-40` </location>
<code_context>
+ analyzer: any,
+ state: any,
+ processedRouteRegistry: Set<string>,
+ entryPointUnitValue: Unit,
+ source: string
+) {
+ flattenUnionValues([entryPointUnitValue])
+ .filter((val) => val.vtype === 'fclos')
+ .forEach((entryPointFuncValue) => {
</code_context>
<issue_to_address>
**issue (bug_risk):** processEntryPointAndTaintSource assumes entryPointUnitValue is always defined, which may not hold at all call sites.
Some callers (e.g. `EchoEntrypointCollectChecker`, `RestfulEntrypointCollectChecker`) pass positions like `argvalues[1]` / `argvalues[2]` and also slice argument arrays without bounds checks, so `entryPointUnitValue` may be `undefined`. In that case `flattenUnionValues([entryPointUnitValue])` will fail because it expects a `Unit`. Consider either early-returning when `entryPointUnitValue` is missing/invalid or updating `flattenUnionValues` to safely handle `undefined` entries.
</issue_to_address>
### Comment 3
<location> `src/checker/taint/go/echo-entrypoint-collect-checker.ts:231-226` </location>
<code_context>
+ case 'File':
+ this.handleMiddlewareArgs(analyzer, scope, state, argvalues.slice(2))
+ break
+ case 'FileFS':
+ flattenUnionValues([argvalues[2]]).forEach((fs) => {
+ processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, fs.field.Open, '0')
+ })
+ this.handleMiddlewareArgs(analyzer, scope, state, argvalues.slice(3))
+ break
+ case 'Host':
</code_context>
<issue_to_address>
**issue (bug_risk):** FileFS handling assumes the third argument is always present and shaped as expected.
In the `FileFS` branch, `flattenUnionValues([argvalues[2]])` and `fs.field.Open` will throw if fewer than three args are passed or if the third arg isn’t an object with a `field` property. Please add defensive checks around `argvalues[2]` (and its expected shape) before calling `flattenUnionValues` and accessing `.field.Open`.
</issue_to_address>
### Comment 4
<location> `src/checker/taint/go/echo-entrypoint-collect-checker.ts:339-347` </location>
<code_context>
+ case 'KeyAuth':
+ processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, symbol.arguments[0], '0, 1')
+ break
+ case 'WithConfig':
+ flattenUnionValues([symbol.arguments[0]]).forEach((middlewareConfig) => {
+ const tokenLookupFuncs = middlewareConfig.field.TokenLookupFuncs
+ if (!tokenLookupFuncs) return
+ Object.values(tokenLookupFuncs.value).forEach((v) => {
+ processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, v as Unit, '0')
+ })
+ })
+ this.handleConfigObjectCollection(analyzer, state, symbol)
+ break
+ case 'NewMiddlewareWithConfig':
</code_context>
<issue_to_address>
**issue (bug_risk):** Some middleware config handlers assume `middlewareConfig.field` is always defined.
In this and similar cases (`NewMiddlewareWithConfig`, `MiddlewareWithConfig`, etc.), `middlewareConfig.field` is accessed (`TokenLookupFuncs` / `LabelFuncs` / `Store`) without checking that `field` exists. If the config is partially constructed or from a mismatched library version, `field` could be `undefined` and cause a crash. Please add a guard on `middlewareConfig.field` (or use optional chaining) before dereferencing it.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces support for the Echo web framework in the Go taint analyzer, which is a great addition. The implementation includes a new checker for Echo entry points and middleware, along with necessary configuration updates. I appreciate the refactoring work to create shared utilities (util.ts), which improves code reuse and maintainability by centralizing logic previously duplicated in the go-restful checker. The optimizations in the core analyzer to cache function closure evaluation are also a welcome improvement.
I've found a few potential null-reference issues in the new Echo checker that could cause the analyzer to crash. I've left specific suggestions to fix them. Overall, this is a solid contribution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR is being reviewed by Cursor Bugbot
Details
Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.
To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.
Summary by Sourcery
Add Echo framework entrypoint and middleware taint collection support and improve Go analyzer import resolution and entrypoint handling.
New Features:
Enhancements:
Note
Adds Echo framework support for Go (entrypoint collection + taint rules), refactors shared taint utils, and improves Go analyzer import handling and call processing.
checker/taint/go/echo-entrypoint-collect-checker.tsto collect Echo routes/middlewares and register taint sources/entrypoints.checker/taint/go/util.tswithflattenUnionValuesandprocessEntryPointAndTaintSourcefor deduped entrypoint/taint handling.echo-entrypoint-collect-checkerinresource/checker/checker-config.jsonand include intaint-flow-golang-defaultpack.resource/example-rule-config/rule_config_go.json): add Echoecho.Context.Bindas source and Echo sinks (Context.Render,HTML,JSON).Analyzer.processCallExpressionnow accepts cachedfclos; Go analyzer passes it to avoid recomputation.GoAnalyzer: addregisterKnownPackageNamesand use it to fix default import names; minor call/var-decl logic updates.Written by Cursor Bugbot for commit 9bd06c4. This will update automatically on new commits. Configure here.