Project

General

Profile

Patch #44259 » 0002-Add-context-menu-tests-guarding-against-data-leaks-t.patch

Jens Krämer, 2026-07-11 15:12

View differences:

test/functional/context_menus/projects_controller_test.rb
46 46

  
47 47
      assert_response :forbidden
48 48
    end
49

  
50
    def test_index_should_not_leak_identifier_to_non_admin
51
      # Project 5 is private; user 4 is not a member, so Project.visible would
52
      # exclude it. Without authorization the action would render and the
53
      # project's identifier ("private-child") would surface in link hrefs.
54
      private_project = Project.find(5)
55
      assert_equal false, private_project.is_public
56
      assert_not User.find(4).member_of?(private_project)
57

  
58
      @request.session[:user_id] = 4
59
      get(:index, :params => {:ids => [5]})
60

  
61
      assert_response :forbidden
62
      assert_not_includes @response.body, private_project.identifier
63
    end
64

  
65
    def test_index_should_not_expose_existence_oracle
66
      # Existing private id and missing id must both return 403 — same
67
      # status, no enumeration oracle.
68
      @request.session[:user_id] = 4
69

  
70
      get(:index, :params => {:ids => [5]})
71
      assert_response :forbidden
72

  
73
      get(:index, :params => {:ids => [999_999]})
74
      assert_response :forbidden
75
    end
76

  
77
    def test_index_should_not_leak_archived_state
78
      # The response must not distinguish active ("Archive" button) from
79
      # archived ("Unarchive" button) projects the user cannot see.
80
      Project.find(5).archive
81

  
82
      @request.session[:user_id] = 4
83
      get(:index, :params => {:ids => [5]})
84

  
85
      assert_response :forbidden
86
      assert_select 'a.icon-unlock', :text => /Unarchive/i, :count => 0
87
      assert_select 'a.icon-lock',   :text => /Archive/i,   :count => 0
88
    end
49 89
  end
50 90
end
test/functional/context_menus/time_entries_controller_test.rb
116 116

  
117 117
      assert_select 'a.disabled', :text => 'Bulk edit'
118 118
    end
119

  
120
    def test_index_should_not_leak_activity_names_from_invisible_project
121
      # time_entry 5 belongs to project 5 (private). User 4 is not a member;
122
      # the menu must not render and no activity names from the private
123
      # project may leak via the response body.
124
      entry = TimeEntry.find(5)
125
      assert_equal 5, entry.project_id
126
      assert_not entry.visible?(User.find(4))
127

  
128
      @request.session[:user_id] = 4
129
      get(:index, :params => {:ids => [5]})
130

  
131
      assert_response :not_found
132

  
133
      Project.find(5).activities.each do |activity|
134
        assert_not_includes @response.body, activity.name
135
      end
136
    end
119 137
  end
120 138
end
test/functional/context_menus/users_controller_test.rb
86 86
      get :index, :params => {:ids => [8]}
87 87
      assert_response :forbidden
88 88
    end
89

  
90
    def test_index_should_not_leak_lock_state_to_non_admin
91
      # User 5 (Dave Lopper2) is locked in fixtures. The rendered menu must
92
      # not show an "Unlock" link to non-admins, revealing lock status.
93
      assert User.find(5).locked?
94

  
95
      @request.session[:user_id] = 4
96
      get :index, :params => {:ids => [5]}
97

  
98
      assert_response :forbidden
99
      assert_select 'a.icon-unlock', :text => /Unlock/i,   :count => 0
100
      assert_select 'a',             :text => /Activate/i, :count => 0
101
    end
102

  
103
    def test_index_should_not_leak_registered_state
104
      # Registered (not-yet-activated) users must not surface an "Activate"
105
      # link, revealing their pending-activation state.
106
      User.find(5).update_columns(:status => User::STATUS_REGISTERED)
107

  
108
      @request.session[:user_id] = 4
109
      get :index, :params => {:ids => [5]}
110

  
111
      assert_response :forbidden
112
      assert_select 'a', :text => /Activate/i, :count => 0
113
    end
114

  
115
    def test_index_should_not_expose_existence_oracle
116
      @request.session[:user_id] = 4
117

  
118
      get :index, :params => {:ids => [8]}
119
      assert_response :forbidden
120

  
121
      get :index, :params => {:ids => [999_999]}
122
      assert_response :forbidden
123
    end
124

  
125
    def test_index_should_not_render_admin_links_for_non_admin
126
      # The menu must not expose /users/:id/edit and DELETE /users/:id for
127
      # any caller, confirming the target id exists.
128
      @request.session[:user_id] = 4
129
      get :index, :params => {:ids => [8]}
130

  
131
      assert_response :forbidden
132
      assert_select 'a.icon-edit', :count => 0
133
      assert_select 'a.icon-del',  :count => 0
134
    end
89 135
  end
90 136
end
(2-2/2)