Skip to content

Security: Multiple vulnerabilities in sprig v3.3.0 (DoS, AES-CBC padding oracle, DNS panic, error info leak) #473

Description

@uug4na

Security Report: Multiple Vulnerabilities in sprig v3.3.0

Note: This repository has no security policy (SECURITY.md) and private vulnerability reporting is not enabled. This issue is filed publicly as there is no private channel available for responsible disclosure.

Tested on sprig v3.3.0 with Go 1.25.6.


Finding 1 (HIGH): Unbounded Resource Allocation DoS — CWE-770

Affected functions: repeat, until, untilStep, seq, indent, randAlphaNum, randAlpha, randBytes

These functions accept unbounded size/count parameters. When user-controlled input is passed as the size argument, it directly controls memory allocation with no upper bounds, enabling trivial denial-of-service.

Reproduction:

Template Allocation
{{ "X" | repeat 100000000 }} ~95 MB
{{ until 50000000 }} ~2.2 GB
{{ seq 1 10000000 }} ~1.3 GB
{{ randAlpha 50000000 }} ~4.2 GB

Root cause: functions.go line 128 — strings.Repeat(str, count) with no upper bound on count. The same unbounded pattern applies to until, seq, and the rand* family.

Suggested fix: Add configurable upper bounds on count/size parameters. Consider a MaxAlloc option or similar mechanism.


Finding 2 (MEDIUM): AES-CBC Padding Oracle with Error-Based Information Leak — CWE-327, CWE-347

Affected functions: encryptAES, decryptAES

encryptAES uses AES-CBC mode without any authentication (no HMAC, no GCM). decryptAES at crypto.go line 658 uses the last decrypted byte as the padding length without any validation:

return string(decrypted[:len(decrypted)-int(decrypted[len(decrypted)-1])]), nil

When decryption with a wrong key produces a last byte value N > len(decrypted), Go's slice bounds check panics with "slice bounds out of range [:-N]", leaking the decrypted byte value N through the error message.

Additionally, key derivation at lines 608–609 is just zero-padding:

key := make([]byte, 32)
copy(key, []byte(password))

No KDF, no salt, no iterations — passwords are used directly as key material.

Suggested fix: Replace AES-CBC with AES-GCM (authenticated encryption). Add proper PKCS#7 padding validation. Use a real KDF (e.g., Argon2, scrypt, or at minimum PBKDF2).


Finding 3 (MEDIUM): getHostByName Crash on Failed DNS Lookup — CWE-476

Affected function: getHostByName

In network.go lines 8–12:

func getHostByName(name string) string {
    addrs, _ := net.LookupHost(name)
    //TODO: add error handing when release v3 comes out
    return addrs[rand.Intn(len(addrs))]
}

The error from net.LookupHost is discarded. When DNS resolution fails, addrs is nil, and rand.Intn(0) panics with an unrecoverable crash. The TODO comment in the source code acknowledges this was supposed to be fixed in v3 but never was.

Suggested fix: Check the error return value and handle the empty addrs slice (return empty string or propagate error).


Finding 4 (LOW–MEDIUM): Error Messages Rendered as Template Output — CWE-209

Affected functions: htpasswd, bcrypt, b64dec, b32dec, genPrivateKey, derivePassword

These functions return Go error messages as template string output rather than returning errors through Go's template error mechanism. For example, {{ b64dec "!!!" }} outputs "illegal base64 data at input byte 0" as rendered content.

Root cause: strings.go lines 18–24 — return err.Error() instead of propagating the error properly. This can leak internal implementation details and Go runtime information to end users.

Suggested fix: Return errors through the template error channel rather than rendering them as output strings.


Impact on Downstream Projects

Sprig is a widely-used template function library consumed by:

  • Helm (~27k stars) — Kubernetes package manager
  • Hugo — Static site generator
  • Listmonk — Mailing list manager
  • Many other Go projects

While Helm removes env/expandenv, all DoS-capable functions (repeat, until, seq, randAlpha, etc.) remain available in Helm templates. Any system that renders user-supplied or partially-user-controlled templates using sprig is affected.


Recommendations

  1. Enable private vulnerability reporting on this repository via Settings → Code security and analysis → Private vulnerability reporting.
  2. Add a SECURITY.md with disclosure instructions.
  3. Address the findings above, prioritizing Finding 1 (DoS) and Finding 3 (panic) as they have the most straightforward exploitation path.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions