API: It's possible to share a project with a group you cannot see

While debugging https://gitlab.com/gitlab-org/gitlab-ce/issues/21871#note_15242055, I discovered that you can actually do the following things via the API:

  • share a project with a group that doesn't exist: POST /api/v3/projects/9/share?group_id=42&group_access=30 => this ends-up generating errors like the one described in #21871 (closed) and can be solved by actually checking that the group exists, as we do in app/controllers/projects/group_links_controller.rb.
  • share a project with a group you cannot see (i.e. a private group): POST /api/v3/projects/9/share?group_id=<PRIVATE GROUP ID>&group_access=30 => this leaks at least the group's name and owner:

Screen_Shot_2016-10-05_at_16.16.47

Screen_Shot_2016-10-05_at_16.16.59

Screen_Shot_2016-10-05_at_16.18.04

The fix is quite simple, we should do as we do in the controller.

Replace:

link = user_project.project_group_links.new(attrs)

by:

group = Group.find(params[:link_group_id])
return render_404 unless can?(current_user, :read_group, group)

user_project.project_group_links.create(
  group: group,
  group_access: params[:group_access],
  expires_at: params[:expires_at]
)

/cc @stanhu @briann @markglenfletcher