Problem
The AI microservice passes user input directly to the LLM without validation or sanitization:
func handleAIRequest(w http.ResponseWriter, r *http.Request) {
var req struct {
Prompt string `json:"prompt"`
}
json.NewDecoder(r.Body).Decode(&req)
// No length check, no injection detection:
callLLM(req.Prompt)
}
Two risks:
- Token abuse: A prompt of 100,000 tokens (the max context window) costs the service hundreds of dollars per request. After paying a $0.001 micropayment, an attacker triggers a $1 LLM call.
- Prompt injection: System prompts or instructions can be overridden by crafted user input like "Ignore all previous instructions and..."
Proposed Fix
const (
MaxPromptLength = 4000 // characters (~1000 tokens)
MaxPromptTokens = 1000 // hard token budget
)
var injectionPatterns = []string{
"ignore all previous instructions",
"ignore your system prompt",
"disregard all prior",
"you are now",
"new persona",
}
func validatePrompt(prompt string) error {
if len(prompt) == 0 {
return fmt.Errorf("prompt cannot be empty")
}
if len(prompt) > MaxPromptLength {
return fmt.Errorf("prompt too long: max %d characters, got %d", MaxPromptLength, len(prompt))
}
lower := strings.ToLower(prompt)
for _, pattern := range injectionPatterns {
if strings.Contains(lower, pattern) {
return fmt.Errorf("prompt contains disallowed content")
}
}
return nil
}
func handleAIRequest(w http.ResponseWriter, r *http.Request) {
var req AIRequest
json.NewDecoder(r.Body).Decode(&req)
if err := validatePrompt(req.Prompt); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
callLLM(req.Prompt, MaxPromptTokens)
}
Acceptance Criteria
Problem
The AI microservice passes user input directly to the LLM without validation or sanitization:
Two risks:
Proposed Fix
Acceptance Criteria
README.md