diff --git a/app/controllers/dashboard/projects_controller.rb b/app/controllers/dashboard/projects_controller.rb
index 71acc244a9170b488423318b2dd091c4cce98295..c08eb8115322e8be3b987ba7325a0beac3b71f33 100644
--- a/app/controllers/dashboard/projects_controller.rb
+++ b/app/controllers/dashboard/projects_controller.rb
@@ -28,7 +28,7 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController
   end
 
   def starred
-    @projects = current_user.starred_projects.sorted_by_activity
+    @projects = current_user.viewable_starred_projects.sorted_by_activity
     @projects = filter_projects(@projects)
     @projects = @projects.includes(:namespace, :forked_from_project, :tags)
     @projects = @projects.sort(@sort = params[:sort])
diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb
index 1dce4a21729f88fea4b5d2cee06c933c63fc5e8a..4dda4e51f6a5a2440e48a6e779d50e9817906cd3 100644
--- a/app/controllers/dashboard_controller.rb
+++ b/app/controllers/dashboard_controller.rb
@@ -25,7 +25,7 @@ class DashboardController < Dashboard::ApplicationController
   def load_events
     projects =
       if params[:filter] == "starred"
-        current_user.starred_projects
+        current_user.viewable_starred_projects
       else
         current_user.authorized_projects
       end
diff --git a/app/models/user.rb b/app/models/user.rb
index 1e4814641d1b02e4e02ac5a96902a3f76e8896f1..a0115957f00ac485dab7e546a6d45254ea9cf62b 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -381,6 +381,11 @@ class User < ActiveRecord::Base
     Project.where("projects.id IN (#{projects_union.to_sql})")
   end
 
+  def viewable_starred_projects
+    starred_projects.where("projects.visibility_level IN (?) OR projects.id IN (#{projects_union.to_sql})",
+                           [Gitlab::VisibilityLevel::PUBLIC, Gitlab::VisibilityLevel::INTERNAL])
+  end
+
   def owned_projects
     @owned_projects ||=
       Project.where('namespace_id IN (?) OR namespace_id = ?',
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index cc2c7a0c5032ece375a194ff363b73e8438bc6ef..9b59577267575b564277300cd64208f7690ef2af 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -44,7 +44,7 @@ module API
       # Example Request:
       #   GET /projects/starred
       get '/starred' do
-        @projects = current_user.starred_projects
+        @projects = current_user.viewable_starred_projects
         @projects = filter_projects(@projects)
         @projects = paginate @projects
         present @projects, with: Entities::Project
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 26d4e139396b177d9892b19cc356a3d8af565b87..06d1ca3b7dadafac6420c32cda5d081c44a490cb 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -233,6 +233,8 @@ describe User, models: true do
       @project = create :project, namespace: @user.namespace
       @project_2 = create :project, group: create(:group) # Grant MASTER access to the user
       @project_3 = create :project, group: create(:group) # Grant DEVELOPER access to the user
+      @project_4 = create :project, group: create(:group)
+      @project_5 = create :project, group: create(:group)
 
       @project_2.team << [@user, :master]
       @project_3.team << [@user, :developer]
@@ -782,4 +784,26 @@ describe User, models: true do
 
     it { is_expected.to eq([private_project]) }
   end
+
+  describe '#viewable_starred_projects' do
+    let(:user) { create(:user) }
+    let(:public_project) { create(:project, :public) }
+    let(:private_project) { create(:project, :private) }
+    let(:private_viewable_project) { create(:project, :private) }
+    let(:viewable?) { -> (project) { user.can?(:read_project, project) } }
+    let(:projects) { [public_project, private_project, private_viewable_project] }
+
+    before do
+      private_viewable_project.team << [user, Gitlab::Access::MASTER]
+      projects.each { |project| user.toggle_star(project) }
+    end
+
+    it 'returns only starred projects the user can view' do
+      expect(user.viewable_starred_projects).to all(satisfy(&viewable?))
+    end
+
+    it 'rejects only starred projects the user can not view' do
+      expect(projects - user.viewable_starred_projects).not_to include(satisfy(&viewable?))
+    end
+  end
 end
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 66193eac051e1592ec0e00d689688cecccbbbdfb..f167813e07dcfae10063fa51d8cfeba8945c3866 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -10,20 +10,20 @@ describe API::API, api: true  do
   let(:admin) { create(:admin) }
   let(:project) { create(:project, creator_id: user.id, namespace: user.namespace) }
   let(:project2) { create(:project, path: 'project2', creator_id: user.id, namespace: user.namespace) }
-  let(:project3) { create(:project, path: 'project3', creator_id: user.id, namespace: user.namespace) }
   let(:snippet) { create(:project_snippet, :public, author: user, project: project, title: 'example') }
   let(:project_member) { create(:project_member, :master, user: user, project: project) }
   let(:project_member2) { create(:project_member, :developer, user: user3, project: project) }
   let(:user4) { create(:user) }
   let(:project3) do
     create(:project,
+    :private,
     name: 'second_project',
     path: 'second_project',
     creator_id: user.id,
     namespace: user.namespace,
     merge_requests_enabled: false,
     issues_enabled: false, wiki_enabled: false,
-    snippets_enabled: false, visibility_level: 0)
+    snippets_enabled: false)
   end
   let(:project_member3) do
     create(:project_member,
@@ -164,21 +164,18 @@ describe API::API, api: true  do
   end
 
   describe 'GET /projects/starred' do
+    let(:public_project) { create(:project, :public) }
+
     before do
-      admin.starred_projects << project
-      admin.save!
+      project_member2
+      user3.update_attributes(starred_projects: [project, project2, project3, public_project])
     end
 
-    it 'should return the starred projects' do
-      get api('/projects/all', admin)
+    it 'should return the starred projects viewable by the user' do
+      get api('/projects/starred', user3)
       expect(response.status).to eq(200)
       expect(json_response).to be_an Array
-
-      expect(json_response).to satisfy do |response|
-        response.one? do |entry|
-          entry['name'] == project.name
-        end
-      end
+      expect(json_response.map { |project| project['id'] }).to contain_exactly(project.id, public_project.id)
     end
   end