Skip to content

Security: z1fex/brandKIT

Security

SECURITY.md

Security

Reporting vulnerabilities

Please open a GitHub issue at https://github.com/z1fex/brandKIT/issues with the label security. For anything you believe is high-impact, mark the issue private by emailing the maintainer via GitHub profile contact info rather than filing publicly.

Threat model & known limitations

brandKIT is designed as a low-trust public API that fetches public assets. It is intentionally simple, which means some defenses you'd build into a higher-stakes product are not in scope for v1.

In scope — what's defended

  • IP-address inputs are rejected. ?domain=127.0.0.1 returns 400, blocking naive SSRF.
  • Reserved hostnames are rejected. localhost, *.local, *.internal are blocked.
  • Upstream response size is capped. Default 2 MB. Prevents memory exhaustion via hostile sites.
  • Upstream requests have a hard timeout. Default 5 seconds.
  • Constant-time comparison for the optional API key. No timing side-channel.
  • Per-IP rate limiting. 60/min default.

Known limitations — read before exposing publicly

  • DNS-based SSRF is not fully prevented. A domain that resolves to a private IP (e.g. a custom DNS entry pointing internal.corp at 10.0.0.5) will still be fetched. If you expose brandKIT on a network that has routable access to private services, either block egress to RFC1918 at the network layer or run brandKIT in a sandbox with no internal network access.
  • X-Forwarded-For is trusted. Rate limiting uses the first IP from X-Forwarded-For / X-Real-IP / CF-Connecting-IP. This is correct behind a trusted proxy (Vercel, Cloudflare, a load balancer you control). If you expose brandKIT directly to the internet without a trusted proxy, an attacker can spoof these headers to bypass per-IP rate limiting. Either put a reverse proxy in front, or tighten RATE_LIMIT_PER_MINUTE down aggressively.
  • No DDoS protection beyond rate limiting. If you expect abuse, put Cloudflare / AWS Shield / similar in front.
  • Cache poisoning is bounded but possible. The cache keys on domain. A hostile site can serve a different logo to the brandKIT fetcher than to humans (via User-Agent sniffing). This is a fundamental limitation of fetching remote assets — we cache what we see.

Responsible use

brandKIT fetches assets that sites publish for public consumption (favicons, apple-touch-icons, Open Graph images). Respect robots.txt where applicable. If your use case involves high-volume lookups, consider using the filesystem or Supabase cache to avoid repeatedly hitting upstream sites.

There aren't any published security advisories