HIGH replay attackchibasic auth

Replay Attack in Chi with Basic Auth

Replay Attack in Chi with Basic Auth — how this specific combination creates or exposes the vulnerability

A replay attack in the context of Chi using HTTP Basic Authentication occurs when an adversary intercepts a valid request—containing the Base64-encoded Authorization header—and retransmits it to the service to gain unauthorized access. Because Basic Auth does not include any built-in nonce, timestamp, or per-request signature, the transmitted credentials remain the same across requests, making captured authentication tokens reusable indefinitely (or until the password changes).

Chi routes are typically stateless and rely on explicit middleware to inspect headers. If your Chi application validates Basic Auth by decoding the header and checking credentials on each request without additional protections, an attacker who observes a single authenticated exchange (for example, via an insecure network or a compromised proxy) can replay that exact request to perform actions as the victim user. This risk is amplified when the application does not enforce transport-layer protections or when logs inadvertently capture authorization headers, exposing Base64-encoded credentials that can be decoded offline.

Operational visibility into this attack surface is supported through spec-first analysis. By submitting your Chi API’s OpenAPI/Swagger definition to middleBrick, the scanner resolves $ref paths and cross-references runtime behavior to flag endpoints that accept Basic Auth without anti-replay safeguards. The 12 parallel security checks—particularly Authentication, Input Validation, and Data Exposure—help identify whether your Chi routes leak credentials in responses or logs and whether authorization is evaluated only at the entrypoint without per-request binding.

Because middleBrick performs unauthenticated, black-box scanning, it can detect whether intercepted Basic Auth traffic could be replayed successfully against your Chi endpoints. Findings include severity-ranked guidance, mapping weaknesses to the OWASP API Top 10 and relevant compliance frameworks, so you can prioritize fixes such as enforcing TLS, adding request uniqueness, and moving away from static credentials toward token-based flows.

Basic Auth-Specific Remediation in Chi — concrete code fixes

To mitigate replay risks with Basic Auth in Chi, combine mandatory HTTPS, short-lived credentials, and request-level uniqueness. The following Chi code examples illustrate secure patterns.

1. Enforce HTTPS and reject cleartext credentials

Ensure your Chi server rejects HTTP requests before authentication logic runs. This prevents on-path interception of the Base64-encoded header.

import chiselapi._
import chiselapi.dsl._

val app = new Router {
  override val routes: Route = {
    case req @ GET -> Root / "secure" => {
      // Reject if not TLS; Chi behind a proxy should set X-Forwarded-Proto
      if (!req.headers.get("X-Forwarded-Proto").contains("https")) {
        respondWithStatus(StatusCodes.Forbidden) {
          complete("HTTPS required")
        }
      } else {
        authorizeBasic(req) { credentials =>
          authenticateUser(credentials) match {
            case Some(user) => provideResource(user)
            case None     => respondWithUnauthorized
          }
        }
      }
    }
  }

  def authorizeBasic(req: RequestContext)(validate: (String, String) => RouteResult): RouteResult = {
    req.header[Authorization] match {
      case Some(auth) if auth.scheme == "Basic" =>
        val decoded = new String(java.util.Base64.getDecoder.decode(auth.token))
        val parts  = decoded.split(":", 2)
        if (parts.length == 2) validate(parts(0), parts(1)) else respondWithUnauthorized
      case _ => respondWithUnauthorized
    }
  }

  def authenticateUser((user, pass): (String, String)): Option[User] = {
    // Use a constant-time comparison and a secure store
    val storedHash = getUserHash(user)
    if (storedHash.nonEmpty && slowEquals(storedHash.get, pass)) Some(User(user)) else None
  }

  def slowEquals(a: String, b: String): Boolean = {
    val left  = a.getBytes("UTF-8")
    val right = b.getBytes("UTF-8")
    var diff  = left.length ^ right.length
    var i     = 0
    while (i < left.length) {
      diff |= left(i) ^ right(i)
      i += 1
    }
    diff == 0
  }

  def provideResource(user: User): RouteResult = complete(s"Authenticated as ${user.name}")
}

2. Add per-request nonces or timestamps to defend against replay

Include a server-generated nonce or a timestamp window in the request body or headers, store recent values briefly, and reject duplicates. This binds the credentials to a specific execution context.

import chiselapi._
import chiselapi.dsl._
import java.security.SecureRandom
import java.util.concurrent.ConcurrentHashMap
import scala.concurrent.duration._

object NonceStore {
  private val seen = new ConcurrentHashMap[String, Long]()
  def check(nonce: String, now: Long): Boolean = {
    val existing = seen.putIfAbsent(nonce, now)
    if (existing != null && now - existing < 2000) false else true // 2s window
  }
}

val app2 = new Router {
  override val routes: Route = {
    case req @ POST -> Root / "transaction" => {
      for {
        auth   <- req.header[Authorization]
        body   <- req.entity.asString
        nonce  <- extractNonce(body)
        now    = System.currentTimeMillis()
        _      <- validateIf(NonceStore.check(nonce, now))
        creds  =  parseBasic(auth.get.value)
        user   <- authenticate(creds)
        resp   <- processTransaction(user, body)
      } yield resp
    }
  }

  def extractNonce(body: String): Directive1[String] = ??? // parse {"nonce":"abc"}
  def validateIf(cond: Boolean): Directive0 = if (cond) pass else reject
  def parseBasic(authHeader: String): (String, String) = {
    val decoded = new String(java.util.Base64.getDecoder.decode(authHeader.split("\\s+")(1)))
    val parts   = decoded.split(":", 2)
    (parts(0), parts(1))
  }
  def authenticate(creds: (String, String)): Option[User] = ???
  def processTransaction(user: User, body: String): RouteResult = complete("ok")
}

These examples show how to enforce TLS, validate credentials securely, and introduce one-time nonces to bind each request, reducing the feasibility of replay in Chi environments that rely on Basic Auth.

Frequently Asked Questions

Does middleBrick fix replay vulnerabilities in Chi?
middleBrick detects and reports whether your Chi endpoints accept Basic Auth without replay protections. It provides remediation guidance but does not fix, patch, block, or remediate issues.
Can I test authenticated Chi routes with middleBrick?
middleBrick scans unauthenticated attack surfaces by default. To include authenticated areas, provide authentication details via supported mechanisms when submitting your URL, or use the CLI to pass credentials if your deployment requires them.