CRITICAL double freebasic auth

Double Free with Basic Auth

How Double Free Manifests in Basic Auth

Basic Authentication involves the server parsing the Authorization: Basic <base64> header, decoding it, and splitting the result into a username and password. In many C/C++ implementations this decoding step allocates memory for each credential (e.g., with strdup or malloc) before they are used or stored. If the error‑handling path frees these buffers more than once, a classic double‑free (CWE‑415) can be triggered.

Consider a simplified login handler that extracts credentials:

char *parse_basic_auth(const char *header) {
    const char *prefix = "Basic ";
    if (strncmp(header, prefix, strlen(prefix)) != 0) return NULL;
    char *b64 = strdup(header + strlen(prefix));  // allocate
    if (!b64) return NULL;
    char *decoded = base64_decode(b64);          // allocate inside
    free(b64);                                   // first free
    if (!decoded) { free(decoded); return NULL; } // BUG: double free if decoded is NULL
    char *colon = strchr(decoded, ':');
    if (!colon) { free(decoded); return NULL; }   // second free on same pointer
    *colon = '\0';
    char *username = strdup(decoded);
    char *password = strdup(colon + 1);
    free(decoded);                               // third free – still safe
    return username; // caller must free both username and password
}

In the snippet above, if base64_decode returns NULL (invalid Base64), the code executes free(decoded) twice: once immediately after the if (!decoded) check and again later when the function returns NULL after the colon check. This double free corrupts the heap allocator’s internal bookkeeping and can lead to crashes, arbitrary code execution, or information leakage when the server processes subsequent requests.

The vulnerability is tightly coupled to Basic Auth because the header parsing routine is the only place where the server allocates temporary buffers for the decoded credentials. Other authentication schemes (e.g., JWT, API keys) often avoid manual malloc/free pairs by using higher‑level libraries, making Basic Auth a hotspot for this class of memory‑safety bug.

Basic Auth‑Specific Detection

middleBrick performs unauthenticated, black‑box scanning of the API surface. To surface a double free in a Basic Auth endpoint, it crafts malicious Authorization headers that force the server into the error paths described above. Typical probes include:

  • Extremely long Base64 strings that cause allocation failures.
  • Invalid Base64 padding (= characters in the wrong place) leading base64_decode to return NULL.
  • Headers missing the colon separator (username:) after decoding, triggering the second error branch.

When the server double‑frees a pointer, the heap allocator often detects the corruption and aborts the process, resulting in an HTTP 500 Internal Server Error, an empty response body, or a TCP reset. middleBrick records these anomalous responses as findings, tags them with the Memory Safety category, and provides a severity rating based on the observed impact (e.g., crash vs. silent corruption).

Because the scan is agentless and requires no credentials, the tester simply supplies the target URL; middleBrick iterates over the detected Basic Auth endpoints, injects the malformed headers, and reports any endpoint that reproduces the crash pattern. The finding includes the exact header value that triggered the issue, enabling developers to reproduce the bug locally.

Note: middleBrick does not attempt to exploit the double free; it only detects the presence of the condition by observing abnormal server behavior. The remediation guidance is supplied separately in the report.

Basic Auth‑Specific Remediation

The fix is to ensure each dynamically allocated buffer is released exactly once. A common pattern is to centralize cleanup with a goto label or to set pointers to NULL after freeing. Below is a corrected version of the previous example:

char *parse_basic_auth_fixed(const char *header) {
    const char *prefix = "Basic ";
    if (strncmp(header, prefix, strlen(prefix)) != 0) return NULL;
    char *b64 = strdup(header + strlen(prefix));
    if (!b64) return NULL;
    char *decoded = base64_decode(b64);
    free(b64);
    if (!decoded) {               // single free path
        return NULL;
    }
    char *colon = strchr(decoded, ':');
    if (!colon) {
        free(decoded);
        return NULL;
    }
    *colon = '\0';
    char *username = strdup(decoded);
    char *password = strdup(colon + 1);
    free(decoded);                // decoded freed once
    if (!username || !password) {
        free(username);
        free(password);
        return NULL;
    }
    /* Caller must free username and password */
    return username;
}

Key changes:

  • The decoded buffer is freed only once, after the colon check.
  • Error paths return early without attempting to free decoded a second time.
  • Allocations for username and password are checked; on failure both are freed before returning NULL.

In modern codebases, using higher‑level abstractions eliminates manual malloc/free altogether. For example, in C++ one can return std::pair<std::string, std::string> where the strings manage their own memory, or in C use Apache’s apr_pool_t allocation pools that automatically clean up at the end of a request.

After applying the fix, run middleBrick again (via the CLI: middlebrick scan https://api.example.com/resource) to confirm that the anomalous 500 responses disappear and the security score improves. The dashboard will show the updated score over time, and the GitHub Action can be configured to fail a build if the Basic Auth endpoint’s risk rating rises above a chosen threshold.

Frequently Asked Questions

Can middleBrick automatically fix a double free in my Basic Auth implementation?
No. middleBrick only detects and reports the vulnerability. It provides detailed findings, the exact malicious header that triggered the abnormal response, and remediation guidance. You must apply the code fixes yourself or through your development process.
Does middleBrick need any credentials or agents to test Basic Auth endpoints for double free?
No. middleBrick works unauthenticated and agentlessly. You simply supply the public URL of the API; the scanner sends crafted Basic Auth headers from the outside and observes the server’s responses for signs of memory‑safety issues such as double free.