Exposure of Sensitive Information to an Unauthorized Actor
The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information.
There are many different kinds of mistakes that introduce information exposures. The severity of the error can range widely, depending on the context in which the product operates, the type of sensitive information that is revealed, and the benefits it may provide to an attacker.
Comment corriger cette vulnérabilité
Stratégies de prévention pour Information Exposure basées sur 14 règles de détection Shoulder.
Use environment variables for configuration only; never log or return their values
package main import ( "log" "os" ) func main() { apiKey := os.Getenv("API_KEY") - log.Printf("API Key: %s", apiKey) + if apiKey == "" { + log.Fatal("API_KEY not configured") + } + log.Println("API key configured:", len(apiKey) > 0) + // Use apiKey internally, never log or return it }
Store API keys in environment variables, never log them, and protect model endpoints with authentication
- client := openai.NewClient("sk-proj-1234567890abcdefghijklmnop") - log.Printf("Using key: %s", apiKey) - http.Handle("/models/", http.FileServer(http.Dir("./models"))) + client := openai.NewClient(os.Getenv("OPENAI_API_KEY")) + log.Printf("Request completed: model=%s tokens=%d", model, usage.TotalTokens) + + modelsHandler := http.FileServer(http.Dir("./models")) + http.Handle("/models/", authMiddleware(rateLimiter(modelsHandler)))
Mask PII and redact credentials before sending data to LLM APIs, and use structured logging
- resp, _ := client.CreateChatCompletion(ctx, openai.ChatCompletionRequest{ - Messages: []openai.ChatCompletionMessage{{ - Content: fmt.Sprintf("User SSN: %s, Password: %s", user.SSN, password), - }}, - }) - log.Printf("Request: %v", messages) + safeMessage := maskPII(userInput) + safeMessage = redactCredentials(safeMessage) + + resp, _ := client.CreateChatCompletion(ctx, openai.ChatCompletionRequest{ + Messages: []openai.ChatCompletionMessage{{Content: safeMessage}}, + }) + log.Printf("Completed: model=%s tokens=%d", model, resp.Usage.TotalTokens)
Use secrets internally without exposing them in logs, responses, or client-side code
- app.get('/config', (req, res) => { - res.json({ apiKey: process.env.API_KEY }); - }); + const apiKey = process.env.API_KEY; + // Use the key server-side only + const result = await externalApi.call({ key: apiKey }); + res.json({ data: result });
Load API keys from environment variables and proxy LLM calls through your server
const openai = new OpenAI({ - apiKey: 'sk-proj-1234567890abcdefghijklmnop' + apiKey: process.env.OPENAI_API_KEY });
Mask or redact PII and credentials before sending data to LLM APIs
- const response = await openai.chat.completions.create({ - messages: [{ role: 'user', content: `Process: ${userRecord}` }] + const masked = maskPII(userRecord); + const response = await openai.chat.completions.create({ + messages: [{ role: 'user', content: `Process: ${masked}` }] });
Return generic error messages to users; log detailed errors server-side only
- from flask import jsonify - - @app.route('/api/data') - def handler(): - try: - return jsonify(process()) - except Exception as e: - return jsonify({'error': str(e), 'trace': traceback.format_exc()}), 500 + import logging + from flask import jsonify + + logger = logging.getLogger(__name__) + + @app.route('/api/data') + def handler(): + try: + return jsonify(process()) + except Exception as e: + logger.error(f"Error: {e}", exc_info=True) + return jsonify({'error': 'Internal server error'}), 500
Use Presidio or similar libraries to anonymize PII before sending data to LLM APIs
- messages = [{ - 'role': 'user', - 'content': f"User SSN: {user.ssn}, email: {user.email}. Summarize profile." - }] - logging.info(f"Request: {messages}") - response = openai.chat.completions.create(model='gpt-4', messages=messages) + from presidio_analyzer import AnalyzerEngine + from presidio_anonymizer import AnonymizerEngine + + analyzer = AnalyzerEngine() + anonymizer = AnonymizerEngine() + + def anonymize_text(text: str) -> str: + results = analyzer.analyze(text=text, language='en') + return anonymizer.anonymize(text=text, analyzer_results=results).text + + safe_message = anonymize_text(user_message) + messages = [{'role': 'user', 'content': safe_message}] + response = openai.chat.completions.create(model='gpt-4', messages=messages) + logger.info('Completed', extra={'model': 'gpt-4', 'tokens': response.usage.total_tokens})
Use explicit field selection or serializer schemas to exclude sensitive fields from responses
from flask import jsonify from models import User @app.route('/api/users') def get_users(): users = User.query.all() - return jsonify([u.__dict__ for u in users]) + return jsonify([{ + 'id': u.id, + 'email': u.email, + 'name': u.name + } for u in users])
Trouvez les vulnérabilités dans votre code
Utilisez Shoulder pour scanner votre code à la recherche de patterns Exposure of Sensitive Information to an Unauthorized Actor. 14 règles.
# Scan with Shoulder CLI npx @shoulderdev/cli trust --cwe=200 # Or scan entire project npx @shoulderdev/cli trust .
Règles de Détection (14)
Ce qu'il faut surveiller lors des revues de code
Ces patterns indiquent des vulnérabilités potentielles Exposure of Sensitive Information to an Unauthorized Actor. Recherchez-les lors des revues de code et des audits de sécurité.
Scannez votre base de code pour Exposure of Sensitive Information to an Unauthorized Actor
Shoulder CLI trouve les motifs vulnérables dans toute votre base de code.