Issue #2: Unprotected Chat Summary Trigger (CRITICAL) - Add authentication and admin authorization to /trigger endpoint - Add path validation to prevent directory traversal - Block access to system directories (/etc, /root, /sys, /proc, /boot) - Add tests for unauthorized access and invalid paths Issue #3: Exception Information Disclosure (HIGH) - Replace raw exception messages with generic errors - Log full exception details server-side with logger.exception() - Affected files: auth.py, files.py, passkey.py, opc_agents.py - Prevents information leakage about system architecture Security Impact: - Prevents unauthenticated file system writes - Reduces reconnaissance opportunities for attackers - Maintains security while preserving debugging capability Tests: 214 passing, all security tests verified
This commit is contained in:
@@ -170,7 +170,7 @@ class TestChatSummaryTrigger:
|
||||
"""Test trigger summary endpoint."""
|
||||
|
||||
def test_trigger_summary_success(self, test_app, mock_config, admin_headers, tmp_path):
|
||||
"""Test triggering a summary generation."""
|
||||
"""Test triggering a summary generation as admin."""
|
||||
trigger_path = tmp_path / "trigger"
|
||||
|
||||
with patch.dict(os.environ, {"CHAT_SUMMARY_TRIGGER": str(trigger_path)}):
|
||||
@@ -193,6 +193,32 @@ class TestChatSummaryTrigger:
|
||||
assert trigger_path.parent.exists()
|
||||
assert trigger_path.exists()
|
||||
|
||||
def test_trigger_summary_as_member(self, test_app, mock_config, temp_auth_file, temp_rbac_file, tmp_path):
|
||||
"""Test that non-admin cannot trigger summary."""
|
||||
from datetime import timedelta
|
||||
|
||||
from auth_service import create_access_token
|
||||
|
||||
member_token = create_access_token(data={"sub": "memberuser", "role": "member"}, expires_delta=timedelta(minutes=30))
|
||||
headers = {"Authorization": f"Bearer {member_token}"}
|
||||
|
||||
trigger_path = tmp_path / "trigger"
|
||||
with patch.dict(os.environ, {"CHAT_SUMMARY_TRIGGER": str(trigger_path)}):
|
||||
response = test_app.post("/api/chat-summary/trigger", headers=headers)
|
||||
|
||||
# Page-level RBAC blocks access before endpoint-level check
|
||||
assert response.status_code == 403
|
||||
assert "denied" in response.json()["detail"].lower()
|
||||
|
||||
def test_trigger_summary_invalid_path(self, test_app, mock_config, admin_headers):
|
||||
"""Test that invalid trigger paths are rejected."""
|
||||
# Try to write outside /app/data/
|
||||
with patch.dict(os.environ, {"CHAT_SUMMARY_TRIGGER": "/etc/passwd"}):
|
||||
response = test_app.post("/api/chat-summary/trigger", headers=admin_headers)
|
||||
|
||||
assert response.status_code == 400
|
||||
assert "Invalid trigger path" in response.json()["detail"]
|
||||
|
||||
def test_trigger_summary_without_auth(self, test_app, mock_config):
|
||||
"""Test triggering summary without authentication."""
|
||||
response = test_app.post("/api/chat-summary/trigger")
|
||||
|
||||
Reference in New Issue
Block a user