Merged
Conversation
376ea5b to
b6f151a
Compare
Contributor
There was a problem hiding this comment.
4 issues found across 12 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="pkg/server/api/cookiebanner/v1/handler.go">
<violation number="1" location="pkg/server/api/cookiebanner/v1/handler.go:48">
P1: The new `/{bannerID}/config` handler returns a static `{\"status\":\"ok\"}` response instead of banner configuration, so SDK clients cannot fetch the data this endpoint is meant to provide.</violation>
</file>
<file name="pkg/server/api/api.go">
<violation number="1" location="pkg/server/api/api.go:186">
P1: `cfg.CookieBanner` is used without validation. A nil `CookieBanner` service will panic when the cookie-banner middleware handles requests.</violation>
</file>
<file name="contrib/claude/coredata.md">
<violation number="1" location="contrib/claude/coredata.md:177">
P3: The first migration bullet is incomplete and drops the explicit naming rule, making the guideline unclear.</violation>
</file>
<file name="pkg/coredata/cookie_banner.go">
<violation number="1" location="pkg/coredata/cookie_banner.go:188">
P1: `LoadActiveByOrigin` is not tenant-scoped, so origin lookups can return another tenant’s active banner when origins overlap.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
gearnode
reviewed
Apr 14, 2026
gearnode
reviewed
Apr 14, 2026
gearnode
reviewed
Apr 14, 2026
gearnode
reviewed
Apr 14, 2026
3b89d60 to
b273894
Compare
Contributor
There was a problem hiding this comment.
4 issues found across 15 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="pkg/server/api/cookiebanner/v1/handler.go">
<violation number="1" location="pkg/server/api/cookiebanner/v1/handler.go:170">
P1: `clientIP` can return the full `X-Forwarded-For` chain, which is not a single IP and bypasses anonymization (it gets stored raw when `ParseIP` fails). Parse and use only the first forwarded client IP before passing it to `RecordConsent`.</violation>
</file>
<file name="pkg/coredata/cookie_consent_record.go">
<violation number="1" location="pkg/coredata/cookie_consent_record.go:226">
P2: Make latest-consent selection deterministic by adding a secondary sort key.</violation>
</file>
<file name="pkg/validator/validator_format.go">
<violation number="1" location="pkg/validator/validator_format.go:163">
P2: Origin validation accepts malformed host values with an empty port suffix (e.g. `https://example.com:/`) because only `parsedURL.Host == ""` is checked.</violation>
</file>
<file name="pkg/coredata/migrations/20260413T130000Z.sql">
<violation number="1" location="pkg/coredata/migrations/20260413T130000Z.sql:15">
P1: Backfill/canonicalize existing `cookie_banners.origin` values before creating this unique index; otherwise canonical-equivalent legacy origins remain unenforced and can break origin matching.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
51397de to
a5da664
Compare
gearnode
reviewed
Apr 14, 2026
gearnode
reviewed
Apr 14, 2026
gearnode
reviewed
Apr 14, 2026
gearnode
reviewed
Apr 14, 2026
gearnode
reviewed
Apr 14, 2026
gearnode
reviewed
Apr 14, 2026
gearnode
reviewed
Apr 14, 2026
gearnode
reviewed
Apr 14, 2026
gearnode
reviewed
Apr 14, 2026
09aee7b to
6a1931f
Compare
5289e9f to
80d45c8
Compare
Signed-off-by: Émile Ré <emile@getprobo.com>
Strip www. prefix and trailing slash from origin when creating or updating a cookie banner so CORS lookups match regardless of whether the customer's site redirects www to the apex domain. Signed-off-by: Émile Ré <emile@getprobo.com>
Introduce /cookie-banner/v1/{bannerID}/config endpoint for the JS SDK.
The custom CORS middleware validates each request origin against the
specific banner being requested, preventing cross-customer leakage.
Signed-off-by: Émile Ré <emile@getprobo.com>
Signed-off-by: Émile Ré <emile@getprobo.com>
Signed-off-by: Émile Ré <emile@getprobo.com>
Signed-off-by: Émile Ré <emile@getprobo.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> Signed-off-by: Émile Ré <nemile.re@gmail.com> Signed-off-by: Émile Ré <emile@getprobo.com>
Implement config, consent retrieval, and consent recording endpoints for the JS SDK. IP addresses are anonymized (last octet zeroed for IPv4, /48 mask for IPv6) before storage. Signed-off-by: Émile Ré <emile@getprobo.com>
Parse only the first IP from X-Forwarded-For to prevent the full chain from bypassing anonymization. Add secondary sort key for deterministic consent selection. Reject origins with empty port suffix in the validator. Signed-off-by: Émile Ré <emile@getprobo.com>
Signed-off-by: Émile Ré <emile@getprobo.com>
Move clientIP extraction into a reusable pkg/server/api/clientip package with RFC 7239 Forwarded header support. Add pkg/server/jsonutil with helpers for common HTTP error responses (RenderForbidden, RenderInternalServerError, RenderNotFound, RenderBadRequest) and use them in the cookie banner handlers. Signed-off-by: Émile Ré <emile@getprobo.com>
Add coredata guide section on using Go enum constants as named SQL parameters instead of hardcoded string literals. Fix mixed inline/multiline RenderJSON call in cookie banner handler. Signed-off-by: Émile Ré <emile@getprobo.com>
Signed-off-by: Émile Ré <emile@getprobo.com>
Strip forwarded headers (Forwarded, X-Forwarded-For, X-Real-Ip) from requests originating from untrusted proxies at the HTTP server level, reusing the existing proxy-protocol trusted-proxies config. The clientip package is now a pure extraction helper; context plumbing and middleware wrappers are removed. Signed-off-by: Émile Ré <emile@getprobo.com>
80d45c8 to
e3ab373
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes ENG-271
Summary by cubic
Validate and canonicalize cookie banner origins, enforce one active banner per origin per tenant, and add public JS SDK endpoints (config, consent read/write) with per-banner CORS, CSRF bypass, and anonymized IP logging. Add
pkg/server/trustedproxyto strip untrusted forwarded headers and convertpkg/server/api/clientipinto an RFC 7239 extractor; addresses ENG-271.New Features
Origin()and canonicalization toscheme://host[:port](stripwww., remove trailing slash, no path/query/userinfo, reject empty port). Applied on create/update so CORS checks match.idx_cookie_banners_unique_active_origin; DB violations map toErrOriginAlreadyInUseon create/update/activate./cookie-banner/v1: GET/{bannerID}/config, GET/{bannerID}/consents/{visitorID}, POST/{bannerID}/consents. Per-banner CORS validates the requestOriginagainst the banner’s canonical origin; CSRF bypass added.Forwarded, then leftmostX-Forwarded-For; consent reads are deterministic (created_at then id desc). Addspkg/server/jsonutilerror helpers.pkg/server/trustedproxymiddleware stripsForwardedandX-Forwarded-Forfrom untrusted sources; wired into the API server using existing trusted-proxies config.pkg/server/api/clientipis now a pure extractor.Migration
Written for commit e3ab373. Summary will update on new commits.