564 words
3 minutes
SantaCloud Intigriti 2025: Exposed Backup File Leads to Admin Takeover and Private Notes IDOR

Challenge: SantaCloud (December 2025)
Code: INTIGRITI-LX72F3Y2
Asset: https://santacloud.intigriti.io
Severity: High (chained issues)
Status: Archived / Resolved


Summary#

A chain of low-hanging but high-impact issues allowed complete compromise of the application:

  • Sensitive backup file exposed via robots.txt
  • Hardcoded admin credentials and secrets in composer.json~
  • Successful login as elf_supervisor (admin)
  • IDOR in the Notes API (/api/notes/{id}) that completely ignored user ownership

The result: any unauthenticated visitor could discover the backup, log in as admin, and read every private note belonging to every user — including other participants’ flags.


In Simple Terms#

  1. The site told everyone where to look for secrets (robots.txt).
  2. A backup file sitting in the web root contained the admin username, password, and other secrets in plain text.
  3. Once logged in as admin, the “notes” feature trusted whatever note ID you asked for — no check whether the note actually belonged to you.
  4. Changing the note ID in the API request let us read anyone else’s private data.

Reconnaissance#

Step 1: robots.txt Disclosure#

Visiting the root revealed a robots.txt that pointed to a suspicious backup file:

GET /robots.txt

The file contained:

/composer.json~

Step 2: Backup File Leak#

Direct access to the backup file was possible without authentication:

https://santacloud.intigriti.io/composer.json~

The file contained hardcoded credentials:

"admin-access": {
"username": "elf_supervisor",
"password": "CookiesAndMilk1337",
"api-endpoint": "http://santacloud.intigriti.io/login"
},
"env": {
"secret": "INTIGRITI{019b118e-e563-7348",
"ttl": 3600
}

This single file gave us everything needed for account takeover.


Exploitation#

1. Admin Account Takeover#

Using the leaked credentials:

  • Username: elf_supervisor
  • Password: CookiesAndMilk1337

We successfully authenticated as an administrator.

2. IDOR in the Notes API#

After logging in, we navigated to the user profile and opened the “Internal Notes” section.

Intercepting the request when editing a note revealed:

GET /api/notes/{note-id}

Critical flaw: The endpoint accepted any note-id and returned the note without verifying ownership.

Proof-of-Concept Request:

GET /api/notes/3
Host: santacloud.intigriti.io
Cookie: session=...

Response:

{
"success": true,
"note": {
"id": 3,
"user_id": 1,
"title": "The Secret Key",
"content": "INTIGRITI{019b118e-e563-7348-a377-c1e5f944bb46}",
"is_private": true
}
}

Evidence of IDOR:

  • Our logged-in user had user_id = 2
  • The note returned belonged to user_id = 1
  • No authorization check existed on the server

By simply changing the note ID, we could enumerate and read private notes (and flags) from all users.


Impact#

AspectImpact
ConfidentialityFull access to all users’ private notes
AuthenticationComplete admin account compromise
AuthorizationTotal bypass via IDOR
SecretsHardcoded credentials and application secret exposed
Real-world riskAny attacker could exfiltrate all private data

This is a classic example of chained low-severity issues resulting in high-severity impact: information disclosure → credential leakage → broken access control.


Root Cause#

  1. Backup files (.~, .bak, etc.) were not excluded from public web access.
  2. Hardcoded secrets were committed (and backed up) in application source files.
  3. Missing authorization on the /api/notes/{id} endpoint — the API trusted the caller to only request their own notes.
  4. Client-side trust — the frontend only showed notes belonging to the current user, but the backend performed no ownership validation.

Remediation#

Immediate Actions#

  • Delete or restrict access to composer.json~ and any other backup files.
  • Remove sensitive paths from robots.txt.
  • Rotate all exposed credentials and secrets immediately.

Code-Level Fixes#

1. Prevent backup file exposure

# .htaccess or web server config
<FilesMatch "\.(~|bak|old|swp)$">
Require all denied
</FilesMatch>

2. Never store secrets in source-controlled files Use environment variables or a proper secrets manager.

3. Fix the IDOR (proper authorization)

// Example server-side check
const note = await db.notes.findById(noteId);
if (!note || note.user_id !== currentUser.id) {
return res.status(403).json({ error: "Forbidden" });
}
return res.json({ note });

4. Add server-side ownership validation on all object retrieval endpoints.


Conclusion#

This challenge demonstrated how a seemingly minor information disclosure (a backup file) can quickly escalate when combined with poor secret management and missing authorization checks.

The combination of:

  • Publicly listed backup file
  • Hardcoded admin credentials
  • Unprotected object references in the API

…allowed complete compromise of user data.

Flag: INTIGRITI{019b118e-e563-7348-a377-c1e5f944bb46}


Reported on Intigriti as part of the December 2025 SantaCloud challenge (INTIGRITI-LX72F3Y2).

Challenge Link: https://santacloud.intigriti.io

SantaCloud Intigriti 2025: Exposed Backup File Leads to Admin Takeover and Private Notes IDOR
https://blogs.hacck3y.me/posts/santacloud-intigriti-backup-file-id-or/
Author
hacck3y
Published at
2026-02-01
License
CC BY-NC-SA 4.0