GDPR Article 5(1)(f) requires that personal data be processed with appropriate security, including protection against unauthorized access — which includes log aggregation services. CWE-532 (Insertion of Sensitive Information into Log File) and OWASP A09 (Security Logging and Monitoring Failures) both apply when prompt content ends up in application logs. Application logs typically flow to third-party aggregators like Datadog, Logtail, or Better Stack, each with their own access controls, retention windows, and breach surfaces. When a developer logs console.log({ messages, model }) during a debugging session and forgets to remove it, every user prompt written since is now stored in a system with weaker controls than the primary database.
High because prompt content in persistent logs constitutes an unauthorized third-party disclosure under GDPR Art. 5(1)(f) and CWE-532, multiplying the number of parties that hold user data without consent.
Replace full-payload logging with metadata-only logging in every AI API call handler. Log enough to debug failures; never log what users said.
// Before (unsafe):
console.log('AI request:', { messages, model })
// After (safe):
console.log('AI request:', {
model,
messageCount: messages.length,
estimatedTokens: estimateTokens(messages),
requestId: crypto.randomUUID()
})
For Sentry or similar error reporters, scrub before attaching context:
try {
await callAiProvider(messages)
} catch (error) {
Sentry.captureException(error, {
extra: { context: 'AI generation failed', model }
// NOT: prompt, messages, userInput
})
throw error
}
Audit every console.log, logger.info, and logger.debug call in your AI pipeline and remove any that include the messages array or user input string.
ID: ai-data-privacy.pii-protection.no-pii-in-logs
Severity: high
What to look for: Enumerate every relevant item. Examine logging statements in and around AI API call handlers. Look for console.log, console.debug, logger.info, or similar calls that output the full prompt, the messages array, the user input string, or the AI response content. Also check error handling blocks for logging calls that include request payloads. Look for patterns like console.log(prompt), logger.info({ messages }), console.log(req.body), or similar in AI route handlers.
Pass criteria: At least 1 of the following conditions is met. Logging near AI API calls records only metadata — token counts, model name, latency, request ID, error codes — without including the actual prompt text, user message content, or AI response content.
Fail criteria: Any console.log, logger, or winston/pino/bunyan call in the AI pipeline outputs the full user message, the full prompt array, or the full AI response text to logs that persist beyond the request lifecycle.
Skip (N/A) when: The logging statement is inside a NODE_ENV === 'development' guard or a debug flag check, and would not run in production.
Detail on fail: "Logging call in [file] outputs full prompt/message content to persistent logs — user input reaching AI provider is also reaching log storage"
Remediation: Application logs are typically less access-controlled than your primary database and are often shipped to third-party log aggregators (Datadog, Logtail, Better Stack, etc.). Prompt content ending up in logs means it has been shared with yet another third party.
Log only metadata:
// Before (unsafe):
console.log('AI request:', { messages, model })
// After (safe):
console.log('AI request:', {
model,
messageCount: messages.length,
estimatedTokens: estimateTokens(messages),
requestId: crypto.randomUUID()
})
For error logging with Sentry or similar, scrub the payload before attaching context:
try {
await callAiProvider(messages)
} catch (error) {
Sentry.captureException(error, {
extra: { context: 'AI generation failed', model }
// Do NOT include: prompt, messages, userInput
})
throw error
}