13 views
This guide focuses on Log Injection Defenses for production systems, with practical trade-offs for reliability, security, and cost.
Classic log injection smuggles newlines into plaintext logs to forge entries. Structured JSON reduces that risk—but only if you actually serialize objects and scrub control characters. User agents, search queries, and ticket titles still break SIEM parsers or plant fake password=... lines when teams string-concatenate.
⚡ TL;DR: Always log via JSON serializers (pino/winston/structlog); never interpolate user strings into format templates as raw lines. Strip/escape\n,\r,\u0000, and ANSI. Cap field lengths. Pair with Secret-Aware Context Filters, CloudWatch Logs Anomaly Detection, and Lambda Log Buffering.
Log Injection Defenses: production guidance
text
User sets display_name = "alice\nERROR auth ok user=admin"
Plaintext logger:
INFO user=alice
ERROR auth ok user=admin ← forged
JSON logger with raw concat can still break if you print strings by hand
Node: pino with redaction and scrubbing
typescript
import pino from "pino";
function scrub(value: unknown): unknown {
if (typeof value !== "string") return value;
return value
.replace(/[\u0000-\u001f\u007f]/g, " ")
.slice(0, 512);
}
const log = pino({
level: "info",
redact: {
paths: ["req.headers.authorization", "password", "token", "*.secret"],
censor: "[REDACTED]",
},
serializers: {
user(u) {
return { id: u.id, name: scrub(u.name) };
},
},
});
// GOOD
log.info({ user: { id, name: req.body.name } }, "profile_updated");
// BAD
console.log(`profile_updated name=${req.body.name}`);
Python: structlog / stdlib JSON
python
import json
import logging
import re
_CTRL = re.compile(r"[\x00-\x1f\x7f]")
def scrub(s: str, limit: int = 512) -> str:
return _CTRL.sub(" ", s)[:limit]
class JsonFormatter(logging.Formatter):
def format(self, record: logging.LogRecord) -> str:
payload = {
"level": record.levelname,
"msg": scrub(str(record.getMessage())),
"correlation_id": scrub(getattr(record, "correlation_id", "")),
}
if hasattr(record, "user_name"):
payload["user_name"] = scrub(str(record.user_name))
return json.dumps(payload, ensure_ascii=False)
# GOOD: extra fields as structured keys
logger.info("profile_updated", extra={"user_name": scrub(name)})
# BAD
logger.info("profile_updated name=%s" % name)
SIEM and CloudWatch considerations
Even with JSON, unbounded user fields inflate ingestion cost and confuse anomaly detectors—cap lengths and drop high-cardinality free text from indices when possible (Lambda Log Buffering, CloudWatch Logs Anomaly Detection). Never log secrets; treat tokens like Secret-Aware Context Filters.Closing checklist
- [ ] All services use structured JSON loggers (no raw console concat)
- [ ] User-controlled strings scrubbed of control chars and length-capped
- [ ] Redaction paths cover auth headers, passwords, tokens
- [ ] CI lint bans
console.log(\…${user})patterns where feasible - [ ] SIEM parsers tested against adversarial newline payloads
- [ ] Correlation IDs remain trusted server-side values
Related reading
- Secret-Aware Context Filters: Stop AI Editors From Shipping Keys
- CloudWatch Logs Anomaly Detection: Ignore Deploy Noise, Catch Novel Errors
- Lambda Log Buffering: Cut CloudWatch Ingestion Without Losing Correlation
- Prompt Injection in Trackers: Sanitize Jira Before Agents Read Issues
Watch: 100 Days of AI on YouTube
Short videos from CheatCoders, one AI engineering topic per day.
Most viewed
- Python Decorators Explained: From Simple Wrappers to Production Patterns
- Claude Code vs Cursor vs GitHub Copilot: Choose by Workflow, and Set Up One Repo That Works With All Three
- AI Agent Frameworks in 2025: LangGraph vs CrewAI vs AutoGen vs Raw API
- Python String Methods: Every str Method With Real Production Examples
- Css Animation Performance: Performance-Optimized Motion for Modern UIs
Newly added
- AWS Systems Manager Parameter Store: Hierarchical Runtime Config for Coding Agents
- Amazon Cognito Identity Pools: Federate Coding-Agent Tool Callers Without Long-Lived Keys
- Amazon Athena for Coding Agents: Query Tool Audit Logs and Eval Traces on S3 Without a Warehouse
- AWS Batch for Coding Agents: Parallel Overnight PR Reviews and Long-Running Jobs Without Lambda Timeouts
- Amazon Bedrock Prompt Management: Version and A/B Test Coding-Agent System Prompts
Deep-dive PDF
Get the expanded guide for this post — extra diagrams-style checklists, failure modes, and a production walkthrough. Free when you subscribe to CheatCoders.
Already subscribed? or open the subscribe page.
Discover more from CheatCoders
Subscribe to get the latest posts sent to your email.
