Skip to content

v2.3.1 — Security hardening, devel merge & i18n

Choose a tag to compare

@davmont davmont released this 15 Jun 05:42
· 645 commits to master since this release

dotProject v2.3.1 Release Notes

Release date: 2026-06-15

This is a security, performance, and localization patch release. It merges all work
from the devel branch into master and adds hardening found during a cloud security
review.


Security fixes

  • Password hashing migration: MD5 passwords are transparently upgraded to bcrypt on
    first login. New passwords use password_hash() with PASSWORD_DEFAULT.
  • CSRF protection: Central verifyCsrfToken() check on all dosql dispatches;
    non-POST dosql requests are now rejected outright, closing the GET-based CSRF bypass.
  • Session hardening: session_regenerate_id(true) on login; HttpOnly and Secure
    cookie flags; SameSite=Lax; Secure now correctly detected behind reverse proxies
    by reading the configured base_url scheme.
  • XSS fixes: URL parameters wrapped in intval() in HR allocations, view roles,
    timeplanning, inventory utility, and communication addedit.
  • SQL injection fixes: Parameterized or intval()-guarded queries in calendar event
    delete/query, mileage log, CTesting::delete(), timecard date, annotations addedit,
    and user-lookup in sendpass.
  • unserialize() hardened: ['allowed_classes' => false] added to PostNuke
    authenticator.
  • File upload MIME detection: Server-side finfo detection; falls back to
    application/octet-stream instead of the client-supplied Content-Type value when
    finfo is unavailable.
  • Rate limiting: File-based rate limiter on login and password-reset endpoints
    (classes/ratelimiter.class.php).
  • echo db_error() removed: Database error details no longer exposed in HTTP
    responses.
  • New-user email: Plaintext password removed from new-user notification; users are
    directed to the password-reset flow instead.

Bug fixes

  • Gantt chart: Fixed fatal TypeError on count(null) when a project has no tasks.
  • Project form: Fixed null-access warning on $criticalTasks when creating a new
    project; fixed noCompanies error message incorrectly using append=true.
  • Calendar entities: Replaced HTML entity hack with a proper decoding utility.
  • jscalendar: Implemented missing strftime format specifiers (%T, %R, %X,
    %r, %E, %F, %G, %g, %h).
  • Old password check: !empty() guard added before comparing passwords in user edit
    and change-password flows; fetchRow() used in chpwd.php for cleaner null handling.

Performance

  • N+1 query loops eliminated with bulk inserts / ADOdb transactions across: Tasks,
    Task Assigned Users deletion, Resource Manager projects loop, ATA controller, Calendar
    event assignment, Minute Members insertion, Project Contacts/Departments bulk insert,
    Contact↔Company upgrade, Project deletion, Task budget & child-count loading.
  • Contacts search filter string concatenation optimised.
  • Task dependency updates batched with REPLACE INTO.

PMBOK 8th Edition

  • New task-level Status field (table column task_status) for PMBOK-aligned
    project tracking.

Localization

  • 76 missing translation keys added across all 25 supported locales.
  • 8 modules that previously had no locale files now have them:
    communication, messages, mileagelog, tasks_template, unitcost,
    timesheet, finances, closure.
  • Cross-cutting keys (Assign, Unassign, Loading, Send, Dependency,
    Parent task, weeks ago, etc.) added to common.inc for every locale.
  • Spanish (es): Full translations for all new keys; iGantt locale fully
    translated (previously used English fallbacks for 40+ strings).

Code health

  • Deprecated checkFlag() removed from includes/permissions.php.
  • Commented-out dead code purged from bugspray, gantt PDF, cronograma, projects tab,
    and monitoring & control modules.
  • CDpObject::bind() test coverage improved.
  • DBQuery::setLimit(), addLimit(), sanitise(), addTable() test coverage added.
  • GACL self-repair on upgrade: auto-restores missing gacl_acl_sections table.

Database upgrade

The installer's upgrade_latest.php will automatically apply:

Date Change
20260531 users.user_password widened to VARCHAR(255) for bcrypt hashes
20260615 gacl_acl_sections table created (CREATE TABLE IF NOT EXISTS)

Upgrade path

Update versions.inc.php now includes 2.3.0 → 2.3.1. Run the installer upgrade
wizard or apply db/upgrade_latest.php manually.


Known outstanding issues

See README.md for the full module status list. Several legacy modules
(Helpdesk, Ticketing, Finances, third-party integrations) have not been fully tested
against PHP 8.x and the Material theme.