php-uptelligence/changelog/2026/jan/code-review.md
Snider ef8a40829f security: fix shell injection in AssetTrackerService
- Add package name validation with strict regex patterns
- Convert all Process::run() calls to array syntax
- Support Composer and NPM package name formats
- Add comprehensive shell injection tests (20 attack patterns)
- Update security docs and changelog

Fixes P2 shell injection vulnerability from security audit.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 12:21:07 +00:00

145 lines
8 KiB
Markdown

# Uptelligence Module Review
**Updated:** 2026-01-21 - All recommended improvements implemented
## Overview
The Uptelligence module is an internal tooling system for tracking and managing upstream vendor software updates. It provides:
1. **Vendor Tracking** - Monitor licensed software (66biolinks, Mixpost Pro/Enterprise), OSS projects, and plugins for version changes
2. **Diff Analysis** - Compare versions, cache diffs, and auto-categorise changes by type (security, controller, model, view, etc.)
3. **AI Analysis** - Use Claude or OpenAI to analyse diffs and generate prioritised porting todos
4. **Asset Tracking** - Monitor Composer/NPM packages, fonts, and CDN resources for updates
5. **Pattern Library** - Store reusable code patterns with variants for MCP context
6. **Issue Generation** - Auto-create GitHub/Gitea issues from todos
7. **Agent Plan Integration** - Generate structured porting plans for the Agentic module
8. **Cold Storage** - Archive vendor versions to S3 with on-demand retrieval
## Production Readiness Score: 72/100 (was 60/100 - All recommended improvements implemented 2026-01-21)
This module is well-designed architecturally. P1 critical issues fixed in Wave 1. All recommended improvements now implemented.
## Critical Issues (Must Fix)
- [x] **No database migrations** - FIXED: Created `2026_01_21_100000_create_uptelligence_tables.php` with all 10 tables
- [ ] **No Controllers/Routes** - No way to interact with the system via HTTP. No UI, no API endpoints
- [ ] **No Commands** - No artisan commands to run analyses, check for updates, or generate issues
- [ ] **No Tests** - Zero test coverage. No unit tests, feature tests, or factories
- [ ] **No Seeders** - No way to seed default vendors defined in config
- [x] **Dependency on Agentic module** - FIXED: `UpstreamPlanGeneratorService` now checks `agenticModuleAvailable()` before using Agentic models
- [ ] **API keys required** - AI analysis and GitHub/Gitea integration require API keys but no validation or graceful degradation
- [x] **DiffAnalyzerService shell injection risk** - FIXED: Now uses `Process::run(['diff', '-u', $prevPath, $currPath])` array syntax
- [x] **AssetTrackerService shell injection risk** - FIXED: Now uses array-based Process invocation with package name validation
## Recommended Improvements
- [x] **Add input validation on file paths in `DiffAnalyzerService::generateDiff()`** - FIXED: Path traversal validation added to prevent directory traversal attacks.
- [x] **Add rate limiting for AI API calls in `AIAnalyzerService`** - FIXED: Rate limiting implemented for AI analysis calls.
- [x] **Add retry logic with exponential backoff for external API calls** - FIXED: Retry logic with exponential backoff added for Packagist, NPM, GitHub, Gitea, Anthropic, and OpenAI calls.
- [x] **Add logging for all external API failures** - FIXED: Enhanced logging for API failures beyond just `report($e)`.
- [x] **Add database transactions in `DiffAnalyzerService::cacheDiffs()`** - FIXED: Database transactions added with rollback on failure.
- [x] **Add soft deletes to models for audit trail** - FIXED: Soft deletes added to relevant models.
- [x] **Add index on `diff_cache.version_release_id` and `upstream_todos.vendor_id`** - FIXED: Database performance indexes added.
- [x] **Add validation that vendor `target_repo` format is valid** - FIXED: Validation added before using `explode('/', ...)` in IssueGeneratorService.
- [x] **VendorStorageService uses both Laravel `Storage` facade and direct `file_exists()` calls** - FIXED: Standardised to use Storage facade throughout.
- [x] **Add config validation on boot to warn about missing API keys** - FIXED: Config validation added on boot.
- [ ] AssetTrackerService processes packages sequentially - could benefit from parallel processing for large checks
- [ ] Add webhook support for vendor notifications (currently only outbound notifications to Slack/Discord)
- [ ] Pattern model stores code as text - consider blob storage for large patterns
- [x] **Add timestamps validation for `released_at` in AssetVersion** - FIXED: Proper validation added instead of using fragile `now()->parse()`.
## Missing Features (Future)
- [ ] Livewire/Flux UI for managing vendors, viewing diffs, and tracking todos
- [ ] Scheduled job to auto-check vendors/assets for updates
- [ ] Webhook endpoint for receiving vendor release notifications
- [ ] CLI commands: `upstream:check`, `upstream:analyze`, `upstream:issues`, `upstream:sync-assets`
- [ ] Dashboard with metrics (pending todos, quick wins, security updates)
- [ ] Email digest notifications for new upstream releases
- [ ] Git submodule sync for OSS vendors (referenced in config but not implemented)
- [ ] Diff viewer UI with syntax highlighting
- [ ] Batch AI analysis with cost tracking
- [ ] Export/import of todos for external tracking systems
- [ ] Integration with project management tools (Linear, Jira)
- [ ] Automated PR creation for simple porting tasks
- [ ] Version comparison UI showing what's changed
- [ ] Pattern search and preview UI
## Test Coverage Assessment
**Current Coverage: 0%**
No tests exist. The module needs:
- Unit tests for all Models (scopes, helpers, relationships)
- Unit tests for DiffCache::detectCategory()
- Unit tests for Vendor path matching methods
- Feature tests for DiffAnalyzerService
- Feature tests for AIAnalyzerService (with mocked API responses)
- Feature tests for IssueGeneratorService (with mocked GitHub/Gitea APIs)
- Feature tests for VendorStorageService (local and S3 modes)
- Feature tests for AssetTrackerService
- Integration test for full analysis workflow
- Factories for all models
## Security Concerns
1. **Shell injection in DiffAnalyzerService** - FIXED: Now uses array syntax for Process::run().
2. **No authentication/authorisation** - When routes are added, they need proper guards. This is internal tooling and should be admin-only.
3. **API tokens in config** - GitHub, Gitea, Anthropic, OpenAI tokens are stored in config. Ensure these are properly protected via `.env` and not logged.
4. **S3 bucket access** - Vendor archives in S3 should use private ACL. Code doesn't explicitly set ACL.
5. **Path traversal** - FIXED: Validation added to ensure slug contains no `../` sequences.
6. **Arbitrary code patterns** - Pattern model stores code that could be surfaced via MCP. Ensure patterns are vetted before use.
7. **SQL injection via search** - `Pattern::scopeSearch()` uses LIKE with user input. Currently safe due to Eloquent but worth noting.
## Notes
### Architecture
The module follows good separation of concerns:
- Models are clean with well-defined scopes and helpers
- Services handle specific domains (diff analysis, AI, issues, storage)
- Config is comprehensive and uses env vars appropriately
### Dependencies
- Requires `Mod\Agentic` module for plan generation (soft dependency - now checks availability)
- External: Anthropic API, OpenAI API, GitHub API, Gitea API, Packagist, NPM registry, AWS S3
### Config Observations
The config includes 3 pre-defined vendors (66biolinks, Mixpost Pro, Mixpost Enterprise) but no seeder to create them.
The AI model defaults to `claude-sonnet-4-20250514` which is appropriate.
S3 config supports dual endpoints (Hetzner Object Store pattern) which is good for the infrastructure.
### Code Quality
- Consistent use of `declare(strict_types=1)`
- Good PHPDoc on classes
- Constants defined for all magic strings
- Proper type hints throughout
- UK English spelling in documentation (colour, analyse, etc.) matching brand guidelines
### Missing from Boot.php
- Routes not registered (no routes file)
- No commands registered
- No event listeners
- No scheduled tasks
- DiffAnalyzerService and AssetTrackerService not registered as singletons (only Issue, Plan, and Storage services are)
### Potential Quick Wins
1. Create migrations from model definitions - DONE
2. Add basic artisan commands
3. Register DiffAnalyzerService and AssetTrackerService as singletons
4. Add a simple seeder for default vendors
5. Fix the shell injection in DiffAnalyzerService - DONE