Skip to content

fix: strict input validation on POST /api/goals#469

Open
advikdivekar wants to merge 4 commits into
Priyanshu-byte-coder:mainfrom
advikdivekar:fix/issue-454-goal-input-validation
Open

fix: strict input validation on POST /api/goals#469
advikdivekar wants to merge 4 commits into
Priyanshu-byte-coder:mainfrom
advikdivekar:fix/issue-454-goal-input-validation

Conversation

@advikdivekar
Copy link
Copy Markdown
Contributor

Problem

POST /api/goals accepted arbitrary values with no bounds checking:

  • target: 0 → division by zero in the frontend progress bar (0 / 0 * 100 = Infinity%)
  • target: -1 → a goal with current: 0 displayed as 100% complete
  • target: 0.5, NaN, 999999999 → silently stored
  • title had no length cap — a multi-MB string would be persisted and break layout
  • A malformed JSON body produced an unhandled 500 instead of a 400

Fix

src/app/api/goals/route.ts

  • req.json() wrapped in try/catch → returns 400 Invalid JSON on parse failure
  • title: must be a non-empty string, trimmed, ≤ 100 characters
  • target: must be an integer in [1, 10_000] — rejects 0, negatives, floats, NaN, and overflow values
  • unit: clamped to 30 characters silently
  • recurrence: unknown values default to "none" explicitly
  • All bounds defined as named constants at the top of the file

Test plan

  • POST /api/goals with target: 0 returns 400
  • POST /api/goals with target: -5 returns 400
  • POST /api/goals with target: 0.5 returns 400
  • POST /api/goals with target: 999999999 returns 400
  • POST /api/goals with a 101-character title returns 400
  • POST /api/goals with a whitespace-only title returns 400
  • POST /api/goals with malformed JSON returns 400
  • Valid goal creation still works as expected

Closes #454

- Wrap req.json() in try/catch — returns 400 on malformed JSON
- Validate body is a non-null object before destructuring
- title: must be non-empty string, trimmed, max 100 characters
- target: must be integer in [1, 10000] — blocks 0, negatives, floats, NaN, overflow
- unit: clamped to 30 chars silently
- recurrence: unknown values default to 'none' explicitly
- All bounds defined as named constants

Fixes division-by-zero (target:0 → Infinity% progress bar) and
negative target making 0-progress goals show as 100% complete.

Closes Priyanshu-byte-coder#454
@vercel
Copy link
Copy Markdown

vercel Bot commented May 20, 2026

@advikdivekar is attempting to deploy a commit to the PRIYANSHU DOSHI's projects Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions github-actions Bot added gssoc26 GSSoC 2026 contribution type:bug GSSoC type bonus: bug fix labels May 20, 2026
@github-actions
Copy link
Copy Markdown

GSSoC Label Checklist 🏷️

@Priyanshu-byte-coder — please apply the appropriate labels before merging:

Difficulty (pick one):

  • level:beginner — 20 pts
  • level:intermediate — 35 pts
  • level:advanced — 55 pts
  • level:critical — 80 pts

Quality (optional):

  • quality:clean — ×1.2 multiplier
  • quality:exceptional — ×1.5 multiplier

Validation (required to score):

  • gssoc:approved — counts for points
  • gssoc:invalid / gssoc:spam / gssoc:ai-slop — does not score

Type labels (type:*) are auto-detected from files and title. Review and adjust if needed.
Points formula: (difficulty × quality_multiplier) + type_bonus

Copy link
Copy Markdown
Owner

@Priyanshu-byte-coder Priyanshu-byte-coder left a comment

Choose a reason for hiding this comment

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

Merge conflict — rebase on main to resolve. The logic and implementation are correct; once conflict is cleared this can merge immediately.

@Priyanshu-byte-coder Priyanshu-byte-coder added level:intermediate GSSoC: Intermediate difficulty (35 pts) type:security GSSoC type bonus: security (+20 pts) labels May 21, 2026
@advikdivekar
Copy link
Copy Markdown
Contributor Author

@Priyanshu-byte-coder resolved the merge conflicts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gssoc26 GSSoC 2026 contribution level:intermediate GSSoC: Intermediate difficulty (35 pts) type:bug GSSoC type bonus: bug fix type:security GSSoC type bonus: security (+20 pts)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CRITICAL BUG: Goal Input Validation Missing Bounds

2 participants