Files
cmsPRO/.paul/codebase/concerns.md
Jacek Pyziak bf4b7c6429 docs(codebase): mapa kodu wygenerowana przez /paul:map-codebase
7 dokumentów w .paul/codebase/ — overview, stack, architecture,
conventions, testing, integrations, concerns (CRITICAL→LOW).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 00:46:01 +02:00

6.7 KiB

Technical Debt & Concerns

Generated: 2026-04-26 | Prioritized by severity

CRITICAL

C1 — Unserialize on User-Controlled Cookies

File: admin/ajax/pages.php lines 36, 49
Code: $array = unserialize($_COOKIE['cookie_menus']);
Risk: Object injection / RCE — classic PHP vulnerability.
Fix: Replace with json_decode($_COOKIE['cookie_menus'] ?? '{}', true).

C2 — Path Traversal in Update File Deletion

File: autoload/admin/factory/class.Update.php lines 76-80, 119-128
Code: unlink('../' . $filePath)$filePath from JSON manifest, not validated.
Risk: Attacker-controlled manifest could delete arbitrary files.
Fix:

$full = realpath('../' . $filePath);
$base = realpath('../');
if (strpos($full, $base) !== 0) throw new \Exception('Path traversal');
unlink($full);

C3 — God Class: Helpers.php (1220 lines, 75+ static methods)

File: autoload/Shared/Helpers/Helpers.php
Risk: Unmaintainable, untestable, global state dependency (global $mdb, $settings, $lang).
Domains mixed: image processing, HTML DOM, caching, SEO, authentication, dates, session.
Fix: Extract into focused service classes (ImageService, SeoHelper, DateHelper, etc.).


HIGH

H1 — Direct Superglobal Access Without Validation

File: autoload/Shared/Helpers/Helpers.php lines 25-26
Code: $crop_w = $_GET['c_w']; — no isset, no type check.
Also: admin/ajax/pages.php lines 36, 49 — \S::get() passed directly to queries.
Fix: Centralized request wrapper with typed getters.

H2 — SQL String Concatenation (String Values)

File: autoload/Domain/Articles/ArticlesRepository.php lines 53, 68, 87 and others.
Code: "... WHERE article_id = " . (int)$id — integer cast OK, but pattern is dangerous for string params.
Fix: Use Medoo parameterized methods exclusively. Audit and replace all raw query() calls.

H3 — No Input Validation / Sanitization Layer

All entry points — no Validator or Sanitizer class. Values flow from $_GET/$_POST → repository without validation.
Fix: Add validation at control layer before delegation to factory/repository.

File: admin/index.php lines 59-61
Code: $obj = json_decode($_COOKIE[$cookie_name]); $password = $obj->{'hash'};
Risk: Cookie exposure leaks credential hash, no HMAC signing.
Fix: Use signed JWT or HMAC-signed remember-me token, never store hashes in cookies.

H5 — Update Download Without Signature Verification

File: autoload/admin/factory/class.Update.php lines 12, 25, 28
Code: file_get_contents('https://www.cmspro.project-dc.pl/updates/...')
Risk: MITM, supply chain — ZIP extracted without verifying integrity beyond SHA256 (if present).
Fix: Verify SHA256 checksum server-side before extraction; use curl with CURLOPT_SSL_VERIFYPEER.

H6 — Deprecated mime_content_type() Removed in PHP 8.1

File: autoload/Shared/Helpers/Helpers.php line 39
Fix:

$finfo = finfo_open(FILEINFO_MIME_TYPE);
$type = finfo_file($finfo, $file);
finfo_close($finfo);

MEDIUM

M1 — Global Variables as Dependency Injection

Files: Factory classes (global $mdb, global $user), Helpers (global $settings, $lang).
Risk: Untestable, tightly coupled, order-dependent initialization.
Fix: Pass $mdb to factories/repositories directly; remove global from repository code.

M2 — Repository Classes Contain Business Logic and Side Effects

File: autoload/Domain/Articles/ArticlesRepository.php line 45, 59
Code: \S::delete_cache() and \S::seo() called inside repository methods.
Fix: Repositories should only do DB operations; call side effects in factories/services.

M3 — Mixed Procedural + OOP AJAX Handlers

Files: admin/ajax/pages.php, admin/ajax/articles.php, admin/ajax/users.php
Pattern: 50-90 line if ($a == '...') chains, no routing abstraction.
Fix: Create AjaxRouter + controller base class.

M4 — No Request/Response Abstraction

All entry points$_GET/$_POST accessed directly everywhere.
Fix: Request class (typed getters) + JsonResponse class.

M5 — Error Suppression with @ Operator

Files: admin/index.php lines 2, 14; Helpers.php lines 40, 98, 111, 1188-1200
Code: @file_get_contents(...), @unlink(...).
Fix: Use if (file_exists()) guards and proper try/catch.

M6 — Uninitialized Variables

File: autoload/Domain/Articles/ArticlesRepository.php line 72
Code: if ($out == '')$out never declared.
Fix: $out = ''; before the loop.

M7 — No Interface Contracts for Repositories

All 10 repositories share identical method signatures but no shared interface.
Fix: Define RepositoryInterface with find(), all(), save(), delete().

M8 — Hardcoded Values

  • Update base URL: 'https://www.cmspro.project-dc.pl/updates/' in 3 files
  • File permissions: chmod(..., 0755) in 25 places
  • Cookie expiry: time() + 3600 * 24 * 365 as magic number Fix: Extract to constants in a config class.

LOW

L1 — Backup Files in Repository

libraries/medoo/medoo.bck.php (973 lines), libraries/grid/gdb.min.bck.php (957 lines).
Fix: Delete; use Git for history.

L2 — test.php in Project Root (700 lines)

Production benchmark/test script accessible via HTTP. Contains DB credentials in lines 15-17.
Fix: Remove or move to tests/ with .htaccess protection.

L3 — Legacy class.S.php Wrapper

200+ calls to \S::* throughout codebase — double indirection through __callStatic.
Fix: Gradual rename campaign to \Shared\Helpers\Helpers::*.

L4 — Legacy SQL Update Fallback Format

class.Update.php lines 97-132 — parses old _sql.txt format alongside new JSON manifest.
Fix: Deprecate and remove once all deployments are on manifest format.

L5 — Update Process Without Rollback

SQL runs before file extraction. If extraction fails, DB is inconsistent. No transaction wrapping.
Fix: Wrap SQL in transaction; extract files first, then run SQL; add rollback on failure.


Files Needing Immediate Attention

File Lines Issue
autoload/Shared/Helpers/Helpers.php 1220 God class (C3)
autoload/admin/factory/class.Update.php 157 Path traversal (C2), supply chain (H5)
admin/ajax/pages.php ~90 Unserialize (C1), missing validation (H1)
admin/index.php Password hash in cookie (H4)
autoload/Domain/Articles/ArticlesRepository.php 648 Side effects in repo (M2), raw SQL (H2)
test.php 700 Remove from root (L2)