diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-03-28 09:08:30 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-03-28 09:08:30 +0000 |
commit | 132dd28342c2bcbd42475f9dffc60dff12ffb8a6 (patch) | |
tree | 4c60a8801a24b49921eb7480a61674e422231d1f | |
parent | dcc65c870d1f8c8fb697a46c2d61f1cef7b9fd3a (diff) | |
download | gitlab-ce-132dd28342c2bcbd42475f9dffc60dff12ffb8a6.tar.gz |
Add latest changes from gitlab-org/gitlab@master
-rw-r--r-- | app/views/projects/graphs/charts.html.haml | 2 | ||||
-rw-r--r-- | changelogs/unreleased/andr3-rails-session-samesite-strict.yml | 5 | ||||
-rw-r--r-- | changelogs/unreleased/djensen-update-repository-analytics-title.yml | 5 | ||||
-rw-r--r-- | config/application.rb | 3 | ||||
-rw-r--r-- | lib/gitlab/middleware/same_site_cookies.rb | 63 | ||||
-rw-r--r-- | locale/gitlab.pot | 6 | ||||
-rw-r--r-- | spec/lib/gitlab/middleware/same_site_cookies_spec.rb | 107 |
7 files changed, 187 insertions, 4 deletions
diff --git a/app/views/projects/graphs/charts.html.haml b/app/views/projects/graphs/charts.html.haml index cb76e89f736..19fe7ba4360 100644 --- a/app/views/projects/graphs/charts.html.haml +++ b/app/views/projects/graphs/charts.html.haml @@ -1,4 +1,4 @@ -- page_title _("Contribution Charts") +- page_title _("Repository Analytics") .repo-charts %h4.sub-header diff --git a/changelogs/unreleased/andr3-rails-session-samesite-strict.yml b/changelogs/unreleased/andr3-rails-session-samesite-strict.yml new file mode 100644 index 00000000000..8a8f7c58777 --- /dev/null +++ b/changelogs/unreleased/andr3-rails-session-samesite-strict.yml @@ -0,0 +1,5 @@ +--- +title: Make all HTTPS cookies set SameSite to none +merge_request: 28205 +author: +type: fixed diff --git a/changelogs/unreleased/djensen-update-repository-analytics-title.yml b/changelogs/unreleased/djensen-update-repository-analytics-title.yml new file mode 100644 index 00000000000..612e35a680d --- /dev/null +++ b/changelogs/unreleased/djensen-update-repository-analytics-title.yml @@ -0,0 +1,5 @@ +--- +title: Renamed Contribution Charts as Repository Analytics +merge_request: 28162 +author: +type: changed diff --git a/config/application.rb b/config/application.rb index 5c4eb8f5dff..a135bef342a 100644 --- a/config/application.rb +++ b/config/application.rb @@ -24,6 +24,7 @@ module Gitlab require_dependency Rails.root.join('lib/gitlab/current_settings') require_dependency Rails.root.join('lib/gitlab/middleware/read_only') require_dependency Rails.root.join('lib/gitlab/middleware/basic_health_check') + require_dependency Rails.root.join('lib/gitlab/middleware/same_site_cookies') require_dependency Rails.root.join('lib/gitlab/runtime') # Settings in config/environments/* take precedence over those specified here. @@ -231,6 +232,8 @@ module Gitlab config.middleware.insert_after Warden::Manager, Rack::Attack + config.middleware.insert_before ActionDispatch::Cookies, ::Gitlab::Middleware::SameSiteCookies + # Allow access to GitLab API from other domains config.middleware.insert_before Warden::Manager, Rack::Cors do headers_to_expose = %w[Link X-Total X-Total-Pages X-Per-Page X-Page X-Next-Page X-Prev-Page X-Gitlab-Blob-Id X-Gitlab-Commit-Id X-Gitlab-Content-Sha256 X-Gitlab-Encoding X-Gitlab-File-Name X-Gitlab-File-Path X-Gitlab-Last-Commit-Id X-Gitlab-Ref X-Gitlab-Size] diff --git a/lib/gitlab/middleware/same_site_cookies.rb b/lib/gitlab/middleware/same_site_cookies.rb new file mode 100644 index 00000000000..45968035e79 --- /dev/null +++ b/lib/gitlab/middleware/same_site_cookies.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +# This middleware sets the SameSite directive to None on all cookies. +# It also adds the Secure directive if HTTPS is enabled. +# +# Chrome v80, rolled out in March 2020, treats any cookies without the +# SameSite directive set as though they are SameSite=Lax +# (https://www.chromestatus.com/feature/5088147346030592). This is a +# breaking change from the previous default behavior, which was to treat +# those cookies as SameSite=None. +# +# This middleware is needed until we upgrade to Rack v2.1.0+ +# (https://github.com/rack/rack/commit/c859bbf7b53cb59df1837612a8c330dfb4147392) +# and a version of Rails that has native support +# (https://github.com/rails/rails/commit/7ccaa125ba396d418aad1b217b63653d06044680). +# +module Gitlab + module Middleware + class SameSiteCookies + COOKIE_SEPARATOR = "\n".freeze + + def initialize(app) + @app = app + end + + def call(env) + status, headers, body = @app.call(env) + result = [status, headers, body] + + set_cookie = headers['Set-Cookie']&.strip + + return result if set_cookie.blank? || !ssl? + + cookies = set_cookie.split(COOKIE_SEPARATOR) + + cookies.each do |cookie| + next if cookie.blank? + + # Chrome will drop SameSite=None cookies without the Secure + # flag. If we remove this middleware, we may need to ensure + # that all cookies set this flag. + if ssl? && !(cookie =~ /;\s*secure/i) + cookie << '; Secure' + end + + unless cookie =~ /;\s*samesite=/i + cookie << '; SameSite=None' + end + end + + headers['Set-Cookie'] = cookies.join(COOKIE_SEPARATOR) + + result + end + + private + + def ssl? + Gitlab.config.gitlab.https + end + end + end +end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index d1fd25c6a86..90c28cf21ea 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -5503,9 +5503,6 @@ msgstr "" msgid "Contribution Analytics" msgstr "" -msgid "Contribution Charts" -msgstr "" - msgid "ContributionAnalytics|<strong>%{created_count}</strong> created, <strong>%{accepted_count}</strong> accepted." msgstr "" @@ -16828,6 +16825,9 @@ msgstr "" msgid "Repository" msgstr "" +msgid "Repository Analytics" +msgstr "" + msgid "Repository Graph" msgstr "" diff --git a/spec/lib/gitlab/middleware/same_site_cookies_spec.rb b/spec/lib/gitlab/middleware/same_site_cookies_spec.rb new file mode 100644 index 00000000000..0cf1028a930 --- /dev/null +++ b/spec/lib/gitlab/middleware/same_site_cookies_spec.rb @@ -0,0 +1,107 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Middleware::SameSiteCookies do + include Rack::Test::Methods + + let(:mock_app) do + Class.new do + attr_reader :cookies + + def initialize(cookies) + @cookies = cookies + end + + def call(env) + [200, { 'Set-Cookie' => cookies }, ['OK']] + end + end + end + + let(:app) { mock_app.new(cookies) } + + subject do + described_class.new(app) + end + + describe '#call' do + let(:request) { Rack::MockRequest.new(subject) } + + def do_request + request.post('/some/path') + end + + context 'without SSL enabled' do + before do + allow(Gitlab.config.gitlab).to receive(:https).and_return(false) + end + + context 'with cookie' do + let(:cookies) { "thiscookie=12345" } + + it 'does not add headers to cookies' do + response = do_request + + expect(response['Set-Cookie']).to eq(cookies) + end + end + end + + context 'with SSL enabled' do + before do + allow(Gitlab.config.gitlab).to receive(:https).and_return(true) + end + + context 'with no cookies' do + let(:cookies) { nil } + + it 'does not add headers' do + response = do_request + + expect(response['Set-Cookie']).to be_nil + end + end + + context 'with single cookie' do + let(:cookies) { "thiscookie=12345" } + + it 'adds required headers' do + response = do_request + + expect(response['Set-Cookie']).to eq("#{cookies}; Secure; SameSite=None") + end + end + + context 'multiple cookies' do + let(:cookies) { "thiscookie=12345\nanother_cookie=56789" } + + it 'adds required headers' do + response = do_request + + expect(response['Set-Cookie']).to eq("thiscookie=12345; Secure; SameSite=None\nanother_cookie=56789; Secure; SameSite=None") + end + end + + context 'multiple cookies with some missing headers' do + let(:cookies) { "thiscookie=12345; SameSite=None\nanother_cookie=56789; Secure" } + + it 'adds missing headers' do + response = do_request + + expect(response['Set-Cookie']).to eq("thiscookie=12345; SameSite=None; Secure\nanother_cookie=56789; Secure; SameSite=None") + end + end + + context 'multiple cookies with all headers present' do + let(:cookies) { "thiscookie=12345; Secure; SameSite=None\nanother_cookie=56789; Secure; SameSite=None" } + + it 'does not add new headers' do + response = do_request + + expect(response['Set-Cookie']).to eq(cookies) + end + end + end + end +end |