When Secure APIs Leak Through Logging: A Hidden Risk

In one of the environments I work with, APIs play a key role in delivering functionality — including the ability to download selected PDF files through a GUI. At first glance, this download feature appears to be well-designed and secure. However, during routine research, I discovered a risk that stems not from the API itself, but from something often overlooked: logging. This post dives into how even secure features can be undermined when logs expose sensitive metadata — and what I learned from the experience.

How the Download Process Works

The GUI lets users download a selection of files bundled into a ZIP archive. Behind the scenes, four endpoints handle this process:

POST /api/download/initiate

  • Authorization: JWT token (user session-based)
  • Request: A list of document IDs to be bundled
  • Response: A job ID for checking download status

GET /api/download/status/<job_id>

  • Authorization: JWT token
  • Request: Job ID
  • Response: Progress or completion status of the ZIP

GET /api/download/confirm

  • Authorization: JWT token
  • Request: Job ID
  • Response: An encrypted string used for downloading

GET /api/download/resource?id=<encrypted_id>

Response: The ZIP file containing requested documents

Authorization: None

Request: Encrypted ID

The Design Strength

The two strongest points of this implementation:

  • Strong Encryption: The download ID is encrypted using AES-GCM-256 with a 12-byte IV, tied to the ZIP file’s full path on the server. It’s practically impossible to guess or brute-force this ID.
  • JWT-Based Authorization: Every action up until the final download requires a valid, signed token.

What manipulations did I try?

This wasn’t an attempt to break things — I wanted to see how resilient the system was to basic tampering:

Field Manipulation in POST /initiate
I tried:

At first, this seemed to work — until I realized I was testing with an admin-level account. Once I switched to a regular user, the system correctly rejected unauthorized document IDs.

JWT Token Manipulation
Using jwt_tool, I tried tampering with claims to escalate privileges or change access. However, the JWT’s signature is verified server-side and couldn’t be bypassed.

Brute-forcing the Download Endpoint
Attempts to directly access the final ZIP download with modified or random encrypted IDs didn’t succeed either — the encryption key is derived from internal server paths.

Overall, the API design stood firm against:

  • Broken Object Level Authorization (BOLA)
  • Broken Authentication
  • Broken Function Level Authorization

The Hidden Problem: Logging

Despite all the solid design choices above, the system’s internal logging introduced an unexpected vulnerability. Millions of logs are generated weekly — and some of them include the decrypted download path, which contains metadata like job ID and user identifiers. While this isn’t plain-text document content, it still exposes potentially sensitive information. Worse, access to the logging tool is broadly granted by default when employees join the team — regardless of role or necessity. That creates unnecessary exposure and potential misuse.

Why This Matters

You can design your APIs with security best practices — but if your monitoring, logging, or support systems aren’t held to the same standard, they can leak valuable information that adversaries could use in the reconnaissance or manipulation phase of an attack.

Aftermath & Action Taken

I brought this to the attention of our internal security officer. We scheduled a session to review the logging configurations and visibility in our monitoring stack. I also submitted a feature request to our development team asking them to mask sensitive information in logs, especially decrypted file paths and user metadata.

Lessons Learned

  • Don’t underestimate the risk of indirect exposure — logs and monitoring tools can leak sensitive details.
  • Apply role-based access control (RBAC) to internal tools, not just the API.
  • Review logging output during development and post-deployment.
  • Consider using log masking or encrypting fields that reference file paths, user identifiers, or session-specific content.