Skip to content

fix(security): remediate audit findings#15

Merged
Iron-Mark merged 3 commits into
mainfrom
codex/security-remediation
May 20, 2026
Merged

fix(security): remediate audit findings#15
Iron-Mark merged 3 commits into
mainfrom
codex/security-remediation

Conversation

@Iron-Mark
Copy link
Copy Markdown
Owner

@Iron-Mark Iron-Mark commented May 20, 2026

Summary

  • harden fee sponsorship, proof metadata, CSP, amount parsing, opportunity escrow, and docs drift from the security findings pass

  • add focused frontend, Playwright, and Soroban contract coverage for the remediated behavior

Changes Made

Fee Sponsorship

  • disable public browser auto-sponsorship by default and require server bearer authorization

  • validate sponsored XDR size, network, source, op count, fee ceiling, configured contract, and method allowlist

Proof Integrity and XSS

  • add nonce-based CSP middleware, escaped JSON-LD, URL sanitizers, safe metadata fetch bounds, and status-derived proof claims

  • prevent missing or non-verified proofs from making verified, payment-settled, or completed-work claims

Contract and Amount Safety

  • cap opportunity milestones at 24 and allow employer refund from submitted state

  • replace float amount parsing with strict exact decimal scaling and fix u64 opportunity IDs

Workflow and Docs

  • pin Stellar release workflow to an immutable SHA and narrow permissions

  • align env/docs/security notes with the hardened behavior and current contract state

Why

  • closes the CSV security findings as one coordinated hardening pass and keeps proof trust claims tied to verified on-chain state

Notes for Reviewers

  • verified with cargo test, frontend unit tests, lint, build, Playwright E2E, and git diff --check

Note

Medium Risk
Modifies on-chain Soroban contract escrow state rules (create_opportunity validation and refund_opportunity transitions), which can affect fund flows and requires careful review/testing despite added coverage.

Overview
Hardens the Soroban opportunity-escrow flow by capping milestone_count (max 24) during create_opportunity and allowing employers to refund_opportunity even after a candidate has moved the opportunity into Submitted, preventing escrow lock-in.

Expands the contract test suite (now 12 tests) with new coverage and snapshot fixtures for the milestone cap and the new refund transition, and updates documentation to reflect the updated error variant count, escrow behavior, and current contract baseline.

Tightens the GitHub release workflow by moving permissions to the job scope and pinning the reusable soroban-build-workflow reference to an immutable commit SHA.

Reviewed by Cursor Bugbot for commit c62e346. Bugbot is set up for automated code reviews on this repo. Configure here.

## Summary

- harden fee sponsorship, proof metadata, CSP, amount parsing, opportunity escrow, and docs drift from the security findings pass

- add focused frontend, Playwright, and Soroban contract coverage for the remediated behavior

## Changes Made

### Fee Sponsorship

- disable public browser auto-sponsorship by default and require server bearer authorization

- validate sponsored XDR size, network, source, op count, fee ceiling, configured contract, and method allowlist

### Proof Integrity and XSS

- add nonce-based CSP middleware, escaped JSON-LD, URL sanitizers, safe metadata fetch bounds, and status-derived proof claims

- prevent missing or non-verified proofs from making verified, payment-settled, or completed-work claims

### Contract and Amount Safety

- cap opportunity milestones at 24 and allow employer refund from submitted state

- replace float amount parsing with strict exact decimal scaling and fix u64 opportunity IDs

### Workflow and Docs

- pin Stellar release workflow to an immutable SHA and narrow permissions

- align env/docs/security notes with the hardened behavior and current contract state

## Why

- closes the CSV security findings as one coordinated hardening pass and keeps proof trust claims tied to verified on-chain state

## Notes for Reviewers

- verified with cargo test, frontend unit tests, lint, build, Playwright E2E, and git diff --check
@vercel
Copy link
Copy Markdown

vercel Bot commented May 20, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
stellaroid-earn-demo Ready Ready Preview, Comment May 20, 2026 10:45am

@Iron-Mark
Copy link
Copy Markdown
Owner Author

@codex please review this security remediation PR.

## Summary

- enable allowImportingTsExtensions so CI typecheck accepts the Node strip-types test imports

## Changes Made

### Typecheck

- update frontend tsconfig to match the .ts import style used by the new unit tests

## Why

- GitHub Actions failed at npx tsc --noEmit because test files import local modules with explicit .ts extensions

## Notes for Reviewers

- locally verified npx tsc --noEmit --incremental false --pretty false, npm run test:unit, npm run lint, and git diff --check
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

submissionXdr = await requestFeeBump(signedXdr);

P2 Badge Pass sponsor auth token when client sponsorship is enabled

When NEXT_PUBLIC_FEE_SPONSOR_CLIENT_ENABLED=1 and a sponsor address is configured, signAndSubmit calls requestFeeBump(signedXdr) without the required bearer token. requestFeeBump now throws immediately for missing authorization, and that exception is swallowed, so gasless mode silently never activates even when the client-side sponsorship flag is enabled.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread frontend/src/lib/security.ts Outdated
Comment thread frontend/src/lib/security.ts
Comment thread frontend/src/lib/contract-client.ts Outdated
## Summary

- tighten proof metadata URL validation and private host filtering

- keep opportunity IDs lossless through frontend routing and contract calls

- remove misleading browser fee-sponsor auto toggle and update docs

## Changes Made

### URL and SSRF Hardening

- require HTTPS for external proof metadata/evidence URLs

- block IPv4-mapped IPv6 loopback/private hostnames

### Opportunity IDs

- add shared opportunity ID normalization that preserves string and bigint values

- use lossless IDs for opportunity pages, records, and u64 contract calls

### Fee Sponsorship

- keep fee bump as explicit server-authorized flow and remove public client auto-sponsor config

## Why

- resolves ChatGPT Codex connector comments on PR #15 before merge

## Notes for Reviewers

- verified with unit tests, typecheck, lint, build, E2E, and git diff --check
@Iron-Mark Iron-Mark merged commit 0242dfa into main May 20, 2026
4 checks passed
@Iron-Mark Iron-Mark deleted the codex/security-remediation branch May 20, 2026 10:49
@Iron-Mark
Copy link
Copy Markdown
Owner Author

@codex closeout update:

Fixed and shipped the proof preview data-binding issue.

  • Commit: fdd06c4 (fix(security): checkpoint proof preview and deployment alignment)
  • Production: https://stellaroid.tech redeployed and aliased successfully
  • Contract: CDMUOHMARNVOJZM3IVOCJUPGBHDTHFBMZCCZXEZPQDVJGILH3NIKTTW3

What changed:

  • ProofBlockPreview now prefers real credential titles from registration / lookup records.
  • AppExperience now carries credentialTitle and credentialStatus into the preview.
  • Non-demo hashes fall back to neutral Pending Issuance, not the bootcamp demo title.
  • Added focused unit coverage for non-demo title binding and neutral fallback.

Verification:

  • npm run test:unit: 15 passed
  • npm run lint: passed
  • npm run build: passed locally and in Vercel production build
  • npm run test:e2e: 5 passed
  • Live smoke passed for home, status, health, proof metadata JSON, verified proof, OG image, unknown-proof neutral behavior, and fee-bump disabled/public rejection.

@chatgpt-codex-connector
Copy link
Copy Markdown

Acknowledged — based on your @codex closeout update trigger and PR context, no additional code changes are required from me at this point.

I validated that the referenced fix commit is present on the current branch:

  • cd /workspace/Hackathon-Stellaroid_Earn && git status --short && git log --oneline -n 5

The log includes:

  • fdd06c4 fix(security): checkpoint proof preview and deployment alignment

Since there were no new local changes to commit, I did not create another commit and did not call make_pr (per your workflow constraints).

View task →

@Iron-Mark
Copy link
Copy Markdown
Owner Author

@codex closeout update for the two follow-up findings:

Fixed and shipped:

  • Metadata URL SSRF: fixed by removing server-side fetch of issuer-supplied metadata URLs. Proof metadata now derives from on-chain certificate fields and known demo fallback data; safe metadata URLs are kept only as evidence links. Also tightened trailing-dot private-host normalization.
  • Stale proof preview title: fixed by clearing preview title state when a newly loaded credential record has a blank/whitespace title, so the preview falls back to neutral copy instead of retaining the previous credential title.

Commits:

  • 73ebfbe fix(security): harden proof metadata and preview state
  • b8a4170 fix(test): repair proof preview typecheck

Production:

Verification:

  • Local npm run test:unit: 17 passed
  • Local npm run lint: passed
  • Local npm run build: passed
  • Local npm run test:e2e: 5 passed
  • GitHub main CI for b8a4170: passed build, lint, typecheck, and Playwright E2E
  • Live smoke passed for home, status, health, proof metadata JSON, verified proof, proof OG image, unknown-proof neutral behavior, and fee-bump disabled/public rejection.

@chatgpt-codex-connector
Copy link
Copy Markdown

Acknowledged — based on this new closeout update and the PR context, I did not make additional code changes.

I verified the branch already contains the two shipped follow-up commits you listed:

  • 73ebfbe fix(security): harden proof metadata and preview state
  • b8a4170 fix(test): repair proof preview typecheck

Because there were no new local edits to apply, I did not create a new commit and did not open a follow-up PR.

Checks run

  • cd /workspace/Hackathon-Stellaroid_Earn && git status --short && git log --oneline -n 8

View task →

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