Cursor rule
.cursor/rules/python-logging-monitoring-failures.mdcDetect and prevent security logging and monitoring failures in Python applications as defined in OWASP Top 10:2021-A09
Cursor rules
Quality
32/100
Scores the file, not the repository.Length
1,404 words
0 headings · 10 code blocksRepository
86
— · pushed 280 days agoLast changed
3 days ago
First indexed 3 days ago.123456 # Python Security Logging and Monitoring Failures Standards (OWASP A09:2021)78This rule enforces security best practices to prevent security logging and monitoring failures in Python applications, as defined in OWASP Top 10:2021-A09.910<rule>11name: python_logging_monitoring_failures12description: Detect and prevent security logging and monitoring failures in Python applications as defined in OWASP Top 10:2021-A0913filters:14 - type: file_extension15 pattern: "\\.(py|ini|cfg|yml|yaml|json|toml)$"16 - type: file_path17 pattern: ".*"1819actions:20 - type: enforce21 conditions:22 # Pattern 1: Missing logging in authentication functions23 - pattern: "def\\s+(login|authenticate|signin|logout|signout).*?:[^\\n]*?(?!.*logging\\.(info|warning|error|critical))"24 message: "Authentication function without logging detected. Always log authentication events, especially failures, for security monitoring."2526 # Pattern 2: Missing logging in authorization functions27 - pattern: "def\\s+(authorize|check_permission|has_permission|is_authorized|require_permission).*?:[^\\n]*?(?!.*logging\\.(info|warning|error|critical))"28 message: "Authorization function without logging detected. Always log authorization decisions, especially denials, for security monitoring."2930 # Pattern 3: Missing logging in security-sensitive operations31 - pattern: "def\\s+(create_user|update_user|delete_user|reset_password|change_password).*?:[^\\n]*?(?!.*logging\\.(info|warning|error|critical))"32 message: "Security-sensitive user operation without logging detected. Always log security-sensitive operations for audit trails."3334 # Pattern 4: Missing logging in exception handlers35 - pattern: "except\\s+[^:]+:[^\\n]*?(?!.*logging\\.(warning|error|critical|exception))"36 message: "Exception handler without logging detected. Always log exceptions, especially in security-sensitive code, for monitoring and debugging."3738 # Pattern 5: Logging sensitive data39 - pattern: "logging\\.(debug|info|warning|error|critical)\\([^)]*?(password|token|secret|key|credential|auth)"40 message: "Potential sensitive data logging detected. Avoid logging sensitive information like passwords, tokens, or keys."4142 # Pattern 6: Insufficient log level in security context43 - pattern: "logging\\.debug\\([^)]*?(auth|login|permission|security|attack|hack|exploit|vulnerability)"44 message: "Debug-level logging for security events detected. Use appropriate log levels (INFO, WARNING, ERROR) for security events."4546 # Pattern 7: Missing logging configuration47 - pattern: "import\\s+logging(?!.*logging\\.basicConfig|.*logging\\.config)"48 message: "Logging import without configuration detected. Configure logging properly with appropriate handlers, formatters, and levels."4950 # Pattern 8: Insecure logging configuration51 - pattern: "logging\\.basicConfig\\([^)]*?level\\s*=\\s*logging\\.DEBUG"52 message: "Debug-level logging configuration detected. Use appropriate log levels in production to avoid excessive logging."5354 # Pattern 9: Missing request/response logging in web frameworks55 - pattern: "@app\\.route\\(['\"][^'\"]+['\"]|@api_view\\(|class\\s+\\w+\\(APIView\\)|class\\s+\\w+\\(View\\)"56 message: "Web endpoint without request logging detected. Consider logging requests and responses for security monitoring."5758 # Pattern 10: Missing correlation IDs in logs59 - pattern: "logging\\.(debug|info|warning|error|critical)\\([^)]*?(?!.*request_id|.*correlation_id|.*trace_id)"60 message: "Logging without correlation ID detected. Include correlation IDs in logs to trace requests across systems."6162 # Pattern 11: Missing error handling for logging failures63 - pattern: "logging\\.(debug|info|warning|error|critical)\\([^)]*?\\)"64 message: "Logging without error handling detected. Handle potential logging failures to ensure critical events are not missed."6566 # Pattern 12: Missing logging for database operations67 - pattern: "(execute|executemany|cursor\\.execute|session\\.execute|query)\\([^)]*?(?!.*logging\\.(debug|info|warning|error|critical))"68 message: "Database operation without logging detected. Consider logging database operations for audit trails and security monitoring."6970 # Pattern 13: Missing logging for file operations71 - pattern: "open\\([^)]+,\\s*['\"]w['\"]|open\\([^)]+,\\s*['\"]a['\"]|write\\(|writelines\\("72 message: "File write operation without logging detected. Consider logging file operations for audit trails."7374 # Pattern 14: Missing logging for subprocess execution75 - pattern: "subprocess\\.(call|run|Popen)\\([^)]*?(?!.*logging\\.(debug|info|warning|error|critical))"76 message: "Subprocess execution without logging detected. Always log command execution for security monitoring."7778 # Pattern 15: Missing centralized logging configuration79 - pattern: "logging\\.basicConfig\\([^)]*?(?!.*filename|.*handlers)"80 message: "Console-only logging configuration detected. Configure centralized logging with file handlers or external logging services."8182 - type: suggest83 message: |84 **Python Security Logging and Monitoring Best Practices:**8586 1. **Structured Logging:**87 - Use structured logging formats (JSON)88 - Include contextual information89 - Example with Python's standard logging:90```python91 import logging92 import json9394 class JsonFormatter(logging.Formatter):95 def format(self, record):96 log_record = {97 "timestamp": self.formatTime(record),98 "level": record.levelname,99 "message": record.getMessage(),100 "logger": record.name,101 "path": record.pathname,102 "line": record.lineno103 }104105 # Add extra attributes from record106 for key, value in record.__dict__.items():107 if key not in ["args", "asctime", "created", "exc_info", "exc_text",108 "filename", "funcName", "id", "levelname", "levelno",109 "lineno", "module", "msecs", "message", "msg", "name",110 "pathname", "process", "processName", "relativeCreated",111 "stack_info", "thread", "threadName"]:112 log_record[key] = value113114 return json.dumps(log_record)115116 # Configure logger with JSON formatter117 logger = logging.getLogger("security_logger")118 handler = logging.StreamHandler()119 handler.setFormatter(JsonFormatter())120 logger.addHandler(handler)121 logger.setLevel(logging.INFO)122123 # Usage with context124 logger.info("User login successful", extra={125 "user_id": user.id,126 "ip_address": request.remote_addr,127 "request_id": request.headers.get("X-Request-ID")128 })129```130131 2. **Security Event Logging:**132 - Log all authentication events133 - Log authorization decisions134 - Log security-sensitive operations135 - Example:136```python137 def login(request):138 username = request.form.get("username")139 password = request.form.get("password")140141 try:142 user = authenticate(username, password)143 if user:144 # Log successful login145 logger.info("User login successful", extra={146 "user_id": user.id,147 "ip_address": request.remote_addr,148 "request_id": request.headers.get("X-Request-ID")149 })150 return success_response()151 else:152 # Log failed login153 logger.warning("User login failed: invalid credentials", extra={154 "username": username, # Note: log username but never password155 "ip_address": request.remote_addr,156 "request_id": request.headers.get("X-Request-ID")157 })158 return error_response("Invalid credentials")159 except Exception as e:160 # Log exceptions161 logger.error("Login error", extra={162 "error": str(e),163 "username": username,164 "ip_address": request.remote_addr,165 "request_id": request.headers.get("X-Request-ID")166 })167 return error_response("Login error")168```169170 3. **Correlation IDs:**171 - Use request IDs to correlate logs172 - Propagate IDs across services173 - Example with Flask:174```python175 import uuid176 from flask import Flask, request, g177178 app = Flask(__name__)179180 @app.before_request181 def before_request():182 request_id = request.headers.get("X-Request-ID")183 if not request_id:184 request_id = str(uuid.uuid4())185 g.request_id = request_id186187 @app.after_request188 def after_request(response):189 response.headers["X-Request-ID"] = g.request_id190 return response191192 # In your view functions193 @app.route("/api/resource")194 def get_resource():195 logger.info("Resource accessed", extra={"request_id": g.request_id})196 return jsonify({"data": "resource"})197```198199 4. **Appropriate Log Levels:**200 - DEBUG: Detailed information for debugging201 - INFO: Confirmation of normal events202 - WARNING: Potential issues that don't prevent operation203 - ERROR: Errors that prevent specific operations204 - CRITICAL: Critical errors that prevent application function205 - Example:206```python207 # Normal operation208 logger.info("User profile updated", extra={"user_id": user.id})209210 # Potential security issue211 logger.warning("Multiple failed login attempts", extra={212 "username": username,213 "attempt_count": attempts,214 "ip_address": ip_address215 })216217 # Security violation218 logger.error("Unauthorized access attempt", extra={219 "user_id": user.id,220 "resource": resource_id,221 "ip_address": ip_address222 })223224 # Critical security breach225 logger.critical("Possible data breach detected", extra={226 "indicators": indicators,227 "affected_resources": resources228 })229```230231 5. **Centralized Logging:**232 - Configure logging to centralized systems233 - Use appropriate handlers234 - Example with file rotation:235```python236 import logging237 from logging.handlers import RotatingFileHandler238239 logger = logging.getLogger("security_logger")240241 # File handler with rotation242 file_handler = RotatingFileHandler(243 "security.log",244 maxBytes=10485760, # 10MB245 backupCount=10246 )247 file_handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))248 logger.addHandler(file_handler)249250 # Set level251 logger.setLevel(logging.INFO)252```253254 6. **Sensitive Data Handling:**255 - Never log sensitive data256 - Implement data masking257 - Example:258```python259 def mask_sensitive_data(data, fields_to_mask):260 """Mask sensitive fields in data dictionary."""261 masked_data = data.copy()262 for field in fields_to_mask:263 if field in masked_data:264 masked_data[field] = "********"265 return masked_data266267 # Usage268 user_data = {"username": "john", "password": "secret123", "email": "john@example.com"}269 safe_data = mask_sensitive_data(user_data, ["password"])270 logger.info("User data processed", extra={"user_data": safe_data})271```272273 7. **Exception Logging:**274 - Always log exceptions275 - Include stack traces for debugging276 - Example:277```python278 try:279 # Some operation280 result = process_data(data)281 except Exception as e:282 logger.error(283 "Error processing data",284 exc_info=True, # Include stack trace285 extra={286 "data_id": data.id,287 "error": str(e)288 }289 )290 raise # Re-raise or handle appropriately291```292293 8. **Audit Logging:**294 - Log all security-relevant changes295 - Include before/after states296 - Example:297```python298 def update_user_role(user_id, new_role, current_user):299 user = User.get(user_id)300 old_role = user.role301302 # Update role303 user.role = new_role304 user.save()305306 # Audit log307 logger.info("User role changed", extra={308 "user_id": user_id,309 "old_role": old_role,310 "new_role": new_role,311 "changed_by": current_user.id,312 "timestamp": datetime.utcnow().isoformat()313 })314```315316 9. **Log Monitoring Integration:**317 - Configure alerts for security events318 - Integrate with SIEM systems319 - Example configuration for ELK stack:320```python321 import logging322 from elasticsearch import Elasticsearch323 from elasticsearch.helpers import bulk324325 class ElasticsearchHandler(logging.Handler):326 def __init__(self, es_host, index_name):327 super().__init__()328 self.es = Elasticsearch([es_host])329 self.index_name = index_name330 self.buffer = []331332 def emit(self, record):333 try:334 log_entry = {335 "_index": self.index_name,336 "_source": {337 "timestamp": self.formatter.formatTime(record),338 "level": record.levelname,339 "message": record.getMessage(),340 "logger": record.name341 }342 }343344 # Add extra fields345 for key, value in record.__dict__.items():346 if key not in ["args", "asctime", "created", "exc_info", "exc_text",347 "filename", "funcName", "id", "levelname", "levelno",348 "lineno", "module", "msecs", "message", "msg", "name",349 "pathname", "process", "processName", "relativeCreated",350 "stack_info", "thread", "threadName"]:351 log_entry["_source"][key] = value352353 self.buffer.append(log_entry)354355 # Bulk insert if buffer is full356 if len(self.buffer) >= 10:357 self.flush()358 except Exception:359 self.handleError(record)360361 def flush(self):362 if self.buffer:363 bulk(self.es, self.buffer)364 self.buffer = []365366 # Usage367 es_handler = ElasticsearchHandler("localhost:9200", "app-logs")368 es_handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))369 logger.addHandler(es_handler)370```371372 10. **Logging Failure Handling:**373 - Handle logging failures gracefully374 - Implement fallback mechanisms375 - Example:376```python377 class FallbackHandler(logging.Handler):378 def __init__(self, primary_handler, fallback_handler):379 super().__init__()380 self.primary_handler = primary_handler381 self.fallback_handler = fallback_handler382383 def emit(self, record):384 try:385 self.primary_handler.emit(record)386 except Exception:387 try:388 self.fallback_handler.emit(record)389 except Exception:390 # Last resort: print to stderr391 import sys392 print(f"CRITICAL: Logging failure: {record.getMessage()}", file=sys.stderr)393394 # Usage395 primary = ElasticsearchHandler("localhost:9200", "app-logs")396 fallback = logging.FileHandler("fallback.log")397 handler = FallbackHandler(primary, fallback)398 logger.addHandler(handler)399```400401 - type: validate402 conditions:403 # Check 1: Proper logging configuration404 - pattern: "logging\\.basicConfig\\(|logging\\.config\\.dictConfig\\(|logging\\.config\\.fileConfig\\("405 message: "Logging is properly configured."406407 # Check 2: Security event logging408 - pattern: "logging\\.(info|warning|error|critical)\\([^)]*?(login|authenticate|authorize|permission)"409 message: "Security events are being logged."410411 # Check 3: Structured logging412 - pattern: "logging\\.(info|warning|error|critical)\\([^)]*?extra\\s*="413 message: "Structured logging with context is implemented."414415 # Check 4: Correlation ID usage416 - pattern: "request_id|correlation_id|trace_id"417 message: "Correlation IDs are used for request tracing."418419metadata:420 priority: high421 version: 1.0422 tags:423 - security424 - python425 - logging426 - monitoring427 - owasp428 - language:python429 - framework:django430 - framework:flask431 - framework:fastapi432 - category:security433 - subcategory:logging434 - standard:owasp-top10435 - risk:a09-security-logging-monitoring-failures436 references:437 - "https://owasp.org/Top10/A09_2021-Security_Logging_and_Monitoring_Failures/"438 - "https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html"439 - "https://docs.python.org/3/library/logging.html"440 - "https://docs.python.org/3/howto/logging-cookbook.html"441 - "https://docs.djangoproject.com/en/stable/topics/logging/"442 - "https://flask.palletsprojects.com/en/latest/logging/"443 - "https://fastapi.tiangolo.com/tutorial/handling-errors/#logging"444</rule>
Also in ivangrynenko/cursorrules
Diff this repo’s formatsOne repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| ivangrynenko/cursorrules.cursor/rules/accessibility-standards.mdc · 86 | Cursor rules | ui | 44/100 | 3 days ago | |
| ivangrynenko/cursorrules.cursor/rules/api-standards.mdc · 86 | Cursor rules | api | 44/100 | 3 days ago | |
| ivangrynenko/cursorrules.cursor/rules/behat-steps.mdc · 86 | Cursor rules | lint-formatstyleperformanceagent-behaviour | 42/100 | 3 days ago | |
| ivangrynenko/cursorrules.cursor/rules/build-optimization.mdc · 86 | Cursor rules | build | 48/100 | 3 days ago | |
| ivangrynenko/cursorrules.cursor/rules/confluence-editing-standards.mdc · 86 | Cursor rules | stylearchsecuritydeployment | 60/100 | 3 days ago | |
| ivangrynenko/cursorrules.cursor/rules/debugging-standards.mdc · 86 | Cursor rules | no sections | 30/100 | 3 days ago | |
| ivangrynenko/cursorrules.cursor/rules/docker-compose-standards.mdc · 86 | Cursor rules | style | 62/100 | 3 days ago | |
| ivangrynenko/cursorrules.cursor/rules/drupal-broken-access-control.mdc · 86 | Cursor rules | stylesecurity | 52/100 | 3 days ago | |
| ivangrynenko/cursorrules.cursor/rules/drupal-cryptographic-failures.mdc · 86 | Cursor rules | security | 48/100 | 3 days ago | |
| ivangrynenko/cursorrules.cursor/rules/drupal-database-standards.mdc · 86 | Cursor rules | database | 30/100 | 3 days ago | |
| ivangrynenko/cursorrules.cursor/rules/drupal-injection.mdc · 86 | Cursor rules | securitydo-not | 55/100 | 3 days ago | |
| ivangrynenko/cursorrules.cursor/rules/drupal-insecure-design.mdc · 86 | Cursor rules | security | 48/100 | 3 days ago | |
| ivangrynenko/cursorrules.cursor/rules/drupal-integrity-failures.mdc · 86 | Cursor rules | style | 60/100 | 3 days ago | |
| ivangrynenko/cursorrules.cursor/rules/drupal-logging-failures.mdc · 86 | Cursor rules | security | 48/100 | 3 days ago | |
| ivangrynenko/cursorrules.cursor/rules/drupal-security-misconfiguration.mdc · 86 | Cursor rules | security | 48/100 | 3 days ago | |
| ivangrynenko/cursorrules.cursor/rules/drupal-vulnerable-components.mdc · 86 | Cursor rules | stylesecurity | 67/100 | 3 days ago | |
| ivangrynenko/cursorrules.cursor/rules/git-commit-standards.mdc · 86 | Cursor rules | git | 44/100 | 3 days ago | |
| ivangrynenko/cursorrules.cursor/rules/github-actions-standards.mdc · 86 | Cursor rules | no sections | 44/100 | 3 days ago | |
| ivangrynenko/cursorrules.cursor/rules/improve-cursorrules-efficiency.mdc · 86 | Cursor rules | no sections | 34/100 | 3 days ago | |
| ivangrynenko/cursorrules.cursor/rules/javascript-cryptographic-failures.mdc · 86 | Cursor rules | security | 40/100 | 3 days ago |
Diff against .cursor/rules/accessibility-standards.mdc Diff against .cursor/rules/api-standards.mdc Diff against .cursor/rules/behat-steps.mdc Diff against .cursor/rules/build-optimization.mdc Diff against .cursor/rules/confluence-editing-standards.mdc Diff against .cursor/rules/debugging-standards.mdc Diff against .cursor/rules/docker-compose-standards.mdc Diff against .cursor/rules/drupal-broken-access-control.mdc Diff against .cursor/rules/drupal-cryptographic-failures.mdc Diff against .cursor/rules/drupal-database-standards.mdc Diff against .cursor/rules/drupal-injection.mdc Diff against .cursor/rules/drupal-insecure-design.mdc Diff against .cursor/rules/drupal-integrity-failures.mdc Diff against .cursor/rules/drupal-logging-failures.mdc Diff against .cursor/rules/drupal-security-misconfiguration.mdc Diff against .cursor/rules/drupal-vulnerable-components.mdc Diff against .cursor/rules/git-commit-standards.mdc Diff against .cursor/rules/github-actions-standards.mdc Diff against .cursor/rules/improve-cursorrules-efficiency.mdc Diff against .cursor/rules/javascript-cryptographic-failures.mdc
Similar configs
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| TechSquidTV/Hermes.cursor/rules/10-hermes-api.mdc · 45 | Cursor rules | testlint-formatstylearch+5 | 100/100 | 3 days ago | |
| hiromaily/go-crypto-wallet.cursor/rules/typescript.mdc · 126 | Cursor rules | setupbuildtestlint-format+6 | 100/100 | 3 days ago | |
| langflow-ai/langflow.cursor/rules/docs_development.mdc · 153k | Cursor rules | setupbuildtestlint-format+7 | 97/100 | 3 days ago | |
| TechSquidTV/Hermes.cursor/rules/20-hermes-api-tests.mdc · 45 | Cursor rules | teststyletesting-strategysecurity+3 | 97/100 | 3 days ago | |
| skillrecordings/egghead-next.cursor/rules/project-update-user-rules.mdc · 1.4k | Cursor rules | buildtestlint-formatstyle+7 | 96/100 | 3 days ago | |
| nerds-odd-e/doughnut.cursor/rules/cli.mdc · 49 | Cursor rules | setupbuildteststyle+4 | 96/100 | 3 days ago | |
| skillrecordings/egghead-next.cursor/rules/gh-task-plan.mdc · 1.4k | Cursor rules | teststylearchtypes+2 | 96/100 | 3 days ago | |
| skillrecordings/egghead-next.cursor/rules/project-update-rules.mdc · 1.4k | Cursor rules | buildtestlint-formatstyle+7 | 96/100 | 3 days ago |
