diff --git a/app/models/active_session.rb b/app/models/active_session.rb
index 2eb9c9bca7f24730c3de04caf629006261b51368..4ee04a3d62d2dc571332f14fd9e7963de3245e61 100644
--- a/app/models/active_session.rb
+++ b/app/models/active_session.rb
@@ -25,11 +25,17 @@ class ActiveSession
   SESSION_BATCH_SIZE = 200
   ALLOWED_NUMBER_OF_ACTIVE_SESSIONS = 100
 
-  attr_accessor :ip_address, :browser, :os,
+  ATTR_ACCESSOR_LIST = [
+    :ip_address, :browser, :os,
     :device_name, :device_type,
     :is_impersonated, :session_id, :session_private_id
+  ].freeze
+  ATTR_READER_LIST = [
+    :created_at, :updated_at
+  ].freeze
 
-  attr_reader :created_at, :updated_at
+  attr_accessor(*ATTR_ACCESSOR_LIST)
+  attr_reader(*ATTR_READER_LIST)
 
   def created_at=(time)
     @created_at = time.is_a?(String) ? Time.zone.parse(time) : time
@@ -240,6 +246,8 @@ def dump
 
     if raw_session.start_with?('v2:')
       session_data = Gitlab::Json.parse(raw_session[3..]).symbolize_keys
+      # load only known attributes
+      session_data.slice!(*ATTR_ACCESSOR_LIST.union(ATTR_READER_LIST))
       new(**session_data)
     else
       # Deprecated legacy format. To be removed in 15.0
diff --git a/lib/gitlab/auth/current_user_mode.rb b/lib/gitlab/auth/current_user_mode.rb
index 9bd4711c4bbf16bf3c5993d76e90d07160b01c42..4dd808182ec7ed77b2d35dd0b99980f257cc5754 100644
--- a/lib/gitlab/auth/current_user_mode.rb
+++ b/lib/gitlab/auth/current_user_mode.rb
@@ -8,6 +8,7 @@ module Auth
     # an administrator must have explicitly enabled admin-mode
     # e.g. on web access require re-authentication
     class CurrentUserMode
+      include Gitlab::Utils::StrongMemoize
       NotRequestedError = Class.new(StandardError)
 
       # RequestStore entries
@@ -85,8 +86,9 @@ def current_admin
         end
       end
 
-      def initialize(user)
+      def initialize(user, session = Gitlab::Session.current)
         @user = user
+        @session = session
       end
 
       def admin_mode?
@@ -138,6 +140,11 @@ def request_admin_mode!
         current_session_data[ADMIN_MODE_REQUESTED_TIME_KEY] = Time.now
       end
 
+      def current_session_data
+        Gitlab::NamespacedSessionStore.new(SESSION_STORE_KEY, @session)
+      end
+      strong_memoize_attr :current_session_data
+
       private
 
       attr_reader :user
@@ -152,10 +159,6 @@ def admin_mode_requested_rs_key
         @admin_mode_requested_rs_key ||= { res: :current_user_mode, user: user.id, method: :admin_mode_requested? }
       end
 
-      def current_session_data
-        @current_session ||= Gitlab::NamespacedSessionStore.new(SESSION_STORE_KEY)
-      end
-
       def session_with_admin_mode?
         return true if bypass_session?
 
diff --git a/spec/features/user_settings/active_sessions_spec.rb b/spec/features/user_settings/active_sessions_spec.rb
index bc0693d79e1f820b6d59cbca930af602bd56b35b..bb3ad718173ca3fed4a3d62ff8a306fb26013f02 100644
--- a/spec/features/user_settings/active_sessions_spec.rb
+++ b/spec/features/user_settings/active_sessions_spec.rb
@@ -110,4 +110,20 @@
       expect(page).to have_content('You need to sign in or sign up before continuing.')
     end
   end
+
+  it 'load_raw_session does load known attributes only' do
+    new_session = ActiveSession.send(:load_raw_session,
+      'v2:{"ip_address": "127.0.0.1", "browser": "Firefox", "os": "Debian",' \
+      '"device_type": "desktop", "session_id": "8f62cc7383c",' \
+      '"new_attribute": "unknown attribute"}'
+    )
+
+    expect(new_session).to have_attributes(
+      ip_address: "127.0.0.1",
+      browser: "Firefox",
+      os: "Debian",
+      device_type: "desktop",
+      session_id: "8f62cc7383c"
+    )
+  end
 end
diff --git a/spec/lib/gitlab/auth/current_user_mode_spec.rb b/spec/lib/gitlab/auth/current_user_mode_spec.rb
index 650af6af22961c691f58105147086e2f774cf533..014c812d9eea4a1e26299fe6e270ce6d468b03ef 100644
--- a/spec/lib/gitlab/auth/current_user_mode_spec.rb
+++ b/spec/lib/gitlab/auth/current_user_mode_spec.rb
@@ -7,6 +7,55 @@
 
   subject { described_class.new(user) }
 
+  describe '#initialize' do
+    context 'with user' do
+      around do |example|
+        Gitlab::Session.with_session(nil) do
+          example.run
+        end
+      end
+
+      it 'has no session' do
+        subject
+        expect(Gitlab::Session.current).to be_nil
+      end
+    end
+
+    context 'with user and session' do
+      include_context 'custom session'
+      let(:session) { { 'key' => "value" } }
+
+      it 'has a session' do
+        described_class.new(user, session)
+        expect(Gitlab::Session.current).to eq(session)
+      end
+    end
+  end
+
+  describe '#current_session_data' do
+    include_context 'custom session'
+    let(:session) { { 'key' => "value" } }
+
+    it 'without session' do
+      expect(Gitlab::Session.current).to eq(session)
+
+      expect(Gitlab::NamespacedSessionStore).to receive(:new).with(described_class::SESSION_STORE_KEY, session)
+
+      subject.current_session_data
+      expect(Gitlab::Session.current).to eq(session)
+    end
+
+    it 'with session' do
+      expect(Gitlab::Session.current).to eq(session)
+      subject = described_class.new(user, session)
+
+      expect(Gitlab::NamespacedSessionStore).to receive(:new).with(described_class::SESSION_STORE_KEY, session)
+
+      subject.current_session_data
+      expect(Gitlab::Session.current).to eq(session)
+    end
+  end
+
   context 'when session is available' do
     include_context 'custom session'