Bug #18
openFSDKC Platform — Security, Performance & Quality Improvements (BCP-47)
0%
Description
User Story¶
As a platform engineer maintaining the FSDKC connectivity-monitoring platform, I want critical security vulnerabilities closed, real KPI measurements replacing stubs, and code quality improvements applied across the PHP/Laravel backend and React/TypeScript frontend, so that the platform is safe to expose externally, produces trustworthy data, and is maintainable by the team without hidden failure modes.
Background¶
Static analysis of shende-shweta/FSDKC (PHP 8.3/Laravel 12 + React 19/TypeScript + MariaDB 11 + MongoDB 7) uncovered 13 issues from critical security holes to memory leaks and vacuous tests:
-
extract($request->all())inLegacyReportController.php:21lets attackers overwrite any local variable via HTTP params. - All 19 API endpoints have no authentication or authorisation.
- Reachability KPIs are driven by
random_int(1,100) > 20— metrics are statistically random, not real measurements. - Hard-coded credentials committed to
docker-compose.yml. - Wildcard CORS (
*) on both Laravel and the Node.js dev-api.
Parent Jira key: BCP-47 | Labels: ai-created, security, performance, refactor
Phase 1 — Critical Security (5 tasks, no prerequisites)¶
- Remove
extract($request->all())(LegacyReportController.php:21); use$request->validated(). - Remove
extract($context)(LegacyDataMapper.php:22); use named variable assignments. - Restrict CORS to explicit domain list in
config/cors.phpanddev-api/server.js. - Set
APP_DEBUG=falsein.env.example. - Remove hard-coded credentials from
docker-compose.yml; replace with${ENV_VAR}references.
Phase 2 — Authentication + Rate Limiting (7 tasks)¶
- Laravel Sanctum: guard all mutating routes with
auth:sanctum. -
throttle:10,1onrun-checkandstartendpoints. -
express-rate-limiton the dev-api. - Propagate Bearer token from React frontend on all API calls.
-
POST /api/auth/loginendpoint.
Phase 3 — Performance & Correctness (11 tasks)¶
- Add 3 missing DB indexes (new migration).
- Extract
DiscoveryTreeBuilderservice (O(n) single-pass) — removes 3× duplicatedbuildTree(). - Extract
ConnectService::calculateReachability()— removes 3× duplicated formula. - Fix N+1 in
LegacyReportController::carrierSummary(). - Replace blocking
usleep()workers with Redis Queue jobs. - Switch SSE polling to cursor-based fetch (unbounded MongoDB growth fix).
- Implement
DashboardServicewith real KPI aggregation (replaces94.2%/97.8%magic constants). - Pagination on all listing endpoints.
Phase 4 — Input Validation Gaps (7 tasks)¶
- E.164 regex on phone numbers; ISO 3166-1 on
country_code; BCP-47 onlanguages.*. - Enum allow-list on
statusfields; MongoDBmoduleallow-list. - Bulk-import CSV server-side validation; UUID format on
session_id.
Phase 5 — Frontend Quality & Testing (10 tasks)¶
- Fix
LegacyMonitorPollersetIntervalleak (clear inuseEffectcleanup). - Add root + per-route
<ErrorBoundary>. - Cap SSE events array length.
- Create
src/api/endpoints.tsas single source of truth. - Split
ConnectPageandDiscoveryPageinto sub-components. - Vitest + RTL tests for critical paths.
- Replace flaky PHPUnit
random_int()test with deterministic fixture. - Real HTTP integration test for
run-check→ status polling flow.
Key Acceptance Criteria¶
| # | Criterion |
|---|---|
| AC-01 |
extract($request-> removed — grep returns 0 hits |
| AC-02 | Mutating endpoints return 401 without Sanctum token |
| AC-03 | Dashboard KPIs vary with fixture data (not constants) |
| AC-04 | CORS allowed_origins contains no * wildcard |
| AC-05 |
run-check returns 429 after 10 req/min |
| AC-06 |
buildTree() exists in ≤ 1 PHP class |
| AC-07 |
LegacyMonitorPoller interval cleared on unmount (RTL test) |
| AC-08 | Root + per-route <ErrorBoundary> present |
| AC-09 | Invalid phone/country/language payloads return 422
|
| AC-10 | No plaintext credentials in docker-compose.yml
|
| AC-11 | PHPUnit suite passes deterministically (3 consecutive CI runs) |
| AC-12 | SSE MongoDB reads do not grow with event history |
Technical Notes¶
Critical path: Phase 1 → Phase 2 → Phases 3–5 (parallel). Phase 1 must ship before any external exposure.
Security notes: extract() removal must be atomic — update all downstream variable consumers in the same commit. Use HttpOnly cookie for Sanctum tokens. Inject CORS origins via CORS_ALLOWED_ORIGINS env var.
Performance notes: Validate N+1 fix with DB::enableQueryLog() before merge. Redis Queue requires QUEUE_CONNECTION=redis + Supervisor queue:work in Docker Compose.
Testing notes: Vitest with jsdom env; PHPUnit fixtures use RefreshDatabase trait.
Related pipeline artifacts:
-
01-code-analysis.md— full analysis -
analysis_output.json— machine-readable findings -
02-design-document.md— architecture design -
03-task-list.md— 39-task breakdown -
tasks.json— structured task list
Labels: ai-created, security, performance, refactor, backend, frontend, php, react, laravel
Labels: ai-created, security, performance, refactor, backend, frontend, php, react, laravel
No data to display