I was scrolling through Twitter a few days ago when my timeline exploded with the same story. CBSE portal hacked by a kid breaks into On-Screen Marking system. Board exam security compromised.
And then came CBSE's official response.

The URL: cbse.onmark.co.in is the testing site only with sample data for internal testing and review purposes. There are no actual evaluation data, marks or other data held on that portal. The Board emphasises that no security breaches have come to light on the Portal deployed for the actual evaluation work.
I laughed. Actually laughed out loud.
Because I sat for these board exams. I know what they mean to lakhs of students, years of coaching, sleepless nights, parents spending their life savings on preparation. Your entire future compressed into a number on a marksheet. And here was CBSE pulling the classic government playbook: deny, deflect, delete.
So I decided to check for myself.
they took it down and thought that was enough
First thing I tried was direct access to the portal.

cbse.onmark.co.in was already returning 404. Within days of the story going viral, CBSE had nuked the entire system offline.
Classic damage control right? Delete the evidence, deny everything, wait for the news cycle to move on.
But here's the thing about the internet. It remembers.
the wayback machine remembers everything
I headed to the Internet Archive. If the portal ever existed, the Wayback Machine would have snapshots.

Jackpot.
Not just the landing page. The entire compiled Angular application. The JavaScript bundle. Every API endpoint. Every authentication flow. Every function that touches student marks.
The archive had a snapshot from March 3, 2026, the main.js bundle that powered the evaluator portal.
They deleted the portal. They forgot to delete the archive.
pulling the javascript and finding the first horror
I grabbed the archived JavaScript and started digging. The first thing I extracted was the authentication system.
OnMarkWinWebAPI/Auth/CheckUserIDPassword
OnMarkWinWebAPI/Auth/GetForgotPassword
OnMarkWinWebAPI/Auth/InsertUpdateloginstatus
OnMarkWinWebAPI/OnMarkWinEVal/ChangePassword
OnMarkWinWebAPI/OnMarkWinEVal/GenerateLoginQRCode
OnMarkWinWebAPI/OnMarkWinEVal/CheckQRCodeLogin
Standard login endpoints. But then I found how OTP validation actually works.
if(this.isOTPScreen) {
if(this.OTP == this.eval[0].OTP) {
// proceed with login
}
}
Read that again.
The server sends the OTP to the client. The client compares it locally. The "verification" is JavaScript checking if what you typed matches what the server just told you the answer was.
Open DevTools, read this.eval[0].OTP, type it in. You're authenticated.
This is not security. This is a door with the key taped to the handle.
the password reset that doesn't verify anything
The ChangePassword endpoint was even worse.
this.service.getNewsPost("OnMarkWinWebAPI/OnMarkWinEVal/ChangePassword",
JSON.stringify({
ValuatorID: this.eval.user_id,
pin_NewPassword: this.newpassword
})
)
Notice what's missing?
The old password. No email confirmation. No OTP for password changes.
You send a user ID and a new password. The server trusts you. Full account takeover with just a ValuatorID.
And where does ValuatorID come from? Client-side session storage. Change the ID, you're someone else. That's it.
the entire evaluation architecture exposed
I kept pulling endpoints. What emerged was the complete skeleton of how CBSE evaluates your board exams.
head examiner controls
OnMarkWinWebAPI/OnMarkWinEVal/HEValuatorDashboard
OnMarkWinWebAPI/OnMarkWinEVal/HEApproveEval
OnMarkWinWebAPI/OnMarkWinEVal/HEAssignedEvaluators
OnMarkWinWebAPI/OnMarkWinEVal/GenerateHENewScript
OnMarkWinWebAPI/OnMarkWinEVal/GetHeBundleStatusDashboard
assistant head examiner controls
OnMarkWinWebAPI/OnMarkWinEVal/AHEGenScripts
OnMarkWinWebAPI/OnMarkWinEVal/AssignAHE
OnMarkWinWebAPI/OnMarkWinEVal/GetAHEByCollegeId
OnMarkWinWebAPI/OnMarkWinEVal/AssignEvaluatortoAHE
the marks pipeline where your future lives
OnMarkWinWebAPI/OnMarkWinEVal/GetQuestionWiseMarks
OnMarkWinWebAPI/OnMarkWinEVal/InsertUpdateValuationDetails
OnMarkWinWebAPI/OnMarkWinEVal/UpdateMasterSet
OnMarkWinWebAPI/OnMarkWinEVal/RefreshMarksReport
OnMarkWinWebAPI/OnMarkWinEVal/GetTotalMarksTable
OnMarkWinWebAPI/OnMarkWinEVal/UpdateEvaluatorBank
script management for the answer sheets
OnMarkWinWebAPI/OnMarkWinEVal/GenerateNewScript
OnMarkWinWebAPI/OnMarkWinEVal/GetScriptData
OnMarkWinWebAPI/OnMarkWinEVal/GenerateEvaluatedScriptPDF
OnMarkWinWebAPI/OnMarkWinEVal/GenerateScannedPDFS3
OnMarkWinWebAPI/OnMarkWinEVal/RejectorReleaseScript
This is everything. The entire pipeline from scanned answer sheet to final marks. Head examiner approvals. Evaluator assignments. Mark updates. PDF generation.
All of it accessible through an API layer that trusts whatever the client sends.
the idor pattern that breaks everything
Here's the architectural flaw that makes all of this exploitable.
Every sensitive operation reads the user identity from client-side storage.
sessionStorage["eval"] // Contains user_id, role, permissions
localStorage["jwtToken"] // Auth token
sessionStorage["role_id"] // Role identifier
The server doesn't verify. It receives a ValuatorID in the request body and says okay you must be that person.
Change the ID in your session storage, you're someone else. That's it.
This pattern is called an IDOR vulnerability, Insecure Direct Object Reference. It's literally in the OWASP Top 10. It's the kind of thing you learn NOT to do in your first web security course.
And it's everywhere in this codebase.
no route guards at all
The Angular frontend has zero canActivate guards on protected routes.
localStorage.setItem('jwtToken', 'literally_anything');
sessionStorage.setItem('role_id', '23');
window.location.href = '/cbseevalweb/#/dashboard';
No token validation. No role verification. The protection is hoping users don't know the URL.
this is not just cbse
Here's what kept me digging past midnight. CBSE is not the only board using OnMark.

I found multiple subdomains running the same platform.

the evaluator portal

svims portal


other instances

Same codebase. Same authentication patterns. Same vulnerabilities.
How many state boards are running this? How many university exam systems? The OnMark website lists clients across India.
One vendor. One vulnerable architecture. Deployed everywhere.
what i found inside the portals
the dashboard architecture

Standard evaluator dashboard, but with no authorization checks.
evaluator scripts view

Where evaluators access student answer sheets.
the forgot password vulnerability


The response differentiation, "Email Id Is Not Registered" versus success, allows attackers to enumerate valid accounts before attempting authentication attacks. Classic user enumeration.
exposed framework artifacts

test.php exposed, revealing Python 3.6.9 backend and server configuration.

JavaScript directory listing enabled. Source code openly accessible.
cbse's claims versus the evidence
| CBSE Said | The Evidence Shows |
|---|---|
| "cbse.onmark.co.in is the testing site only with sample data" | Production API endpoints: UpdateMasterSet, InsertUpdateValuationDetails, RefreshMarksReport. Testing sites don't have mark manipulation endpoints. |
| "There are no actual evaluation data, marks or other data held on that portal" | Client-side OTP validation. Password reset without verification. IDOR on every sensitive operation. The code handles real evaluator workflows. |
| "No security breaches have come to light on the Portal deployed for actual evaluation work" | They nuked the portal within 48 hours of disclosure going viral. Innocent organizations don't scramble to delete evidence. |
the question nobody is asking
Forget the hack for a second. Forget who found what and when.
Ask yourself this. How did this code ever make it to production?
This is not sophisticated. These aren't zero-days requiring nation-state resources. This is basic foundational web security, the stuff you learn in your first semester of cybersecurity coursework.
Client-side validation for authentication? Beginner mistake. IDOR vulnerabilities? OWASP Top 10. No authorization checks on sensitive endpoints? Security 101.
This is the system that grades Class 12 board exams. The exams that determine college admissions. The exams that shape careers. The exams that students spend years preparing for.
And it was protected by JavaScript that anyone with browser DevTools could read.
deep technical dive
Full API endpoint inventory (100+ endpoints extracted from archived JavaScript)
authentication and session
OnMarkWinWebAPI/Auth/CheckUserIDPassword
OnMarkWinWebAPI/Auth/GetForgotPassword
OnMarkWinWebAPI/Auth/InsertUpdateloginstatus
OnMarkWinWebAPI/OnMarkWinEVal/ChangePassword
OnMarkWinWebAPI/OnMarkWinEVal/GenerateLoginQRCode
OnMarkWinWebAPI/OnMarkWinEVal/CheckQRCodeLogin
OnMarkWinWebAPI/OnMarkWinEVal/InsertUpdateloginstatus
/login_info/login_check
/login_info/forgot_password
/login_info/index
/login_info/logout
/login_info/register
head examiner workflow
OnMarkWinWebAPI/OnMarkWinEVal/HEValuatorDashboard
OnMarkWinWebAPI/OnMarkWinEVal/HEApproveEval
OnMarkWinWebAPI/OnMarkWinEVal/HEAssignedEvaluators
OnMarkWinWebAPI/OnMarkWinEVal/GetHENotifications
OnMarkWinWebAPI/OnMarkWinEVal/GenerateHENewScript
OnMarkWinWebAPI/OnMarkWinEVal/GetValuatorHE
OnMarkWinWebAPI/OnMarkWinEVal/RefreshEvaluatorwiseMarksReport
OnMarkWinWebAPI/OnMarkWinEVal/GetHeBundleStatusDashboard
assistant head examiner workflow
OnMarkWinWebAPI/OnMarkWinEVal/AHEGenScripts
OnMarkWinWebAPI/OnMarkWinEVal/AssignAHE
OnMarkWinWebAPI/OnMarkWinEVal/GetAHEByCollegeId
OnMarkWinWebAPI/OnMarkWinEVal/AssignEvaluatortoAHE
OnMarkWinWebAPI/OnMarkWinEVal/GetEvaluatorsAHEByCollegeId
marks and evaluation
OnMarkWinWebAPI/OnMarkWinEVal/GetQuestionWiseMarks
OnMarkWinWebAPI/OnMarkWinEVal/InsertUpdateValuationDetails
OnMarkWinWebAPI/OnMarkWinEVal/UpdateMasterSet
OnMarkWinWebAPI/OnMarkWinEVal/RefreshMarksReport
OnMarkWinWebAPI/OnMarkWinEVal/RefreshEvalMarksReport
OnMarkWinWebAPI/OnMarkWinEVal/GetTotalMarksTable
OnMarkWinWebAPI/OnMarkWinEVal/UpdateEvaluatorBank
OnMarkWinWebAPI/OnMarkWinEVal/GetAnnotations
OnMarkWinWebAPI/OnMarkWinEVal/GetRejectionReport
script management
OnMarkWinWebAPI/OnMarkWinEVal/GenerateNewScript
OnMarkWinWebAPI/OnMarkWinEVal/GetScriptData
OnMarkWinWebAPI/OnMarkWinEVal/GenerateEvaluatedScriptPDF
OnMarkWinWebAPI/OnMarkWinEVal/GenerateScannedPDFS3
OnMarkWinWebAPI/OnMarkWinEVal/GenerateScannedScriptPDF
OnMarkWinWebAPI/OnMarkWinEVal/RejectorReleaseScript
OnMarkWinWebAPI/OnMarkWinEVal/GetAllVerificationScripts
OnMarkWinWebAPI/OnMarkWinEVal/GetBundleDetailsById
OnMarkWinWebAPI/OnMarkWinEVal/DeleteSciptImages
OnMarkWinWebAPI/OnMarkWinEVal/ExtractImages
OnMarkWinWebAPI/OnMarkWinEVal/ExtractImagesS3
OnMarkWinWebAPI/OnMarkWinEVal/GetCommentsByScriptId
OnMarkWinWebAPI/OnMarkWinEVal/GetNotesByScriptId
evaluator management
OnMarkWinWebAPI/OnMarkWinEVal/GetValuatorwithID
OnMarkWinWebAPI/OnMarkWinEVal/ValuatorDashboard
OnMarkWinWebAPI/OnMarkWinEVal/UpdateEvaluator
OnMarkWinWebAPI/OnMarkWinEVal/GetEvaluators
OnMarkWinWebAPI/OnMarkWinEVal/GetEvaluatorsById
OnMarkWinWebAPI/OnMarkWinEVal/UpdateEvaluatorDetails
OnMarkWinWebAPI/OnMarkWinEVal/AddEvaluatorDetails
OnMarkWinWebAPI/OnMarkWinEVal/GetEvaluatorsByCollegeId
OnMarkWinWebAPI/OnMarkWinEVal/GetValuatorDaywiseReport
OnMarkWinWebAPI/OnMarkWinEVal/GetValuatorSubjectwiseReport
OnMarkWinWebAPI/OnMarkWinEVal/GetValuatorScriptReport
OnMarkWinWebAPI/OnMarkWinEVal/GetEValuatorScriptReport
OnMarkWinWebAPI/OnMarkWinEVal/UpdateFVProfile
subject and school data
OnMarkWinWebAPI/OnMarkWinEVal/GetSubjectStepsSchema
OnMarkWinWebAPI/OnMarkWinEVal/GetSubjectSchema
OnMarkWinWebAPI/OnMarkWinEVal/GetSubjects
OnMarkWinWebAPI/OnMarkWinEVal/GetSubjectListByPogramme
OnMarkWinWebAPI/OnMarkWinEVal/GetPogramme
OnMarkWinWebAPI/OnMarkWinEVal/GetSchoolsBySchlCode
OnMarkWinWebAPI/OnMarkWinEVal/GetParentSectionWise
OnMarkWinWebAPI/OnMarkWinEVal/GetSectionWise
OnMarkWinWebAPI/OnMarkWinEVal/GetSubCompleteCount
svims portal endpoints
/svims/welcome/index
/svims/welcome/dashboard
/svims/welcome/inward_register
/svims/welcome/assign_barcode
/svims/welcome/reports
/svims/welcome/search
/svims/welcome/logout
/svims/welcome1/edit_userform
/svims/scan_info/semester_scan_info
/svims/scan_info/subject_scan_info
/svims/scan_info/bundle_scan_info
/svims/Valuator_valuations/index
/svims/Valuator_valuations/get_scripts
/svims/Valuator_valuations/get_valuations
/svims/Valuator_valuations/view_script
/svims/Valuator_valuations/submit_marks
/svims/Valuator_valuations/submit_change_pwd
Vulnerability severity matrix
| Vulnerability | Severity | Status |
|---|---|---|
| Client-side OTP validation | CRITICAL | Confirmed in archived JS |
| Password reset without old password | CRITICAL | Confirmed in archived JS |
| IDOR on all sensitive operations | HIGH | Confirmed, ValuatorID from client |
| No Angular route guards | HIGH | Confirmed, localStorage bypass |
| User enumeration via forgot password | MEDIUM | Confirmed via response differentiation |
| Exposed test.php with server info | LOW | Screenshot evidence |
| Directory listing enabled | LOW | Screenshot evidence |
my take
They can delete the portal. They can't delete the proof.
The Wayback Machine still has the code. I still have my screenshots. The endpoints are documented. The architecture is mapped.
If you sat for CBSE board exams, your answer sheet went through this system. If you're a parent, your child's future was graded on this platform. If you're a taxpayer, your money funded this.
You deserve to know how it actually worked.
And the next time a government body tells you their secure system wasn't breached, remember: the internet remembers. The archives remember. And some of us know how to read JavaScript. 🫡
methodology
All information in this article was derived from publicly archived sources via the Wayback Machine. The CBSE portal at cbse.onmark.co.in was already returning 404 at the time of this investigation. All technical analysis was performed on archived, publicly available code. No active exploitation of any live system was performed.
