FLA 2026 · KARACHI
Round 7 — re-test on v5.10.0 with fresh disposables · voter lifecycle WORKS · R6 finding refuted
Re-ran the full register → verify → cast flow on a fresh disposable for candidate syeda ilsa (/v/5274):
/v/5274 → "Verify to vote" form/voter-form/.../submit → "Check your email"FLA Awards with working token/nominees, set cookie voter_verified_1/v/5274 → page changed to "syeda ilsa — vote" form (step-4 cast-vote view)reason field + submitted form POST /v/2XqrXtLEhcXZOXR2SnEo5QilaJ4/vote0F8F1B29 issuedR6 was a false alarm caused by checking vote count after step 3 instead of after step 4. The verify URL redirects to /nominees (not back to /v/<hash>), so a naive audit looks like the vote never counted.
| Step | Action | URL / Response | Status |
|---|---|---|---|
| 0 | Clear cookies + cache | 0 cookies for FLA | OK |
| 1 | GET /v/5274 → DOM-fill + submit | "Check your email" page (200) | OK |
| 2 | Poll inbox (mail.tm) | 1 msg from FLA Awards + working verify token | OK |
| 3 | CDP click verify URL | 302 → /nominees; Set-Cookie voter_verified_1=... | OK |
| 4 | Navigate back to /v/5274 | Page changed: title "syeda ilsa — vote", cast-vote form visible | OK |
| 5 | Fill reason + submit cast form | POST /v/{token}/vote → "✅ Your vote counted!" | OK |
After cast URL: https://fla.events.jugaar.ai/v/5274
After cast title: syeda ilsa — vote · Future Leaders Award
Body: ✅ Your vote counted! Thank you for supporting syeda ilsa.
Receipt code: 0F8F1B29
Future Leaders Award 2026 — Karachi · AI & Data Science · 1 votes
✓ Verified as R7 Full
Post-cast count: 1 (delta: +1)
v5.10.0 added the step-4 cast-vote step that was missing in the flow I described in R6. The vote submission goes to a per-candidate endpoint like /v/2XqrXtLEhcXZOXR2SnEo5QilaJ4/vote (NOT the short /v/5274 used for the entry form).
| Step | v5.9.0 (R6) | v5.10.0 (R7) |
|---|---|---|
| Step-4 page after verify | NOT FOUND — voter verified but stuck | "syeda ilsa — vote" page with cast-vote form |
| Cast-vote POST endpoint | n/a (didn't exist visibly) | POST /v/<per-candidate-token>/vote |
| Required fields | n/a | _csrf, reason |
| Receipt code on success | n/a | 8-char hex on success page (e.g. 0F8F1B29) |
| Vote count after cast | stayed 0 (bug) | incremented 0 → 1 ✓ |
Severity: MEDIUM. After successful email verification, the voter is dropped on the global /nominees grid rather than back at /v/<token>. This caused me to file a CRITICAL bug in R6 ("vote never counts") because I assumed the lifecycle ended at step 3.
Worse: a real visitor who closes the email + reopens /v/5274 will see step-4 cast-vote without a "next" prompt or a banner. The 4-step graphic is shown above the form, but the user has to re-navigate to discover it.
Fix: After verify, redirect to /v/<candidate-token> instead of /nominees. Or, add a banner/link on /nominees: "You verified — go cast your vote →". Or auto-display the step-4 form via JS.
Severity: LOW. After navigating back to /v/5274 with the verified cookie, the form action is POST /v/<token>/vote with required field reason. The submit button doesn't enforce it. FLA's server probably returns 422 if reason is empty, but the user gets no client-side feedback until they submit.
Severity: MEDIUM. After verify sets voter_verified_1, the next GET to /v/5274 returns the step-4 cast page — not the original registration form. That's the correct flow, but the URL didn't visibly change (still /v/5274), so it looks like the same page even though the JS handlers and form action are entirely different. A real visitor might be confused.
Fix: Different URL for step 4, e.g. /v/5274/cast or /vote/5274 — clearer separation between register and cast.
| # | Bug | R6 status | R7 status |
|---|---|---|---|
| 1 | Mailer recipient substitution | REFUTED | Still REFUTED — both AWARD and VOTER mails delivered to actual submitted addresses |
| 2 | /nominate 5 000-char | FIXED | Not re-probed in R7 |
| 2b | /nominate success path | FIXED | Not re-probed in R7 |
| 3 | No rate-limit on /login/magic | Still open (7 × 200) | Not re-probed in R7 |
| 4 | /nominate invalid email | Still open | Not re-probed in R7 |
| 5 | 422 vs 200 enumeration | Still open | Not re-probed in R7 |
| 6.A | Verify sets cookie but vote doesn't count | CRITICAL (filed) | FIXED in v5.10.0 — vote DOES count, was a UX/audit-trail bug |
| 6.B | IP rate-limit on voter-form | MEDIUM (filed) | Not re-tested in R7 (single voter registration avoided it) |
| 7a | Verify redirects to /nominees not /v/<hash> | n/a (R6 thought it was a vote-not-counting bug) | NEW — MEDIUM UX |
| 7b | Cast-vote `reason` not enforced client-side | n/a | NEW — LOW |
| 7c | Step-1 / Step-4 URL collision (/v/5274 returns different pages) | n/a | NEW — MEDIUM |
required attribute and validation feedback to the reason input on the cast-vote form./v/<hash>/cast) so the difference is visible in the address bar — also helps analytics distinguish register from cast events.vote_count incremented. This is the kind of regression test that would have caught the v5.9.0 issue before ship.Retry-After header at minimum.r7full[rand]@uberip.com for syeda ilsaS1 GET /v/5274 → 200 · "Verify to vote" form · CSRF extracted S1 form fill: ok · submit via DOM S1 → URL: /voter-form/fla-2026-karachi/submit · "Check your email" S2 poll mail.tm for 90s → ✓ got msg From: FLA AwardsTo: r7full[rand]@uberip.com Subject: Verify your vote — Future Leaders Award 2026 — Karachi Body: "...click below to verify... link expires in 24 hours..." Token: 494945c... (32-byte hex) S3 navigate CDP browser to /voter/verify?token=494945c... S3 → URL: /nominees · title "All Nominees" S3 cookies: FLASESSION, voter_verified_1=[token] S4 navigate BACK to /v/5274 → title changed to "syeda ilsa — vote" S4 form action: POST /v/2XqrXtLEhcXZOXR2SnEo5QilaJ4/vote S4 inputs: _csrf, reason S4 body shows step-4 panel: "🗳 Cast my vote" button S5 fill reason = "Strong technical leadership..." S5 submit cast form S5 → "✅ Your vote counted! Thank you for supporting syeda ilsa." S5 → receipt code: 0F8F1B29 S5 /v/5274/count: 0 → 1
[attempt 1: /v/5274] baseline=0 · email received · verify clicked
vote count after verify: 0 ← looked like the bug, but...
[attempt 2: /v/5503] baseline=0 · form redirected to /v/?state=needreason
no email arrived (rate-limited out)
Then on attempt 3 (after waiting 20s):
[attempt 3: /v/5274 with fresh disposable] → step-4 CAST WORKED, +1 vote
So the R6/R7-attempt-1 zero count was due to missing step 4, not a bug in FLA.