java-topology/whitepaper/outreach/redmine-0004.md
russell@unturf.com 652608142a feat: close outreach doc gap — 276 docs (batches 11-16)
All projects with patches now have outreach docs. 276 new docs covering
CWE-407, CWE-312, CWE-362 across C, C++, Java, Python, Go, Rust, C#,
PHP, Ruby, JavaScript, Dart, Erlang, R, and more.

Outreach gap: 276 -> 0.
2026-04-15 13:57:42 -04:00

2.1 KiB
Raw Blame History

Redmine — CWE-407 Disclosure Brief (redmine-0004)

2026-04-13 · Patch available — awaiting upstream merge

Finding

O(P²) permission deduplication in Role#add_permission! where permissions.include?(p) scans the permissions array for every permission being added.

The Defect

redmine-0004 (PATCHED — LOW): app/models/role.rb:129

def add_permission!(*perms)
  self.permissions = [] unless permissions.is_a?(Array)
  permissions_will_change!
  perms.each do |p|
    p = p.to_sym
    permissions << p unless permissions.include?(p)  # O(P) scan per perm
  end
  save!
end

permissions.include?(p) performs O(P) linear scan for each of the new permissions being added. With P existing permissions and N new permissions, total cost is O(N×P).

Complexity Proof

At P=100 existing permissions and N=50 new permissions:

  • Defective: 50 × 100 = 5,000 symbol comparisons
  • Fixed: 100 set insertions + 50 set checks = 150 operations
  • ~33× op reduction.

Impact

Redmine manages project permissions through roles. Plugin installation and role configuration trigger add_permission! with many permissions. Large Redmine instances with many plugins (each adding multiple permissions) compound the quadratic overhead during role setup and migration.

The Fix

Convert existing permissions to a Set before the loop:

existing = permissions.to_set
perms.each do |p|
  p = p.to_sym
  permissions << p if existing.add?(p)  # O(1) set check + add
end

Patch

Fix available: defects/redmine-0004/patch/redmine-0004-role-add-permission-set.patch

Single-file patch in role.rb.

What We Ask

A patch is ready for review.

  1. Confirm receipt and assign a tracking reference (Redmine issue tracker).
  2. Assess severity — fires during role configuration and plugin installation.
  3. Coordinate a disclosure date — we target 90 days from first contact.
  4. We will credit the Redmine team in the public disclosure. Preferred acknowledgment format welcome.

Contact: see cover email. This brief is confidential until coordinated disclosure.