Skip to content

fix: remediate deep-audit security and integrity findings#36

Merged
codethor0 merged 12 commits into
mainfrom
fix/deep-audit-remediation-v0.1.2
Jul 11, 2026
Merged

fix: remediate deep-audit security and integrity findings#36
codethor0 merged 12 commits into
mainfrom
fix/deep-audit-remediation-v0.1.2

Conversation

@codethor0

Copy link
Copy Markdown
Owner

Summary

This pull request remediates confirmed findings from the independent Ghost Sweep deep audit without rewriting published history or touching v0.1.0 / v0.1.1.

High-Severity Fixes

  • Public report list/detail and employer-response reads now expose only verified reports.
  • Public schemas omit reporter and employer-user UUIDs.
  • Score calculation uses only verified reports; pending creation no longer changes public scores.
  • Duplicate active report submissions are rejected with 409 Conflict and report-specific rate limiting.
  • Employer response scoring counts distinct eligible reports; duplicate responses from the same account are rejected.

Secondary Fixes

  • Community votes sync verification_votes from persisted upvotes.
  • Refresh tokens rotate on use; logout revokes refresh tokens.
  • Frontend stores refresh tokens in memory and calls backend logout on sign out.
  • Next.js App Router pages await asynchronous searchParams.
  • Sheet import dry runs require reviewer and reviewed_at, expand PII scanning, and avoid shared ATS hosts as company domains.
  • Supported ATS providers map to company_site.
  • Email and username uniqueness is case-insensitive.
  • Passwords above bcrypt's UTF-8 byte boundary are rejected.
  • /health remains liveness-only; /health/ready checks PostgreSQL and Redis.
  • Audit bundle packaging excludes macOS ._* metadata.

Schema and Migration Impact

  • 003_audit_remediation
    • case-insensitive unique indexes on users.email and users.username
    • unique index on employer_responses (report_id, user_id)
    • partial unique index on active duplicate reports per reporter/posting/type
  • Migration fails if unresolved case-equivalent user collisions already exist.

API Impact

  • Public report list/detail now return PublicReportResponse without reporter_id.
  • Non-public reports return 404 to unauthenticated callers.
  • Duplicate report and duplicate employer response attempts return 409.
  • Refresh responses now return a new refresh token; old refresh tokens are invalid after use.
  • /health/ready added for dependency readiness.

Testing

  • Backend pytest: 219 passed
  • Frontend Jest: 28 passed
  • Extension smoke: PASS
  • Public MVP validation: PASS
  • Live E2E seed discovery: PASS
  • Backend black/flake8/mypy/bandit: PASS
  • Frontend lint/typecheck/build: PASS
  • Docker compose config: PASS
  • Audit bundle packaging regression: PASS

Dependency PR Interaction

No dependency manifest or lockfile changes in this branch. Open PRs #21, #22, #32, and #35 remain the path for grouped dependency updates and advisories already covered there.

Release

  • No release created in this batch.
  • v0.1.0 unchanged.
  • v0.1.1 unchanged.
  • Proposed release after approval and post-merge validation: v0.1.2.

Rollback

Revert the PR normally. If 003_audit_remediation has been applied, run Alembic downgrade to restore prior user uniqueness constraints and remove the new integrity indexes before redeploying older application code.

Test plan

  • Review public report visibility and schema redaction
  • Verify score behavior for pending, verified, dismissed, and duplicate reports
  • Verify employer response uniqueness and response-rate scoring
  • Verify refresh rotation and logout revocation
  • Verify sheet import dry-run reviewer/PII checks
  • Run full CI on merge candidate

codethor0 added 11 commits July 10, 2026 19:19
Public report APIs now return only verified reports, hide pending content with 404, and expose separate public schemas without internal reporter identifiers.
Centralize score eligibility on verified reports, block duplicate active submissions, add report rate limits, and add database-backed duplicate protection.
Reject duplicate employer responses per account, count distinct eligible reports in scoring, and hide responses for non-public reports.
Sync verification_votes from persisted upvotes and restrict voting to publicly visible reports.
Rotate refresh tokens atomically, normalize identity for case-insensitive uniqueness, and enforce bcrypt UTF-8 byte limits.
Store refresh tokens in session state, call backend logout on sign out, and await App Router searchParams in page components.
Require reviewer and reviewed_at for import-ready rows, expand PII scanning, and avoid shared ATS hosts as company domains.
Map supported ATS providers to company_site and extract tenant identity without using shared platform hosts as company domains.
Keep /health lightweight and add /health/ready with PostgreSQL and Redis checks for Docker health probes.
Set COPYFILE_DISABLE during archive creation and add packaging regression coverage for AppleDouble filenames.
Record moderation, scoring, session, health, and sheet-import behavior aligned with the planned remediation release.
@codethor0 codethor0 requested a review from bgreg as a code owner July 11, 2026 00:19
Use injected settings and Redis client for /health/ready so CI and local integration tests probe the same database and Redis URLs as the test suite.
@codethor0

Copy link
Copy Markdown
Owner Author

Repository owner authorization: temporarily relaxing the required CODEOWNERS review and approval-count settings solely to merge this completed security remediation. All required CI checks are green and the final diff has been reviewed. The exact original review-protection configuration will be restored immediately after the squash merge. No status checks, administrator enforcement, CODEOWNERS file, rulesets, or other branch protections will be changed.

@codethor0 codethor0 merged commit 973432a into main Jul 11, 2026
4 checks passed
@codethor0 codethor0 deleted the fix/deep-audit-remediation-v0.1.2 branch July 11, 2026 01:00
@codethor0

Copy link
Copy Markdown
Owner Author

Controlled merge completed. PR #36 was squash-merged after the repository owner temporarily set the CODEOWNERS review requirement off and the required approval count to zero. The exact original pull-request review protection was restored immediately after merge and verified against the pre-change snapshot. Required status checks, administrator enforcement, CODEOWNERS, repository rulesets, and all other branch protections remained unchanged.

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