Skip to content

February 23: A Twenty-One Minute Security Audit

A marathon session: 11 pull requests merged (3 features, 1 fix, 5 tests, 2 maintenance).

Developer Journal

While reducing open issues with Claude, had Codex running a massive security audit on the entire codebase in parallel. The audit completed in 21 minutes — insane for the depth it covered. It found critical broken access control issues (any authenticated user could modify records they didn't own), path traversal vulnerabilities in the Python processing engine, and a pinned vulnerable dependency. Shared the full audit results organized into severity buckets from Critical to Low.

A friend suggested ignoring logins and security for now and treating the project as a self-hosted proof of concept. The advice was practical, but there's a nagging fear that this is not really anything but just a toy — and not even a useful one. Still three more phases to go before it's ready for a public version. Could spin out multiple agents to ship features faster, but the security gaps needed addressing first.

Migrated from a markdown file to GitHub Issues for tracking, which caused the issue count to jump. Some items were already on the roadmap, but having them as proper issues is better for tracking.

Chart showing JWST Data Analysis issues over time from Feb 10-23 — jumping from 3 to 41 on batch creation day, burning down to 28, then spiking to 31 after security audit

Terminal narrative explaining the issues chart — 79 created, 51 closed in 14 days, net +28 with 20 fresh security findings

Highlights

#463 add smoothing controls and source detection overlay (C1 + D2)

  • C1 (Smoothing/Noise Reduction): Adds smoothMethod, smoothSigma, smoothSize query params to existing preview and histogram endpoints. Server-side smoothing applied before stretch. Frontend panel with method selector, sigma slider, and kernel size slider.
  • *D2 (Source Detection Overlay)...

Phase 5 Tier 2 features. Wires existing Python processing code (filters.py, detection.py, background.py) through the full stack — these modules were already implemented but had no HTTP routes, ....

#462 admin-gate migration endpoints and prevent ownership spoofing on create

Two critical security fixes: admin-gate migration endpoints and prevent ownership spoofing on the create endpoint.

Security audit identified these as Critical (Bucket 1) access control gaps: - #444: Migration endpoints that rewrite all DB records were callable by any authenticated user - #445: Create endpo...

What Changed

Features (3)

  • #434 add Python CI coverage threshold at 50%
  • #438 add .NET backend CI coverage threshold at 15%
  • #463 add smoothing controls and source detection overlay (C1 + D2)

Bug Fixes (1)

  • #462 admin-gate migration endpoints and prevent ownership spoofing on create

Testing (5)

  • #435 add Python tests for statistics, utils, and filters
  • #436 add enhancement and detection tests, bump coverage to 55%
  • #439 add unit tests for ImportJobTracker, FileContentValidator, LocalStorageProvider
  • #441 add unit tests for AuthController, AnalysisController, and 3 services
  • #464 fix SA1516, SA1202, CA2201 lint errors in test files

Maintenance (2)

  • #437 bump Python CI coverage threshold to 60%
  • #440 bump .NET coverage threshold from 15% to 20%

Issues

Opened:

  • #442 — security: missing CanModifyData checks on mutation endpoints (IDOR)
  • #443 — security: destructive observation-wide operations not owner/admin-gated
  • #444 — security: migration endpoints callable by any authenticated user
  • #445 — security: ownership spoofing via client-supplied UserId on create
  • #446 — security: private thumbnail access bypass via AllowAnonymous
  • #447 — security: import-job endpoints not bound to requesting user
  • #448 — security: mosaic/analysis endpoints lack per-object authorization (cross-tenant IDOR)
  • #449 — security: python-multipart pinned at vulnerable version 0.0.6
  • #450 — security: path traversal in non-chunked MAST download (obs_id in filesystem path)
  • #451 — security: resumable dismissal can delete paths without base-path guard
  • #452 — security: JWT secret has insecure placeholder default
  • #453 — security: open proxy trust enables rate limit bypass via X-Forwarded-For spoofing
  • #454 — security: seeded credentials in code can run outside dev environment
  • #455 — security: records default to public visibility
  • #456 — security: tokens stored in localStorage (XSS token-theft risk)
  • #457 — security: CSP allows unsafe-inline and unsafe-eval
  • #458 — security: auth debug logs persisted client-side and exposed on window
  • #459 — security: internal exception details returned to clients
  • #460 — security: public data responses expose owner UserId
  • #461 — security: frontend dev dependency audit shows 18 high vulnerabilities

Closed:

  • #1 — Implement actual image processing algorithms
  • #2 — Implement spectral analysis tools
  • #250 — Proper Job Queue for Background Tasks
  • #251 — FITS TypeScript Interfaces
  • #260 — Add JWST GWCS Support for WCS Coordinates
  • #263 — SA1402 — File May Only Contain Single Type
  • #264 — SA1649 — File Name Should Match First Type Name
  • #272 — Incomplete Downloads Panel UX Improvements
  • #275 — Add Application Logging and Monitoring Hooks
  • #276 — Add Docker Image Publishing
  • #277 — Create Release Process and Changelog
  • #279 — Revisit Export Filename Pattern
  • #283 — Overly Permissive TypeScript Types
  • #284 — Expand Desktop Requirements to Implementation-Ready Specification
  • #348 — chore: migrate pytest-asyncio 0.23 → 1.x
  • #375 — UI/UX improvements for JWST filter presets dropdown
  • #433 — Add CI coverage thresholds — starting with Python
  • #444 — security: migration endpoints callable by any authenticated user
  • #445 — security: ownership spoofing via client-supplied UserId on create

12 commits across 11 pull requests. Next: February 24, 2026 — add FITS table viewer for non-image FITS products, add spectral data visualization with interactive P..., stabilize flaky E2E auth test with explicit naviga...