Completely removed the database context recall system while preserving database tables for safety. This major cleanup removes 80+ files and 16,831 lines of code. What was removed: - API layer: 4 routers (conversation-contexts, context-snippets, project-states, decision-logs) with 35+ endpoints - Database models: 5 models (ConversationContext, ContextSnippet, DecisionLog, ProjectState, ContextTag) - Services: 4 service layers with business logic - Schemas: 4 Pydantic schema files - Claude Code hooks: 13 hook files (user-prompt-submit, task-complete, sync-contexts, periodic saves) - Scripts: 15+ scripts (import, migration, testing, tombstone checking) - Tests: 5 test files (context recall, compression, diagnostics) - Documentation: 30+ markdown files (guides, architecture, quick starts) - Utilities: context compression, conversation parsing Files modified: - api/main.py: Removed router registrations - api/models/__init__.py: Removed model imports - api/schemas/__init__.py: Removed schema imports - api/services/__init__.py: Removed service imports - .claude/claude.md: Completely rewritten without context references Database tables preserved: - conversation_contexts, context_snippets, context_tags, project_states, decision_logs (5 orphaned tables remain for safety) - Migration created but NOT applied: 20260118_172743_remove_context_system.py - Tables can be dropped later when confirmed not needed New files added: - CONTEXT_SYSTEM_REMOVAL_SUMMARY.md: Detailed removal report - CONTEXT_SYSTEM_REMOVAL_COMPLETE.md: Final status - CONTEXT_EXPORT_RESULTS.md: Export attempt results - scripts/export-tombstoned-contexts.py: Export tool for future use - migrations/versions/20260118_172743_remove_context_system.py Impact: - Reduced from 130 to 95 API endpoints - Reduced from 43 to 38 active database tables - Removed 16,831 lines of code - System fully operational without context recall Reason for removal: - System was not actively used (no tombstoned contexts found) - Reduces codebase complexity - Focuses on core MSP work tracking functionality - Database preserved for safety (can rollback if needed) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
152 lines
4.8 KiB
Plaintext
152 lines
4.8 KiB
Plaintext
SQL INJECTION VULNERABILITY FIXES - VERIFICATION GUIDE
|
|
=====================================================
|
|
|
|
FILES MODIFIED:
|
|
--------------
|
|
1. api/services/conversation_context_service.py
|
|
2. api/routers/conversation_contexts.py
|
|
|
|
CHANGES SUMMARY:
|
|
---------------
|
|
|
|
FILE 1: api/services/conversation_context_service.py
|
|
----------------------------------------------------
|
|
|
|
Line 13: ADDED import
|
|
OLD: from sqlalchemy import or_, text
|
|
NEW: from sqlalchemy import or_, text, func
|
|
|
|
Lines 178-201: FIXED search_term SQL injection
|
|
OLD:
|
|
if search_term:
|
|
fulltext_match = text(
|
|
"MATCH(title, dense_summary) AGAINST(:search_term IN NATURAL LANGUAGE MODE)"
|
|
).bindparams(search_term=search_term)
|
|
|
|
query = query.filter(
|
|
or_(
|
|
fulltext_match,
|
|
ConversationContext.title.like(f"%{search_term}%"), # VULNERABLE
|
|
ConversationContext.dense_summary.like(f"%{search_term}%") # VULNERABLE
|
|
)
|
|
)
|
|
|
|
NEW:
|
|
if search_term:
|
|
try:
|
|
fulltext_condition = text(
|
|
"MATCH(title, dense_summary) AGAINST(:search_term IN NATURAL LANGUAGE MODE)"
|
|
).bindparams(search_term=search_term)
|
|
|
|
like_condition = or_(
|
|
ConversationContext.title.like(func.concat('%', search_term, '%')), # SECURE
|
|
ConversationContext.dense_summary.like(func.concat('%', search_term, '%')) # SECURE
|
|
)
|
|
|
|
query = query.filter(or_(fulltext_condition, like_condition))
|
|
except Exception:
|
|
like_condition = or_(
|
|
ConversationContext.title.like(func.concat('%', search_term, '%')),
|
|
ConversationContext.dense_summary.like(func.concat('%', search_term, '%'))
|
|
)
|
|
query = query.filter(like_condition)
|
|
|
|
Lines 210-220: FIXED tags SQL injection
|
|
OLD:
|
|
if tags:
|
|
tag_filters = []
|
|
for tag in tags:
|
|
tag_filters.append(ConversationContext.tags.like(f'%"{tag}"%')) # VULNERABLE
|
|
if tag_filters:
|
|
query = query.filter(or_(*tag_filters))
|
|
|
|
NEW:
|
|
if tags:
|
|
# Use secure func.concat to prevent SQL injection
|
|
tag_filters = []
|
|
for tag in tags:
|
|
tag_filters.append(
|
|
ConversationContext.tags.like(func.concat('%"', tag, '"%')) # SECURE
|
|
)
|
|
if tag_filters:
|
|
query = query.filter(or_(*tag_filters))
|
|
|
|
|
|
FILE 2: api/routers/conversation_contexts.py
|
|
--------------------------------------------
|
|
|
|
Lines 79-90: ADDED input validation for search_term
|
|
NEW:
|
|
search_term: Optional[str] = Query(
|
|
None,
|
|
max_length=200,
|
|
pattern=r'^[a-zA-Z0-9\s\-_.,!?()]+$', # Whitelist validation
|
|
description="Full-text search term (alphanumeric, spaces, and basic punctuation only)"
|
|
),
|
|
|
|
Lines 86-90: ADDED validation for tags
|
|
NEW:
|
|
tags: Optional[List[str]] = Query(
|
|
None,
|
|
description="Filter by tags (OR logic)",
|
|
max_items=20 # Prevent DoS
|
|
),
|
|
|
|
Lines 121-130: ADDED runtime tag validation
|
|
NEW:
|
|
# Validate tags to prevent SQL injection
|
|
if tags:
|
|
import re
|
|
tag_pattern = re.compile(r'^[a-zA-Z0-9\-_]+$')
|
|
for tag in tags:
|
|
if not tag_pattern.match(tag):
|
|
raise HTTPException(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
detail=f"Invalid tag format: '{tag}'. Tags must be alphanumeric with hyphens or underscores only."
|
|
)
|
|
|
|
|
|
TESTING THE FIXES:
|
|
-----------------
|
|
|
|
Test 1: Valid Input (should work - HTTP 200)
|
|
curl "http://172.16.3.30:8001/api/conversation-contexts/recall?search_term=test" \
|
|
-H "Authorization: Bearer $JWT_TOKEN"
|
|
|
|
Test 2: SQL Injection Attack (should be rejected - HTTP 422)
|
|
curl "http://172.16.3.30:8001/api/conversation-contexts/recall?search_term=%27%20OR%20%271%27%3D%271" \
|
|
-H "Authorization: Bearer $JWT_TOKEN"
|
|
|
|
Test 3: Tag Injection (should be rejected - HTTP 400)
|
|
curl "http://172.16.3.30:8001/api/conversation-contexts/recall?tags[]=%27%20OR%20%271%27%3D%271" \
|
|
-H "Authorization: Bearer $JWT_TOKEN"
|
|
|
|
|
|
KEY SECURITY IMPROVEMENTS:
|
|
-------------------------
|
|
|
|
1. NO F-STRING INTERPOLATION IN SQL
|
|
- All LIKE patterns use func.concat()
|
|
- All parameterized queries use .bindparams()
|
|
|
|
2. INPUT VALIDATION AT ROUTER LEVEL
|
|
- Regex pattern enforcement
|
|
- Length limits
|
|
- Character whitelisting
|
|
|
|
3. RUNTIME TAG VALIDATION
|
|
- Additional validation in endpoint
|
|
- Prevents bypass of Query validation
|
|
|
|
4. DEFENSE IN DEPTH
|
|
- Multiple layers of protection
|
|
- Validation + Parameterization + Database escaping
|
|
|
|
|
|
DEPLOYMENT NEEDED:
|
|
-----------------
|
|
These changes are in D:\ClaudeTools but need to be deployed to the running API server at 172.16.3.30:8001
|
|
|
|
After deployment, run: bash test_sql_injection_simple.sh
|
|
|