This security audit identified 19 security issues across the Wildbox Security Platform codebase, ranging from Critical to Low severity. The platform has implemented several good security practices (bcrypt password hashing, defusedxml for XXE protection, proper JWT implementation) but has notable vulnerabilities in authentication, CORS configuration, code injection risks, and hardcoded credentials in committed files.
File: /Users/fab/GitHub/wildbox/open-security-agents/app/main.py (Line 266)
Severity: CRITICAL
Risk: Remote Code Execution (RCE)
task_metadata = eval(task_metadata_str.decode())
Issue: Using eval() to deserialize untrusted data from Redis can allow arbitrary code execution if an attacker can control the Redis data.
Fix:
json.loads() for safe JSON deserializationjson.dumps() when storing instead of str(task_metadata)task_metadata = json.loads(task_metadata_str.decode())
File: /Users/fab/GitHub/wildbox/open-security-identity/.env
Severity: CRITICAL
Risk: Credential Exposure, Unauthorized Access
Issues Found:
DATABASE_URL=postgresql+asyncpg://postgres:password@localhost:5432/identity_db (plaintext password)JWT_SECRET_KEY=INSECURE-DEFAULT-JWT-SECRET-CHANGE-THIS (default/insecure key)Fix:
git filter-branch --tree-filter 'rm -f open-security-identity/.env' HEAD.env and .env.* except .env.exampleFiles:
/Users/fab/GitHub/wildbox/open-security-agents/app/main.py (Line 180)/Users/fab/GitHub/wildbox/open-security-responder/app/main.py (Line 133)Severity: CRITICAL Risk: Unauthorized Access to Core Functionality
Issue: Public endpoints that execute critical operations without authentication:
@app.post("/v1/analyze", ...)
async def analyze_ioc(request: AnalysisTaskRequest): # NO AUTH CHECK
"""Submit IOC for analysis"""
@app.post("/v1/playbooks/{playbook_id}/execute")
async def execute_playbook(playbook_id: str, ...): # NO AUTH CHECK
"""Execute a playbook"""
Fix: Add authentication dependencies:
from fastapi import Depends
from app.auth import get_current_user
@app.post("/v1/analyze", ...)
async def analyze_ioc(
request: AnalysisTaskRequest,
current_user: User = Depends(get_current_user)
):
Files:
/Users/fab/GitHub/wildbox/open-security-agents/app/main.py (Line 91)/Users/fab/GitHub/wildbox/open-security-responder/app/main.py (Line 79)/Users/fab/GitHub/wildbox/open-security-data/app/config.py (Line 64)Severity: HIGH Risk: Cross-Site Request Forgery (CSRF), Data Exfiltration
Issue:
CORSMiddleware,
allow_origins=["*"], # Dangerous!
allow_credentials=True, # Even more dangerous with wildcard
Fix: Restrict to specific domains:
allow_origins=[
os.getenv("CORS_ORIGINS", "http://localhost:3000").split(",")
],
allow_credentials=True,
For data service - explicitly enumerate:
cors_origins: List[str] = field(default_factory=lambda: [
"https://dashboard.wildbox.com",
"https://app.wildbox.com"
])
File: /Users/fab/GitHub/wildbox/open-security-sensor/sensor/collectors/osquery_manager.py (Line 411)
Severity: HIGH
Risk: SQL Injection via Dynamic Table Names
table_pattern = r'(?:FROM|JOIN)\s+(\w+)'
tables = re.findall(table_pattern, query, re.IGNORECASE)
for table in tables:
test_query = f"SELECT COUNT(*) FROM {table} LIMIT 1;" # VULNERABLE
result = subprocess.run(['osqueryi', '--json', test_query], ...)
Issue: While regex restricts to \w+, it’s still unsafe. Even though subprocess is not using shell=True, this is fragile.
Fix: Use osquery’s native validation APIs instead:
# Use osquery's schema API instead of dynamic query construction
# Or use parameterized queries if available
Files:
/Users/fab/GitHub/wildbox/open-security-agents/app/main.py/Users/fab/GitHub/wildbox/open-security-responder/app/main.pySeverity: HIGH Risk: Denial of Service (DoS), Resource Exhaustion
Issue: Public endpoints like /v1/analyze and /v1/playbooks/{id}/execute can be called unlimited times, consuming resources.
Fix: Implement rate limiting:
from slowapi import Limiter
from slowapi.util import get_remote_address
limiter = Limiter(key_func=get_remote_address)
@app.post("/v1/analyze")
@limiter.limit("10/minute") # 10 requests per minute per IP
async def analyze_ioc(request: Request, ...):
Files:
/Users/fab/GitHub/wildbox/open-security-identity/demo.py (Line 22)/Users/fab/GitHub/wildbox/open-security-identity/auth.py (Line 291)Severity: HIGH Risk: Information Disclosure, Credentials in Logs
# demo.py line 22
print(f"Password: {password}") # Logs plaintext password
# auth.py line 291
print(f"Authentication error: {str(e)}") # May include sensitive info
Fix: Remove password logging and mask sensitive data:
# DON'T log passwords ever
logger.debug("Authentication attempt") # OK
# Mask errors
except Exception as e:
logger.error("Authentication error occurred", exc_info=False)
File: /Users/fab/GitHub/wildbox/docker-compose.yml (Lines 28-36)
Severity: HIGH
Risk: Data Compromise, Unauthorized Access
- DATABASE_URL=${DATABASE_URL:-postgresql+asyncpg://postgres:postgres@postgres:5432/identity}
- JWT_SECRET_KEY=${JWT_SECRET_KEY:-please-set-jwt-secret-in-env-file}
- STRIPE_WEBHOOK_SECRET=${STRIPE_WEBHOOK_SECRET:-whsec_set_your_webhook_secret}
- INITIAL_ADMIN_PASSWORD=${INITIAL_ADMIN_PASSWORD:-CHANGE-THIS-PASSWORD}
- API_KEY=${API_KEY:-wbx-<REDACTED-LEAKED-KEY>}
Fix: Remove all default values. Use only ${VAR_NAME} which will fail if not set:
- DATABASE_URL=${DATABASE_URL} # Will fail if not set - this is good!
- JWT_SECRET_KEY=${JWT_SECRET_KEY}
- INITIAL_ADMIN_PASSWORD=${INITIAL_ADMIN_PASSWORD}
Also, change line 58 API_KEY - this looks like a real key was exposed:
- API_KEY=${API_KEY:-wbx-<REDACTED-LEAKED-KEY>} # EXPOSED KEY!
Immediate Action: If wbx-<REDACTED-LEAKED-KEY> is a real key, rotate it immediately.
File: /Users/fab/GitHub/wildbox/open-security-agents/app/main.py (Line 181)
Severity: MEDIUM
Risk: Injection Attacks, Unexpected Behavior
async def analyze_ioc(request: AnalysisTaskRequest):
# No validation of IOC type/value for malicious patterns
task_metadata = {
"ioc": request.ioc.dict(), # May contain malicious data
}
Fix: Add robust input validation:
from pydantic import validator, Field
class AnalysisTaskRequest(BaseModel):
ioc: IOC
priority: str = Field(..., regex="^(low|medium|high|critical)$")
class IOC(BaseModel):
type: str = Field(..., regex="^(ip|domain|hash|url)$")
value: str = Field(..., min_length=1, max_length=2048)
@validator('value')
def validate_ioc_value(cls, v, values):
ioc_type = values.get('type')
# Validate based on type
...
File: /Users/fab/GitHub/wildbox/open-security-tools/app/tools/hash_generator/main.py (Lines 28-65)
Severity: MEDIUM
Risk: Weak Cryptography, Compliance Issues
ALGORITHMS = {
'md5': hashlib.md5, # BROKEN
'sha1': hashlib.sha1, # DEPRECATED
...
}
DEPRECATED = ['md5', 'sha1']
Issue: While these are marked as deprecated, they’re still available. MD5 and SHA1 have known collision attacks.
Fix: Remove or move to a “legacy only” mode:
ALGORITHMS = {
'sha256': hashlib.sha256,
'sha512': hashlib.sha512,
'blake2b': hashlib.blake2b,
}
LEGACY_ALGORITHMS = { # Only for compatibility
'md5': hashlib.md5,
'sha1': hashlib.sha1,
}
File: /Users/fab/GitHub/wildbox/open-security-identity/app/config.py (Line 40)
Severity: MEDIUM
Risk: Cross-Site Request Forgery
Issue:
cors_allow_headers: list[str] = ["*"] # Allows any headers - CSRF not checked
Fix: Be explicit about allowed headers:
cors_allow_headers: list[str] = [
"Content-Type",
"Authorization",
"X-CSRF-Token",
]
cors_expose_headers: list[str] = [
"X-CSRF-Token",
]
Also add CSRF middleware for state-changing operations.
Severity: MEDIUM Risk: Clickjacking, XSS, MIME Type Sniffing
Issue: No explicit security headers configured in FastAPI applications.
Fix: Add middleware for security headers:
from fastapi.middleware import Middleware
from fastapi import FastAPI
@app.middleware("http")
async def add_security_headers(request, call_next):
response = await call_next(request)
response.headers["X-Content-Type-Options"] = "nosniff"
response.headers["X-Frame-Options"] = "DENY"
response.headers["X-XSS-Protection"] = "1; mode=block"
response.headers["Strict-Transport-Security"] = "max-age=31536000; includeSubDomains"
response.headers["Content-Security-Policy"] = "default-src 'self'; script-src 'self'"
return response
File: /Users/fab/GitHub/wildbox/open-security-sensor/sensor/collectors/log_forwarder.py (Line 281)
Severity: MEDIUM
Risk: Command Injection
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
Issue: While subprocess.run without shell=True is safer, the cmd source should be validated.
Fix: Use list form with explicit parameters:
result = subprocess.run(
['/usr/bin/journalctl', '-n', '100', '--output', 'json'], # Explicit args
capture_output=True,
text=True,
timeout=30,
cwd=None, # Explicitly set
)
File: /Users/fab/GitHub/wildbox/open-security-cspm/app/main.py (Multiple lines)
Severity: MEDIUM
Risk: Injection Attacks, Unexpected Type Confusion
metadata = json.loads(metadata_json) # Assumes valid JSON from Redis
Issue: No validation of JSON schema before processing.
Fix: Use Pydantic models for validation:
from pydantic import BaseModel, ValidationError
class TaskMetadata(BaseModel):
task_id: str
status: str
...
try:
metadata = TaskMetadata(**json.loads(metadata_json))
except ValidationError as e:
logger.error(f"Invalid metadata: {e}")
raise HTTPException(400, "Invalid metadata format")
File: /Users/fab/GitHub/wildbox/open-security-guardian/guardian/settings.py (Line 23)
Severity: MEDIUM
Risk: Session Hijacking, CSRF Token Forgery
SECRET_KEY = os.getenv('SECRET_KEY', 'your-secret-key-here-change-in-production')
Fix: Require environment variable:
SECRET_KEY = os.getenv('SECRET_KEY')
if not SECRET_KEY:
raise ValueError("SECRET_KEY environment variable must be set")
# Validate it's not a default value
if SECRET_KEY in ['your-secret-key-here-change-in-production', 'change-me']:
raise ValueError("SECRET_KEY must be changed from default")
File: /Users/fab/GitHub/wildbox/open-security-tools/app/api/router.py (Line 22)
Severity: LOW
Risk: Information Disclosure
Issue: API key required but endpoints don’t return 401 uniformly:
async def list_tools(request: Request, api_key: str = Depends(verify_api_key)):
# verify_api_key might raise HTTPException
Fix: Ensure consistent error responses and validate thoroughly.
File: /Users/fab/GitHub/wildbox/docker-compose.yml (Line 59)
Severity: LOW (if DEBUG is false in production)
Risk: Information Disclosure
- DEBUG=${DEBUG:-false}
Fix: Add validation to ensure DEBUG is false:
if os.getenv('ENVIRONMENT') == 'production' and os.getenv('DEBUG') == 'true':
raise ValueError("DEBUG cannot be true in production")
File: /Users/fab/GitHub/wildbox/tests/verify_authentication_complete.py (Line 581)
Severity: LOW
Risk: Weak Authentication
password = "demopassword123" # Simple password
Fix: Use stronger test passwords:
password = "TempDemo@2024!SecurePass" # Meets complexity requirements
Severity: LOW Risk: Information Disclosure
Issue: Swagger/OpenAPI docs exposed at /docs without authentication.
Fix: Disable in production or protect:
# Only enable in development
if not settings.debug:
docs_url = None
redoc_url = None
app = FastAPI(
title="...",
docs_url=docs_url,
redoc_url=redoc_url,
)
| Severity | Count | Issues |
|---|---|---|
| CRITICAL | 3 | Code injection (eval), Hardcoded credentials, Missing authentication |
| HIGH | 6 | Permissive CORS, SQL injection risk, No rate limiting, Plaintext logging, Default secrets, Guardian defaults |
| MEDIUM | 8 | Input validation, Weak hashes, No CSRF protection, Missing headers, Subprocess risks, Insecure deserialization, Django secret, API validation |
| LOW | 2 | Debug flag, Weak test passwords, API doc security |
Total Issues: 19
wbx-<REDACTED-LEAKED-KEY> hasn’t been exposedbandit for Python security checkssafety for dependency vulnerability scanningtrivy or snyk for container scanninggit-secrets or detect-secrets pre-commit hooksCurrent implementation is partially aligned with:
Audit Date: November 7, 2024 Audit Scope: Python FastAPI/Django services, Docker configuration, dependency files Tools Used: Manual code review, grep/pattern matching, dependency analysis