logo

Database

Need

Restriction of resources served by an endpoint to an explicit public set

Context

• Usage of Kotlin 1.9+ on the JVM for building web applications

• Usage of Spring Web MVC for REST controllers

• Usage of classpath resources for static documents

Description

1. Non compliant code

import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RestController

@RestController
class DocsController {
    @GetMapping("/docs/{name}")
    fun document(@PathVariable name: String): ByteArray? =...

The `/docs/{name}` endpoint below loads the classpath resource named in the URL with `getResourceAsStream` and returns its bytes. The classpath contains much more than public documents. A request for `/docs/application.yml` or `/docs/application-prod.properties` returns the configuration of the service, often with database passwords, API keys and signing secrets, and other names return compiled classes that can be decompiled to study the application. The caller only needs to guess common file names.

2. Steps

• Never pass request data to `getResourceAsStream`, `getResource` or `ClassPathResource`.

• Map public names to fixed resource paths in an explicit allowlist and reject any other name.

• Keep public documents in a dedicated folder, separate from configuration files and compiled code.

• Remove secrets from classpath configuration files and load them at runtime from a secrets manager.

3. Secure code example

import org.springframework.http.HttpStatus
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.server.ResponseStatusException

private val PUBLIC_DOCS = mapOf(
    "terms" to "public-docs/terms.pdf",...

The corrected endpoint only serves documents listed in `PUBLIC_DOCS`, which maps each public name to a resource inside the dedicated `public-docs/` folder of the classpath. The request can only choose among those names; any other value, including `application.yml`, `../` sequences or class files, returns `404 Not Found` without touching the class loader. Because the map is fixed in the code, adding a new public document is an explicit, reviewable change. Keeping public documents in their own folder, separate from configuration and code, also makes it harder to publish a sensitive file by accident.