models/TicketModel.php has two different code paths for group-based internal-ticket visibility that don't agree:
getVisibilityFilter() (~line 728, used for dashboard list/stats queries) matches via FIND_IN_SET(?, REPLACE(t.visibility_groups, ' ', '')) — strips spaces from the column but not from the bound $group parameter.
canUserAccessTicket() (~lines 678-685, used for single-ticket access checks) does plain explode(',', ...) + trim() per element, with no space-stripping at all.
Impact: For a group name containing a space (e.g. an LLDAP group named "IT Support"), a member of that group can open an internal ticket directly by ID/URL (canUserAccessTicket → true) but the same ticket never appears in their dashboard list or stats counts (getVisibilityFilter → false, since "IT Support" never matches the space-stripped column value). Data is invisible-to-browse but directly reachable — a visibility/access-control inconsistency.
Fix: Make both paths use the same normalization (either strip spaces from both sides consistently, or don't strip at all and require exact group-name matches).
**Severity:** High
`models/TicketModel.php` has two different code paths for group-based internal-ticket visibility that don't agree:
- `getVisibilityFilter()` (~line 728, used for dashboard list/stats queries) matches via `FIND_IN_SET(?, REPLACE(t.visibility_groups, ' ', ''))` — strips spaces from the **column** but not from the bound `$group` parameter.
- `canUserAccessTicket()` (~lines 678-685, used for single-ticket access checks) does plain `explode(',', ...)` + `trim()` per element, with no space-stripping at all.
**Impact:** For a group name containing a space (e.g. an LLDAP group named `"IT Support"`), a member of that group can open an internal ticket directly by ID/URL (`canUserAccessTicket` → true) but the same ticket never appears in their dashboard list or stats counts (`getVisibilityFilter` → false, since `"IT Support"` never matches the space-stripped column value). Data is invisible-to-browse but directly reachable — a visibility/access-control inconsistency.
**Fix:** Make both paths use the same normalization (either strip spaces from both sides consistently, or don't strip at all and require exact group-name matches).
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Severity: High
models/TicketModel.phphas two different code paths for group-based internal-ticket visibility that don't agree:getVisibilityFilter()(~line 728, used for dashboard list/stats queries) matches viaFIND_IN_SET(?, REPLACE(t.visibility_groups, ' ', ''))— strips spaces from the column but not from the bound$groupparameter.canUserAccessTicket()(~lines 678-685, used for single-ticket access checks) does plainexplode(',', ...)+trim()per element, with no space-stripping at all.Impact: For a group name containing a space (e.g. an LLDAP group named
"IT Support"), a member of that group can open an internal ticket directly by ID/URL (canUserAccessTicket→ true) but the same ticket never appears in their dashboard list or stats counts (getVisibilityFilter→ false, since"IT Support"never matches the space-stripped column value). Data is invisible-to-browse but directly reachable — a visibility/access-control inconsistency.Fix: Make both paths use the same normalization (either strip spaces from both sides consistently, or don't strip at all and require exact group-name matches).
Fixed and verified against real MariaDB (schema/migration/access-control cases). Merged to main in commit
3664719.