Invalid access code. Please try again.

Penetration Test Report

Target: computersocietyofkirinyaga.org

Date: 2026-02-10T14:53:43.224035

Report ID: PT-2024-CSK-001

Executive Summary

A comprehensive penetration test revealed multiple critical security vulnerabilities in the CSK backend API. The most severe issues allow privilege escalation from track_lead to admin, user enumeration, and unauthorized data access. Some critical fixes are required to prevent potential system compromise.

Methodology

Initial Discovery

It all starts here.

Hackers are at most times interested in your backend than your frontend

Your backend can have a sweet face but a personality that's opposite

and why talk through an interface when you can talk directly right?

Error Triggering

I start by triggering an error in the frontend.

Why?

There'll always be an endpoint that will log an error with the backend url

Example

For example turning off my internet while the site is loading triggers this

and boom there it is csk-backend-v2.onrender.com

The Fix

The fix?

There's basically no fix for this just accept your backend url will always be triggered by an endpoint.

It's good practice however to remove all unnecessary console logs from the backend when going to prod
for example this axios error

Backend Access

Going to the backend we just follow the url

https://csk-backend-v2.onrender.com/

Verification

How we know it's working

If it gives a not found error then we are on the right path

but if it's a "doesn't exist" error the url is a reroute

API Documentation Discovery

Next thing is the swagger documentation normally at /api/docs but in this case we realize it's just /docs

this means none of the endpoints are expected to use /api

Proof of Concept

proof of concept

curl https://csk-backend-v2.onrender.com/users

Endpoint Enumeration

With these we don't even need to brute force endpoints

why?

swagger documentation gives it all

Conclusion

And here's where all the drama begins

📊 Risk Summary

SeverityCount
Critical2
High1
Medium4
Low3
Total10

Vulnerabilities

VULN-001: Privilege Escalation via PATCH /users/{id} (Critical - CVSS: 9.8)

Description: normal users can modify any user's role, including demoting admins to apprentice and self-promoting to admin.

Impact: Complete system compromise, unauthorized administrative access

Proof of Concept: PATCH /users/{admin_id} with {"role": "apprentice"} using a user JWT

Proof of Concept 2: PATCH /users/me with {"role": "admin"} using a track_lead or contributor jwt

Patch: Implement proper authorization checks, role-based access control, validate user permissions before role modifications

OWASP Category: A01:2021 - Broken Access Control

VULN-002: User Enumeration via /auths/registration-status/{email} (Critical - CVSS: 7.5)

Description: Unprotected endpoint reveals if email is registered and exposes full user details including ID, role, and creation date.

Impact: User enumeration, identification of admin accounts, reconnaissance for targeted attacks

Proof of Concept: GET /auths/registration-status/user@example.com returns userExists: true/false with full details

Patch: Require authentication, return consistent responses, implement rate limiting

OWASP Category: A01:2021 - Broken Access Control

VULN-003: Insecure Direct Object Reference (IDOR) (High - CVSS: 8.1)

Description: Users can access other users' data by manipulating user IDs in API requests.

Impact: Unauthorized data access, privacy violation, potential for data theft

Proof of Concept: GET /users/{other_user_id} returns full profile of unauthorized user

Fix: Implement proper access controls, check user permissions for each resource

OWASP Category: A01:2021 - Broken Access Control

VULN-004: Email Enumeration via /auths/send-otp (Medium - CVSS: 5.3)

Description: Different HTTP status codes (201 vs 409) reveal whether an email is registered.

Additionally: The endpoint is not even protected so i can send an otp without authentication.

Impact: User enumeration, reconnaissance for brute force attacks

Proof of Concept: POST to /auths/send-otp returns 409 for existing emails, 201 for new emails

Fix: Return consistent HTTP status codes and generic messages

Fix 2: Enable RBAC for the endpoint

OWASP Category: A01:2021 - Broken Access Control

VULN-005: Missing Rate Limiting on OTP Endpoints (Medium - CVSS: 6.5)

Description: OTP validation endpoint lacks rate limiting, allowing brute force attacks.

Impact: OTP brute force attacks possible, account takeover risk

Proof of Concept: Multiple consecutive OTP validation attempts succeed without blocking

Fix: Implement rate limiting, account lockout after failed attempts

OWASP Category: A07:2021 - Identification and Authentication Failures

VULN-006: Excessive Data Exposure in API Responses (Medium - CVSS: 5.9)

Description: User endpoints return sensitive data including refresh tokens and phone numbers.

Impact: Information disclosure, potential for account compromise

Proof of Concept: GET /users/me returns refreshToken, phone_number, and other sensitive fields

Fix: Implement data minimization, mask sensitive fields

OWASP Category: A01:2021 - Broken Access Control

VULN-007: Missing Input Validation on Pagination (Low - CVSS: 4.3)

Description: No limits on perPage parameter allowing retrieval of all records at once.

Impact: Potential Denial of Service, excessive data exposure

Proof of Concept: GET /users?perPage=1000 returns all 639 users in single request

Fix: Implement maximum limits, pagination constraints

OWASP Category: A05:2021 - Security Misconfiguration

VULN-008: Information Disclosure in JWT Tokens (Low - CVSS: 3.7)

Description: JWT tokens contain sensitive user information and role data in plain text.

Impact: Information disclosure, potential for token manipulation

Proof of Concept: Base64 decode JWT payload reveals user details

Fix: Store minimal data in JWT, use opaque tokens or encrypt sensitive claims

OWASP Category: A02:2021 - Cryptographic Failures

VULN-009: Publicly Accessible API Documentation (Low - CVSS: 3.1)

Description: Swagger/OpenAPI documentation exposed without authentication.

Impact: Reconnaissance, API mapping for attackers

Proof of Concept: Access to /api-docs or /swagger.json reveals API structure

Fix: Restrict access, require authentication, or move to internal network

OWASP Category: A05:2021 - Security Misconfiguration

VULN-010: Broken Password Reset Implementation (Medium - CVSS: 5.5)

Description: Password reset endpoint appears broken or incorrectly implemented.

Reasoning: The whole point of reset password should be they are unable to login therefore can't get the token.

Impact: Broken functionality, user lockout risk

Proof of Concept: POST /auths/reset-password returns 'jwt must be provided' error

Fix: Fix implementation, ensure proper validation, test password reset flow

OWASP Category: A07:2021 - Identification and Authentication Failures

After all this yapping just note that the next time your backend shows me a user id that isn't mine be assured we're back to square one

Recommendations

Immediate Actions

  • Disable PATCH /users/{id} endpoint or implement strict authorization
  • Protect /auths/registration-status/{email} endpoint with authentication
  • Implement rate limiting on all authentication endpoints

Short Term

  • Conduct security code review of authentication and authorization logic
  • Implement proper access control checks on all endpoints
  • Add input validation and sanitization

Long Term

  • Implement atleast some security testing in CI/CD pipeline
  • Conduct regular security awareness training for developers
  • Try to make penetration testing a regular part of your development process

Appendix

Testing Tools: curl, jq, bash, Python requests(scripts), JWT.io

Total Users Enumerated: 639

Admin Users exploited: 2

Critical Vulnerabilities Exploited: 2