Bleichenbacher Attack in Fiber
How Bleichenbacher Attack Manifests in Fiber
The Bleichenbacher padding oracle attack targets RSA decryption that uses PKCS#1 v1.5 padding. In a Fiber application, this can appear when developers implement custom RSA‑based token decryption or key exchange logic directly with the crypto/rsa package, rather than relying on TLS. If the handler returns distinct HTTP responses (different status codes, error messages, or timing) for a padding error versus a general decryption failure, an attacker can iteratively modify ciphertexts and learn whether each guess produces valid padding.
Example vulnerable Fiber handler:
func decryptHandler(c *fiber.Ctx) error {
ciphertext := c.Query("cipher")
if ciphertext == "" {
return c.SendStatus(fiber.StatusBadRequest)
}
data, err := hex.DecodeString(ciphertext)
if err != nil {
return c.Status(fiber.StatusBadRequest).SendString("invalid hex")
}
// Private key loaded elsewhere
plain, err := rsa.DecryptPKCS1v15(rand.Reader, privKey, data)
if err != nil {
// Leaking whether the error is a padding error
if strings.Contains(err.Error(), "padding") {
return c.Status(fiber.StatusBadRequest).SendString("padding error")
}
return c.Status(fiber.StatusInternalServerError).SendString("decryption failed")
}
return c.Send([]byte(plain))
}
Because the handler distinguishes "padding error" from other failures, an attacker can send crafted ciphertexts and observe the response to gradually recover the plaintext – the classic Bleichenbacher oracle. This issue maps to OWASP API Top 10 2023 A2: Cryptographic Failures and is catalogued in CVEs such as CVE-2017-3731 (OpenSSL padding oracle) and CVE-2016-0800 (DROWN, which also exploits RSA PKCS#1 v1.5 weaknesses).
Fiber-Specific Detection
Detecting a Bleichenbacher oracle in a running Fiber API requires probing the endpoint with malformed RSA ciphertexts and observing whether the server’s reactions differ based on padding validity. middleBrick’s Encryption check performs exactly this type of active, black‑box test: it sends a series of PKCS#1 v1.5‑encoded messages with deliberate padding errors, measures response codes, timing, and error messages, and flags any statistically significant divergence.
You can trigger this scan from the CLI:
middlebrick scan https://api.example.com/decrypt
The output will include a finding under the "Encryption" category with severity "high", a description like "Potential RSA PKCS#1 v1.5 padding oracle detected", and remediation guidance. Because middleBrick does not need agents, credentials, or configuration, the scan completes in the advertised 5–15 second window and returns a JSON report you can ingest into CI/CD pipelines.
In the Dashboard, the finding appears alongside the other 11 parallel checks (Authentication, BOLA/IDOR, etc.), allowing you to track the risk score over time and see whether recent code changes have introduced or removed the vulnerability.
Fiber-Specific Remediation
The most reliable fix is to avoid RSA PKCS#1 v1.5 decryption altogether. Use OAEP padding (RSAES‑OAEP) which is not susceptible to Bleichenbacher’s oracle, or better yet, delegate encryption to TLS and never expose raw RSA decryption via an API.
Revised Fiber handler using OAEP:
func decryptHandlerOAEP(c *fiber.Ctx) error {
ciphertext := c.Query("cipher")
if ciphertext == "" {
return c.SendStatus(fiber.StatusBadRequest)
}
data, err := hex.DecodeString(ciphertext)
if err != nil {
return c.Status(fiber.StatusBadRequest).SendString("invalid hex")
}
// OAEP with SHA‑256
plain, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, privKey, data, nil)
if err != nil {
// Generic error – no distinction between padding and other failures
return c.Status(fiber.StatusBadRequest).SendString("decryption failed")
}
return c.Send([]byte(plain))
}
If you must retain PKCS#1 v1.5 for compatibility, ensure constant‑time error handling: treat every decryption error identically and never reveal the error type in the response. Additionally, consider blinding the private key (using rsa.DecryptPKCS1v15SessionKey with a random blinding value) as a mitigation, though migrating to OAEP remains the preferred approach.
After applying the fix, rerun middleBrick (via CLI, GitHub Action, or the Dashboard) to confirm the Encryption check now passes and the overall security score improves.