Security-focused release
An external report of a cross-patient data leak in Conditions led us to audit every route for the same bug class. We found and fixed two more instances, plus a related "reassignment" gap across four routes. New Semgrep rules now catch this class of bug automatically in CI going forward.
Highlights
- Fixed a cross-patient PHI leak in Conditions (GHSA-37f5-3f8c-qxww), plus two related leaks found in Medications and Diagnostic Studies
- Fixed a reassignment IDOR pattern across Appointments, Diagnostic Studies, Prescriptions, and Test Results
/api/system/databasenow requires admin auth (previously reachable by anyone)- Removed a hardcoded JWT secret fallback
- Tightened CORS, added
helmet()security headers, and added a CSP header on the frontend - Pinned all GitHub Actions to commit SHAs
- The app version is now shown in the sidebar and baked into the release image
Upgrade notes
No database migration in this release. Pull and restart, no extra steps needed.
If you have a custom integration, read this part: if anything besides the bundled frontend calls the API directly from browser JavaScript (a separate dashboard, a browser extension), CORS now blocks that by default. Set CORS_ORIGIN in your .env to the calling origin(s) to keep it working. Native mobile apps and server-to-server calls aren't affected, since CORS only restricts browser JavaScript.
Full details in the changelog.
What's Changed
- docs: lead CHANGELOG's 2.0.0 entry with a breaking-changes callout by @DMJoh in #158
- Minor changes to changelog by @DMJoh in #159
- docs: rework SCREENSHOTS.md into a GIF walkthrough + stills by @DMJoh in #160
- docs: center-align the walkthrough GIF by @DMJoh in #161
- docs: tighten SCREENSHOTS.md link wording by @DMJoh in #162
- Revamp documentation with GIF walkthrough and updated visuals by @DMJoh in #163
- test: close file-upload coverage gaps in test-results and diagnostic-studies by @DMJoh in #164
- fix: address SonarQube maintainability findings (53 of 76) by @DMJoh in #165
- refactor: dedupe RowActions (9 list pages) and PhysicianLink (2 detail pages) by @DMJoh in #167
- fix: correctly resolve the S3358/S3776 fixes PR #165 only half-fixed by @DMJoh in #166
- fix: close cross-patient IDOR in condition detail (GHSA-37f5-3f8c-qxww) by @DMJoh in #168
- fix: two more cross-patient IDORs found by an audit of every route by @DMJoh in #169
- fix: revert incorrect DELETE-guard scoping + wire up Semgrep for this bug class by @DMJoh in #170
- fix: test-results reassignment IDOR + fix a real bug in the Semgrep rule itself by @DMJoh in #171
- refactor: dedupe SonarQube-flagged duplicated blocks across routes and Users.jsx by @DMJoh in #172
- fix: frontend CSP header + pin remaining GitHub Actions by @DMJoh in #173
- docs: add 2.1.0 changelog entry by @DMJoh in #174
- feat: report the real app version through /api/health by @DMJoh in #175
- feat: show the app version in the sidebar footer by @DMJoh in #176
- Release 2.1.0 by @DMJoh in #177
Full Changelog: 2.0.0...2.1.0