HIGH command injectionspring bootapi keys

Command Injection in Spring Boot with Api Keys

Command Injection in Spring Boot with Api Keys — how this specific combination creates or exposes the vulnerability

Command Injection occurs when an attacker can cause an application to execute arbitrary system commands. In Spring Boot applications that rely on API keys for access control, this risk can emerge when keys are used to gate functionality that eventually invokes operating system commands. A typical pattern is reading an API key from an HTTP header, validating it, and then passing associated parameters to a shell or native command without sufficient sanitization.

For example, suppose a Spring Boot endpoint accepts an API key and a filename, then constructs a shell command to list or transform files. If the filename or other inputs are taken directly from the request and concatenated into the command string, an attacker can inject shell metacharacters such as ; , &&, or | to execute arbitrary commands under the application process. Because API keys are often treated as trusted once validated, developers may skip additional input validation, inadvertently enabling command injection.

Consider a controller that uses an API key for authorization and then calls Runtime.getRuntime().exec() or ProcessBuilder with user-influenced data. An API key itself does not cause injection, but its presence can lead to relaxed checks on downstream inputs. Attack sequences may include leveraging exposed endpoints to extract environment variables, read sensitive files, or pivot within the network. In an unauthenticated scan, middleBrick tests such unvalidated command-building paths, even when API key validation appears present, to detect whether injection is possible through headers or parameters that influence the command string.

Another scenario involves build-time properties or environment variables that embed keys and are later used in scripts. If a Spring Boot application generates commands using these values without escaping, the effective attack surface expands. The LLM/AI Security checks in middleBrick specifically probe for endpoints that accept keys and then influence behavior in ways that could permit command execution, ensuring findings map to relevant OWASP API Top 10 and system prompt leakage risks where applicable.

Because middleBrick scans the unauthenticated attack surface, it can identify endpoints where API key validation is bypassed or insufficient to prevent injection. This highlights the importance of treating API keys as credentials that require careful handling, alongside strict input validation and output encoding, rather than as a substitute for secure coding practices around command execution.

Api Keys-Specific Remediation in Spring Boot — concrete code fixes

To mitigate command injection when API keys are used, focus on strict input validation, avoiding shell invocation, and applying the principle of least privilege. The primary defense is to never construct shell commands from user or external inputs. Instead, use type-safe APIs and explicitly allowlisted values.

1. Avoid Runtime.exec and ProcessBuilder with user input

Replace shell-based commands with Java’s standard library or dedicated libraries that do not invoke a shell. For example, prefer java.nio.file.Files and Path for file operations.

@RestController
@RequestMapping("/files")
public class FileController {

    private final Path baseDir = Paths.get("/safe/base/dir");

    // Good: No shell, no command injection
    @GetMapping("/list")
    public ResponseEntity<List<String>> listFiles(
            @RequestHeader("X-API-Key") String apiKey,
            @RequestParam String relativePath) {
        // Validate API key (example stub)
        if (!KeyService.isValidKey(apiKey)) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
        }
        // Normalize and restrict to base directory
        Path resolved = baseDir.resolve(Paths.get(relativePath).normalize()).normalize();
        if (!resolved.startsWith(baseDir)) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
        }
        try {
            List<String> names = Files.list(resolved)
                    .map(Path::getFileName)
                    .map(Path::toString)
                    .collect(Collectors.toList());
            return ResponseEntity.ok(names);
        } catch (IOException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
}

2. Use whitelisting and strict validation for allowed values

When API keys gate operations, validate all other inputs against an allowlist. For commands that must be executed (rare), use a strict allowlist of arguments and avoid string concatenation.

@Service
public class ReportService {

    private static final Set<String> ALLOWED_REPORTS = Set.of("summary", "details");

    public Process runReport(String reportType, String apiKey) {
        // Validate API key via your authentication provider
        if (!KeyService.isValidKey(apiKey)) {
            throw new IllegalArgumentException("Invalid API key");
        }
        if (!ALLOWED_REPORTS.contains(reportType)) {
            throw new IllegalArgumentException("Unsupported report type");
        }
        // Safe: no user input in command string
        return new ProcessBuilder("java", "-jar", "report-generator.jar", "--type", reportType).start();
    }
}

3. Secure key handling and separation of duties

Store API keys in a secure keystore or use Spring Cloud Config with encrypted properties. Do not concatenate keys into commands or logs. Use environment variables injected securely at deployment time, and restrict filesystem permissions for sensitive scripts.

# application.properties example
app.api-key-refresh-enabled=false
# Use vault integration in production instead of plain properties

By combining these practices—avoiding shell invocation, using allowlists, and isolating credentials—you reduce the risk of command injection to a minimum while still leveraging API keys for access control. middleBrick can validate these controls by scanning for risky endpoint behaviors and ensuring findings align with compliance frameworks.

Related CWEs: inputValidation

CWE IDNameSeverity
CWE-20Improper Input Validation HIGH
CWE-22Path Traversal HIGH
CWE-74Injection CRITICAL
CWE-77Command Injection CRITICAL
CWE-78OS Command Injection CRITICAL
CWE-79Cross-site Scripting (XSS) HIGH
CWE-89SQL Injection CRITICAL
CWE-90LDAP Injection HIGH
CWE-91XML Injection HIGH
CWE-94Code Injection CRITICAL

Frequently Asked Questions

Does using an API key prevent command injection in Spring Boot?
No. API keys provide access control but do not prevent command injection. Injection occurs when untrusted input is concatenated into commands; keys alone do not sanitize or validate those inputs.
How does middleBrick detect command injection risks related to API keys?
middleBrick tests unauthenticated attack surfaces, including endpoints that accept API keys and user-influenced parameters. It checks whether inputs can influence command-like behavior, such as injected shell metacharacters, even when keys are validated.