Project

General

Profile

Actions

Bug #17

open

PingCRM — IVR Legacy Security Hardening, Consolidation & Modernization (27 tasks, 5 phases)

Added by Redmine Admin about 1 month ago.

Status:
New
Priority:
Normal
Assignee:
-
Start date:
09/03/2026
Due date:
% Done:

0%

Estimated time:

Description

PingCRM — IVR Legacy Security Hardening, Consolidation & Modernization

Labels: ai-created, security, modernization, php, laravel, react, owasp


User Story

As a PingCRM platform owner,
I want the IVR legacy layer secured against OWASP critical vulnerabilities, consolidated to eliminate 660 duplicated method bodies, and migrated to database-portable SQL with an upgraded Inertia.js bridge,
so that the application is safe to operate in a multi-tenant production environment, maintainable by the engineering team, and portable to MySQL/PostgreSQL without further rework.


Background

Static analysis of shende-shweta/pingcrm identified 6 critical security defects confined to the IVR legacy layer, along with extreme structural duplication (12 GodService classes × 55 methods = 660 identical bodies; 84 generated controllers × 55 endpoints = 4,620 endpoints), and several portability and quality issues.

The IVR legacy layer was code-generated and never hardened for production:

  • 90+ CRUD routes are publicly accessible with no authentication middleware
  • Raw user input is concatenated directly into SQL strings
  • A hard-coded API key (LEGACY_IVR_KEY_2042) appears in 12 source files
  • PHP extract() is called on raw request payloads in 660 methods
  • Mass assignment inserts (array) $payload directly into the database
  • sleep(1) in every GodService method blocks PHP-FPM workers under any load
  • Hard-coded $tenantId = 1 breaks multi-tenant isolation across all 84 controllers

Scope

Phase 1 — Critical Security Hardening (T-01 → T-07)

Fix all 6 OWASP critical defects and restore tenant isolation. All changes are reversible and require no schema migration.

Task Fix
T-01 Add ->middleware(['web', 'auth']) to ivr-legacy route group — closes unauthenticated exposure of 90+ endpoints
T-02 Change Route::match(['get','post']) → Route::post() for destructive routes — closes CSRF bypass
T-03 Parameterize raw SQL in 24 vulnerable Index/Store controllers — closes SQL injection
T-04 Move LEGACY_IVR_KEY_2042 to config/ivr.php + .env — closes hard-coded secret
T-05 Replace extract($payload) with Arr::only() field allowlists — closes variable injection
T-06 Replace insertGetId((array) $payload) with explicit field allowlists — closes mass assignment
T-07 Replace hard-coded $tenantId = 1 with Auth::user()->account_id in all 84 controllers

Phase 2 — Consolidation & Performance (T-08 → T-13)

Eliminate 660 identical GodService method bodies and 4,620 controller endpoint duplicates. Remove sleep(1) from the request thread.

  • AbstractGodService base class: 12 GodService classes extend one configurable implementation
  • BaseLegacyController: 84 generated controllers replaced by a single parametric controller
  • IvrSyncJob (Laravel Queue): removes sleep(1) from PHP-FPM worker threads
  • Remove static $sharedRuntimeCache — eliminates cross-request data leakage
  • Structured Log::error() in all catch blocks

Phase 3 — Quality & Portability (T-14 → T-18)

  • DB-portable hourExpression() helper replaces SQLite-specific strftime() — enables MySQL/PostgreSQL migration
  • Inertia.js server upgraded to ^2.0 (resolves server v1 / client v2 mismatch)
  • moduleSlug allowlist validation in LoadsIvrModuleData
  • Dual tenant_id/account_id column alignment to prevent cross-tenant data leakage

Phase 4 — CRM Validation Gaps (T-19 → T-21)

  • Scoped email uniqueness (per-account, not global)
  • password min:8 enforcement
  • ISO 3166 country enum validation

Phase 5 — Testing & Quality Gate (T-22 → T-27)

  • PHPUnit unit tests for all security fixes (T-22–T-23)
  • PHPUnit feature/integration tests (T-24–T-25)
  • Security regression suite (T-26)
  • Final gate: PHPStan / Vitest / php artisan route:list verification (T-27)

Acceptance Criteria

  1. All 90+ IVR legacy routes require authentication — unauthenticated requests return HTTP 401/403
  2. Zero raw SQL string concatenation remains in IVR controllers — all queries use parameterized bindings
  3. LEGACY_IVR_KEY_2042 does not appear in any committed source file
  4. extract() is not called on any user-controlled input in GodService classes
  5. No insertGetId((array) $payload) calls remain — all DB inserts use explicit allowlists
  6. All 84 legacy controllers derive tenant scope from Auth::user()->account_id
  7. sleep(1) removed from GodService methods; async work dispatched via IvrSyncJob
  8. AbstractGodService replaces 12 GodService classes; BaseLegacyController replaces 84 controllers
  9. All SQL uses hourExpression() helper — no SQLite-specific strftime() calls remain
  10. Inertia.js server version is ^2.0; server/client version mismatch resolved
  11. All PHPUnit and Vitest test suites pass; PHPStan reports zero critical issues

Technical Notes

Stack: PHP 8.2 + Laravel 11 · React 19 + TypeScript 5.6 · Inertia.js SPA bridge · SQLite (implicit) · PHPUnit 11 + Vitest 4

Key risk: Determine what sleep(1) was actually synchronizing before removing it — if it was a polling delay for an external IVR API, the IvrSyncJob must replicate that behavior asynchronously.

Dependency chain: T-02 (auth middleware) must ship before T-07 (replace tenantId=1). T-08 (AbstractGodService) must complete before T-09–T-13. All test tasks follow their respective code tasks. T-27 (build verification) is the final gate.

Open question: Does routes/generated/ivr_legacy_api.php have an upstream generator that must also be patched to prevent security issues from being regenerated?


Dependencies

  • PHP 8.2 / Laravel 11 environment
  • Laravel Queue worker configured for IvrSyncJob
  • .env updated with LEGACY_IVR_KEY before deploying T-04
  • Inertia.js ^2.0 client already on v2 — only server package needs upgrading

Generated by AI pipeline — agent: redmine-ticket-publisher-agent | run: 20260903T113839_5f0bw1

Labels: ai-created, security, modernization, php, laravel, react, owasp

No data to display

Actions

Also available in: Atom PDF