#5328·trufflehog

CloudflareApiToken detector misses 40-char tokens ending in '-' (trailing \b)

Author: sumlacCreated Sep 18, 2026Updated Sep 18, 2026

Summary

The CloudflareApiToken detector does not match a 40-character token whose final character is -. Cloudflare API tokens are [A-Za-z0-9_-]{40}, so a token ending in - or _ is a valid token that is silently skipped.

This looks like a trailing \b word boundary in the detector's pattern: \b cannot assert a boundary after a non-word character, so the match fails when the 40th character is -.

Reproduction

Two tokens, identical in their first 39 characters, differing only in the last. Both are exactly 40 characters and both are valid Cloudflare API token shapes.

bash
#!/usr/bin/env bash
set -eu
BASE="zymMlopiWfqUyHRSIf8NFmAUNLnY5Yx0y3RnjDQ"   # exactly 39 chars
[ "${#BASE}" -eq 39 ] || { echo "BASE must be 39 chars"; exit 1; }
for LAST in "A" "-"; do
  TOKEN="${BASE}${LAST}"
  D=$(mktemp -d)
  printf 'cloudflare:\n  auth:\n    apiToken: %s\n' "$TOKEN" > "$D/c.yml"
  N=$(trufflehog filesystem "$D" --json --no-update --log-level=-1 \
        --no-verification --results=verified,unknown,unverified 2>/dev/null \
      | grep -c CloudflareApiToken || true)
  printf "final char %-4s len=%s -> %s\n" "'$LAST'" "${#TOKEN}" \
    "$([ "$N" -gt 0 ] && echo DETECTED || echo MISSED)"
  rm -rf "$D"
done

Actual output

final char 'A'  len=40 -> DETECTED
final char '-'  len=40 -> MISSED

Expected

Both should be detected. - is in the documented token alphabet and carries no less signal than A.

Versions affected

Reproduced identically on 3.94.3 and 3.97.5 (current at time of filing), macOS arm64, Homebrew builds. 4/4 with independently generated high-entropy 39-character prefixes, so it is not specific to the value above.

Why it matters in practice

Found while running TruffleHog over a large repository estate. A real, live Cloudflare API token committed in a serverless.yml was not reported, and its only distinguishing feature versus tokens that were reported is that it ends in -. The same detector concurrently produced ~2,364 matches on 40-character hex strings in a single yarn.lock — so in that estate the detector had a high false-positive rate on lockfile hashes while missing the genuine credential.

A second scanner using a generic high-entropy rule did report it, which is how the gap surfaced.

Suggested fix

Anchor the trailing edge on something that tolerates a non-word final character — e.g. a lookahead for a non-token character or end-of-input rather than \b — so the full [A-Za-z0-9_-]{40} alphabet is matched. The same consideration likely applies to any other detector whose alphabet includes - or _ and which relies on a trailing \b.

Source: trufflesecurity/trufflehog