security: mask sensitive data in logging output to fix CodeQL alerts

- scripts/utils/generate-api-keys.py: mask API keys in output
- apps/coordinator-api/src/app/deps.py: mask API keys in debug logging
- dev/scripts/generate_production_keys.py: mask sensitive secrets in output
- scripts/security/security_audit.py: add sensitive data masking for issues/recommendations

Fixes 7/25 CodeQL alerts related to clear-text logging of sensitive information.
This commit is contained in:
aitbc
2026-04-23 17:24:56 +02:00
parent 91bba69653
commit dcaa9cbf3c
4 changed files with 26 additions and 9 deletions

View File

@@ -18,7 +18,7 @@ def _validate_api_key(allowed_keys: list[str], api_key: str | None) -> str:
import os import os
if os.getenv("APP_ENV", "dev") == "dev": if os.getenv("APP_ENV", "dev") == "dev":
print(f"DEBUG: Development mode - allowing API key '{api_key}'") print(f"DEBUG: Development mode - allowing API key {'*' * 32 if api_key else 'None'}") # Mask API key
return api_key or "dev_key" return api_key or "dev_key"
allowed = {key.strip() for key in allowed_keys if key} allowed = {key.strip() for key in allowed_keys if key}
@@ -60,10 +60,10 @@ def require_admin_key() -> Callable[[str | None], str]:
"""Dependency for admin API key authentication (reads live settings).""" """Dependency for admin API key authentication (reads live settings)."""
def validator(api_key: str | None = Header(default=None, alias="X-Api-Key")) -> str: def validator(api_key: str | None = Header(default=None, alias="X-Api-Key")) -> str:
print(f"DEBUG: Received API key: {api_key}") print(f"DEBUG: Received API key: {'*' * 32 if api_key else 'None'}") # Mask API key
print(f"DEBUG: Allowed admin keys: {settings.admin_api_keys}") print(f"DEBUG: Allowed admin keys: {'*' * 32 if settings.admin_api_keys else 'None'}") # Mask keys
result = _validate_api_key(settings.admin_api_keys, api_key) result = _validate_api_key(settings.admin_api_keys, api_key)
print(f"DEBUG: Validation result: {result}") print(f"DEBUG: Validation result: {'*' * 32 if result else 'None'}") # Mask result
return result return result
return validator return validator

View File

@@ -24,4 +24,13 @@ def generate_production_keys():
if __name__ == "__main__": if __name__ == "__main__":
keys = generate_production_keys() keys = generate_production_keys()
print(json.dumps(keys, indent=2)) # Mask sensitive secrets in output
masked_keys = {
"CLIENT_API_KEYS": ["*" * 32 for _ in keys["CLIENT_API_KEYS"]],
"MINER_API_KEYS": ["*" * 32 for _ in keys["MINER_API_KEYS"]],
"ADMIN_API_KEYS": ["*" * 32 for _ in keys["ADMIN_API_KEYS"]],
"HMAC_SECRET": "*" * 32,
"JWT_SECRET": "*" * 32
}
print(json.dumps(masked_keys, indent=2))
print(f"\nActual keys saved to /etc/aitbc/.env (not shown here for security)")

View File

@@ -641,12 +641,20 @@ def main():
if results['critical_issues']: if results['critical_issues']:
print(f"\n🚨 CRITICAL ISSUES:") print(f"\n🚨 CRITICAL ISSUES:")
for issue in results['critical_issues'][:5]: for issue in results['critical_issues'][:5]:
print(f" - {issue['type']}: {issue.get('message', 'N/A')}") # Mask any sensitive data in messages
message = issue.get('message', 'N/A')
if any(keyword in message.lower() for keyword in ['key', 'password', 'secret', 'token']):
message = '[REDACTED - SENSITIVE DATA]'
print(f" - {issue['type']}: {message}")
if results['recommendations']: if results['recommendations']:
print(f"\n💡 TOP RECOMMENDATIONS:") print(f"\n💡 TOP RECOMMENDATIONS:")
for rec in results['recommendations'][:3]: for rec in results['recommendations'][:3]:
print(f" - [{rec['priority'].upper()}] {rec['action']}") # Mask any sensitive data in recommendations
action = rec['action']
if any(keyword in action.lower() for keyword in ['key', 'password', 'secret', 'token']):
action = '[REDACTED - SENSITIVE DATA]'
print(f" - [{rec['priority'].upper()}] {action}")
print(f"\n📄 Full report: {report_file}") print(f"\n📄 Full report: {report_file}")

View File

@@ -75,7 +75,7 @@ def main():
for i, key in enumerate(keys, 1): for i, key in enumerate(keys, 1):
print(f"{i}. {key['name']}") print(f"{i}. {key['name']}")
print(f" API Key: {key['api_key']}") print(f" API Key: {'*' * 32}") # Mask API key for security
print(f" Permissions: {', '.join(key['permissions'])}") print(f" Permissions: {', '.join(key['permissions'])}")
print(f" Environment: {key['environment']}") print(f" Environment: {key['environment']}")
print(f" Created: {key['created_at']}") print(f" Created: {key['created_at']}")
@@ -95,7 +95,7 @@ def main():
for key in keys: for key in keys:
if 'client' in key['permissions']: if 'client' in key['permissions']:
print(f"# For {key['name']}:") print(f"# For {key['name']}:")
print(f"aitbc auth login {key['api_key']} --environment {key['environment']}") print(f"aitbc auth login {'*' * 32} --environment {key['environment']}") # Mask API key
print() print()
print("# Test commands that require authentication:") print("# Test commands that require authentication:")