Skip to content

fix(security): resolve open code-scanning alerts (XSS, int-conversion, cookie, CI perms)#108

Merged
jkyberneees merged 1 commit into
mainfrom
fix/code-scanning-alerts
Jul 26, 2026
Merged

fix(security): resolve open code-scanning alerts (XSS, int-conversion, cookie, CI perms)#108
jkyberneees merged 1 commit into
mainfrom
fix/code-scanning-alerts

Conversation

@jkyberneees

Copy link
Copy Markdown
Contributor

Summary

Resolves all 12 open alerts from GitHub code scanning in one PR. Each was assessed before fixing — all were valid (none dismissed as false positives).

High

  • go/incorrect-integer-conversion (internal/danger/classifier.go, internal/skills/importer.go) — both inet_aton-style IP parsers truncated out-of-range parts: 300.1.1.1 parsed as 44.1.1.1, and 10.300.1.1 as 10.44.1.1 (a private address — directly relevant to the SSRF/internal-IP checks these parsers feed). Both now validate per inet_aton rules (leading parts ≤ 0xFF; final part fits the remaining bytes) and reject invalid input, matching browser semantics. Regression cases pinned in TestParseBrowserIP and the importer's isPrivateHost table.
  • go/incomplete-url-scheme-check (cmd/odek/browser_tool.go) — link extraction only skipped lowercase javascript:. Now filters javascript:, data:, and vbscript: case-insensitively. New TestBrowser_SkipsDangerousLinkSchemes proves all three schemes (plus caps variants) are excluded while safe links survive.
  • js/xss (cmd/odek/ui/app.js) — formatNum passed non-numeric values through String(n) straight into innerHTML. It now coerces to a finite number; the latency stat is coerced the same way, so a crafted event value can never reach the DOM as markup.
  • js/xss-through-dom (cmd/odek/ui/app.js) — renderFileChips built chips via innerHTML with a file name in the flow. Rewritten with createElement/textContent + addEventListener (also drops the inline onclick).
  • js/double-escaping (cmd/odek/ui/app.js) — escapeAttr replaced & last, producing ". & is now replaced first.

Medium

  • go/cookie-secure-not-set (cmd/odek/serve.go) — the WS-token cookie now sets Secure: true. This is safe for the bundled UI because it always also sends the token as a WebSocket subprotocol (odek.<token>) and as the X-Odek-Ws-Token header on /api/*, so a browser that drops the cookie on plain-http loopback loses nothing (comment explains this).
  • actions/missing-workflow-permissions (×4) — top-level permissions: contents: read added to test.yml and release.yml. The release job keeps its explicit permissions: contents: write override; no job needs more.

Verification

  • go test ./... -count=1 ✅ (28 packages), go vet ./... ✅, golangci-lint run ./... → 0 issues ✅
  • node --check cmd/odek/ui/app.js
  • New regression tests: IP bound cases (both packages), browser scheme filter

…, cookie, CI perms)

Addresses all 12 open alerts from GitHub code scanning:

High:
- go/incorrect-integer-conversion (classifier.go, skills/importer.go):
  both inet_aton-style IP parsers now reject out-of-range parts instead of
  silently truncating (300.1.1.1 no longer parses as 44.1.1.1; 10.300.1.1
  no longer slips into the private range as 10.44.1.1), matching browser
  semantics and protecting the SSRF/internal-IP checks downstream.
- go/incomplete-url-scheme-check (browser_tool.go): link extraction now
  filters javascript:, data:, and vbscript: case-insensitively.
- js/xss (ui/app.js): formatNum coerces to a finite number and the latency
  stat is coerced, so crafted non-numeric values can never reach innerHTML
  as markup.
- js/xss-through-dom (ui/app.js): renderFileChips builds DOM nodes with
  textContent instead of innerHTML.
- js/double-escaping (ui/app.js): escapeAttr replaces & first so quote
  entities are no longer double-escaped.

Medium:
- go/cookie-secure-not-set (serve.go): the WS-token cookie sets
  Secure: true. The UI always also authenticates via WebSocket subprotocol
  and /api header, so browsers that drop the cookie lose nothing.
- actions/missing-workflow-permissions: top-level
  permissions: contents: read in test.yml and release.yml (the release job
  keeps its explicit contents: write).

Regression tests: IP bound cases in both packages, browser scheme-filter
test. Full test suite, vet, golangci-lint, and node --check all pass.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 26, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
odek 6813f02 Commit Preview URL

Branch Preview URL
Jul 26 2026, 10:26 AM

@jkyberneees
jkyberneees merged commit 3218d72 into main Jul 26, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant