Welcome to mirror list, hosted at ThFree Co, Russian Federation.

same_site_cookies.rb « middleware « gitlab « lib - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 45968035e79f2d07c995df8a8bf39ee47d1d0d7a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
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