HIGH command injectionspring boothmac signatures

Command Injection in Spring Boot with Hmac Signatures

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

Command injection occurs when untrusted data is concatenated into a system command and the resulting string is executed by a shell or runtime. In Spring Boot applications that use Hmac Signatures to validate request integrity, a common pattern is to include a user-controlled parameter—such as a filename, path, or identifier—in the data that is signed. If the server later uses that same parameter in a shell command without proper validation, an attacker can supply payloads that break out of the expected argument boundaries and execute arbitrary commands.

Consider a scenario where a Spring Boot endpoint accepts a fileId query parameter, includes it in the signed string (alongside timestamp and other fields), and then passes the fileId to a shell command for processing. If the developer constructs the command via string concatenation or interpolation, an attacker can supply something like abc; cat /etc/passwd or abc && id. Because the Hmac Signature verifies integrity but not safety, the server may trust the parameter and forward it directly to Runtime.getRuntime().exec() or ProcessBuilder, leading to command injection.

The Hmac Signature mechanism itself does not introduce the vulnerability; rather, the risk arises when the signed data includes values that the application later uses in dangerous contexts. For example, if the signature covers a filePath field and the server uses that field in a shell command such as tar -xzf {filePath}, an attacker can attempt to append shell metacharacters to achieve command injection. Because the signature validates that the field has not been tampered with, the developer may incorrectly assume that the content is safe, overlooking the need for input validation and command construction safeguards.

In Spring Boot, this often manifests in code that uses String.split, custom parsers, or external scripts where untrusted values are interpolated into commands. Even if the Hmac Signature ensures the request has not been modified in transit, the application must treat all inputs—including those covered by the signature—as untrusted when building commands. OWASP API Top 10 A03:2023 Injection remains relevant here, as API endpoints that process signed requests can still be abused through improper command construction.

Real-world analogues include cases where directory traversal or path manipulation combined with command execution leads to unauthorized file access or remote code execution. For instance, an attacker might supply a filename like ../../../etc/passwd | ls if the server builds a shell command by simple concatenation. Because the Hmac Signature may still verify, the server proceeds to execute the command, exposing sensitive data or enabling further compromise. Proper mitigation requires strict input validation, avoiding shell metacharacters, using parameterized commands or APIs that bypass the shell, and ensuring that signed fields are not directly used in dangerous contexts.

Hmac Signatures-Specific Remediation in Spring Boot — concrete code fixes

To mitigate command injection while continuing to use Hmac Signatures in Spring Boot, redesign the flow so that signed parameters are never concatenated into shell commands. Instead, use structured APIs and strict allowlists. Below are concrete, safe patterns and code examples.

  • Validate and restrict parameter values before use: enforce an allowlist of permitted values for identifiers used in commands. For example, if the signed parameter is a file ID, map it to a known safe path on the server rather than passing the raw value to a shell.
  • Use Java’s ProcessBuilder with a list of arguments instead of shell strings, and avoid invoking /bin/sh -c. This prevents the shell from interpreting metacharacters.
  • Keep sensitive operations outside the shell: perform file extraction, parsing, or data transformations using Java libraries rather than invoking external utilities.

Example of an unsafe pattern to avoid:

String unsafeCmd = "tar -xzf " + userSuppliedFileId;
Runtime.getRuntime().exec(unsafeCmd);

Example of a safe remediation using ProcessBuilder and an allowlist mapping:

import java.util.List;
import java.util.Map;
import java.util.HashMap;

@Service
public class FileProcessingService {

    // Allowlist mapping from signed fileId to safe filesystem path
    private static final Map<String, String> ALLOWED_FILES = Map.of(
        "report2024", "/data/reports/report2024.tar.gz",
        "backup01",  "/data/backups/backup01.tar.gz"
    );

    public void extractFile(String fileId) {
        String safePath = ALLOWED_FILES.get(fileId);
        if (safePath == null) {
            throw new IllegalArgumentException("Invalid file identifier");
        }
        // Use ProcessBuilder with a list; no shell involved
        ProcessBuilder pb = new ProcessBuilder(
            "tar", "-xzf", safePath, "-C", "/data/extract"
        );
        pb.redirectErrorStream(true);
        try {
            Process p = pb.start();
            int exitCode = p.waitFor();
            if (exitCode != 0) {
                // handle failure
            }
        } catch (Exception e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException("Extraction failed", e);
        }
    }
}

If you must sign and verify parameters that influence behavior, ensure the signed scope is limited and that runtime usage does not involve shell interpretation. For example, sign a contract that includes an action enum and a resource ID, then map the combination to a server-side routine:

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.nio.charset.StandardCharsets;

public class HmacUtil {
    private static final String HMAC_ALGORITHM = "HmacSHA256";

    public static String computeHmac(String data, String secret) throws Exception {
        Mac mac = Mac.getInstance(HMAC_ALGORITHM);
        SecretKeySpec key = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), HMAC_ALGORITHM);
        mac.init(key);
        return Base64.getEncoder().encodeToString(mac.doFinal(data.getBytes(StandardCharsets.UTF_8)));
    }
}

In your controller, verify the Hmac Signature, then route to a predefined handler instead of building a command from raw values:

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

    @GetMapping("/extract")
    public ResponseEntity<String> extract(
            @RequestParam String fileId,
            @RequestParam String timestamp,
            @RequestParam String signature) throws Exception {

        String dataToSign = fileId + timestamp;
        String expected = HmacUtil.computeHmac(dataToSign, System.getenv("HMAC_SECRET"));
        if (!expected.equals(signature)) {
            return ResponseEntity.status(403).body("Invalid signature");
        }

        // Safe routing based on allowlist, no shell usage
        fileProcessingService.extractFile(fileId);
        return ResponseEntity.ok("Extraction scheduled");
    }
}

By combining Hmac Signatures with strict input validation, allowlists, and shell-agnostic execution, you preserve integrity checks while eliminating command injection risk. middleBrick scans can help identify such injection-prone endpoints in unauthenticated testing, and the Pro plan’s continuous monitoring can detect regressions if parameters or handlers change.

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 Hmac Signatures prevent command injection by itself?
No. Hmac Signatures verify integrity of data but do not affect whether that data is used safely. If signed parameters are concatenated into shell commands, command injection can still occur. Mitigation requires input validation, allowlists, and safe command construction.
Can middleBrick detect command injection in signed API endpoints?
middleBrick tests the unauthenticated attack surface and can identify endpoints that reflect command injection patterns. Findings map to OWASP API Top 10 and include remediation guidance; the Pro plan supports continuous monitoring to catch regressions after changes.