diff --git a/Gemfile b/Gemfile
index 4cc4666a67b84914e48552bb8de78e7fde466dac..05dda72667023decc96947508d8090e8e6e0b292 100644
--- a/Gemfile
+++ b/Gemfile
@@ -696,7 +696,7 @@ gem 'valid_email', '~> 0.1', feature_category: :shared
 
 # JSON
 gem 'jsonb_accessor', '~> 1.4', feature_category: :shared
-gem 'json', '~> 2.7.2', feature_category: :shared
+gem 'json', '~> 2.10.0', feature_category: :shared
 gem 'json_schemer', '~> 2.3.0', feature_category: :shared
 gem 'oj', '~> 3.13.21', feature_category: :shared
 gem 'oj-introspect', '~> 0.7', feature_category: :shared
diff --git a/Gemfile.checksum b/Gemfile.checksum
index 2b0d792e30bf1bd63d4954eb9fe2a44d36dbbb60..29173a0e396b4ad6161c225529f192c3779511b4 100644
--- a/Gemfile.checksum
+++ b/Gemfile.checksum
@@ -348,8 +348,8 @@
 {"name":"jira-ruby","version":"2.3.0","platform":"ruby","checksum":"abf26e6bff4a8ea40bae06f7df6276a5776905c63fb2070934823ca54f62eb62"},
 {"name":"jmespath","version":"1.6.2","platform":"ruby","checksum":"238d774a58723d6c090494c8879b5e9918c19485f7e840f2c1c7532cf84ebcb1"},
 {"name":"js_regex","version":"3.8.0","platform":"ruby","checksum":"7934bcdd5a0e6d5af4a520288fd4684a02a472ae55831d9178ccaf82356344b5"},
-{"name":"json","version":"2.7.3","platform":"java","checksum":"7cada8cb6489bac08bceb00da82dd9ed0aada9ea2f483db4b2471e239b28e2f8"},
-{"name":"json","version":"2.7.3","platform":"ruby","checksum":"7cc3ccbfc5f83025f5524776ae8581e911772944169666988406679251932bdf"},
+{"name":"json","version":"2.10.1","platform":"java","checksum":"de07233fb74113af2186eb9342f8207c9be0faf289a1e2623c9b0acb8b0b0ee1"},
+{"name":"json","version":"2.10.1","platform":"ruby","checksum":"ddc88ad91a1baf3f0038c174f253af3b086d30dc74db17ca4259bbde982f94dc"},
 {"name":"json-jwt","version":"1.16.6","platform":"ruby","checksum":"ab451f9cd8743cecc4137f4170806046c1d8a6d4ee6e8570e0b5c958409b266c"},
 {"name":"json_schemer","version":"2.3.0","platform":"ruby","checksum":"9f1fa173b859ca520f15e9e8d08b0892ffca80b78dd8221feb3e360ff4cdeb35"},
 {"name":"jsonb_accessor","version":"1.4","platform":"java","checksum":"2c5590d33d89c7b929d5cf38ae3d2c52658bf6f84f03b06ede5c88e9d76f3451"},
diff --git a/Gemfile.lock b/Gemfile.lock
index 7b3adb54246c896ccc716fc7046dd54bbf975796..6a5d7fbe8a6437456fa342cef0852ad2bcde62b2 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -10,7 +10,7 @@ PATH
     click_house-client (0.1.0)
       activesupport (< 8)
       addressable (~> 2.8)
-      json (~> 2.7.2)
+      json (~> 2.7)
 
 PATH
   remote: gems/csv_builder
@@ -48,7 +48,7 @@ PATH
       google-protobuf (~> 3.25, >= 3.25.3)
       googleauth (~> 1.8.1)
       grpc (= 1.63.0)
-      json (~> 2.7.2)
+      json (~> 2.7)
       jwt (~> 2.5)
       logger (~> 1.5)
       minitest (~> 5.11.0)
@@ -1048,7 +1048,7 @@ GEM
       character_set (~> 1.4)
       regexp_parser (~> 2.5)
       regexp_property_values (~> 1.0)
-    json (2.7.3)
+    json (2.10.1)
     json-jwt (1.16.6)
       activesupport (>= 4.2)
       aes_key_wrap
@@ -2167,7 +2167,7 @@ DEPENDENCIES
   ipynbdiff!
   jira-ruby (~> 2.3.0)
   js_regex (~> 3.8)
-  json (~> 2.7.2)
+  json (~> 2.10.0)
   json_schemer (~> 2.3.0)
   jsonb_accessor (~> 1.4)
   jwt (~> 2.9.3)
diff --git a/Gemfile.next.checksum b/Gemfile.next.checksum
index ca2090b988eb138199944f10f647191c99bd6b6f..d5a427538d830b02dfe9b1961600cbd399844572 100644
--- a/Gemfile.next.checksum
+++ b/Gemfile.next.checksum
@@ -351,8 +351,8 @@
 {"name":"jira-ruby","version":"2.3.0","platform":"ruby","checksum":"abf26e6bff4a8ea40bae06f7df6276a5776905c63fb2070934823ca54f62eb62"},
 {"name":"jmespath","version":"1.6.2","platform":"ruby","checksum":"238d774a58723d6c090494c8879b5e9918c19485f7e840f2c1c7532cf84ebcb1"},
 {"name":"js_regex","version":"3.8.0","platform":"ruby","checksum":"7934bcdd5a0e6d5af4a520288fd4684a02a472ae55831d9178ccaf82356344b5"},
-{"name":"json","version":"2.7.3","platform":"java","checksum":"7cada8cb6489bac08bceb00da82dd9ed0aada9ea2f483db4b2471e239b28e2f8"},
-{"name":"json","version":"2.7.3","platform":"ruby","checksum":"7cc3ccbfc5f83025f5524776ae8581e911772944169666988406679251932bdf"},
+{"name":"json","version":"2.10.1","platform":"java","checksum":"de07233fb74113af2186eb9342f8207c9be0faf289a1e2623c9b0acb8b0b0ee1"},
+{"name":"json","version":"2.10.1","platform":"ruby","checksum":"ddc88ad91a1baf3f0038c174f253af3b086d30dc74db17ca4259bbde982f94dc"},
 {"name":"json-jwt","version":"1.16.6","platform":"ruby","checksum":"ab451f9cd8743cecc4137f4170806046c1d8a6d4ee6e8570e0b5c958409b266c"},
 {"name":"json_schemer","version":"2.3.0","platform":"ruby","checksum":"9f1fa173b859ca520f15e9e8d08b0892ffca80b78dd8221feb3e360ff4cdeb35"},
 {"name":"jsonb_accessor","version":"1.4","platform":"java","checksum":"2c5590d33d89c7b929d5cf38ae3d2c52658bf6f84f03b06ede5c88e9d76f3451"},
@@ -727,8 +727,8 @@
 {"name":"state_machines","version":"0.5.0","platform":"ruby","checksum":"23e6249d374a920b528dccade403518b4abbd83841a3e2c9ef13e6f1a009b102"},
 {"name":"state_machines-activemodel","version":"0.8.0","platform":"ruby","checksum":"e932dab190d4be044fb5f9cab01a3ea0b092c5f113d4676c6c0a0d49bf738d2c"},
 {"name":"state_machines-activerecord","version":"0.8.0","platform":"ruby","checksum":"072fb701b8ab03de0608297f6c55dc34ed096e556fa8f77e556f3c461c71aab6"},
-{"name":"stringio","version":"3.1.4","platform":"java","checksum":"04cf2b014409c3b5fb36145e7189e7dbfc363b780b95045dbff2bee0ad14430a"},
-{"name":"stringio","version":"3.1.4","platform":"ruby","checksum":"7dd68f6f1a88610817c21f6d926dbf36e1fc585d3869fcd4a56c1f3210591d70"},
+{"name":"stringio","version":"3.1.5","platform":"java","checksum":"d1e136540e41c833ba39c0468b212f33755b438517b45bebf5868eec2c9422a7"},
+{"name":"stringio","version":"3.1.5","platform":"ruby","checksum":"bca92461515a131535743bc81d5559fa1de7d80cff9a654d6c0af6f9f27e35c8"},
 {"name":"strings","version":"0.2.1","platform":"ruby","checksum":"933293b3c95cf85b81eb44b3cf673e3087661ba739bbadfeadf442083158d6fb"},
 {"name":"strings-ansi","version":"0.2.0","platform":"ruby","checksum":"90262d760ea4a94cc2ae8d58205277a343409c288cbe7c29416b1826bd511c88"},
 {"name":"swd","version":"2.0.3","platform":"ruby","checksum":"4cdbe2a4246c19f093fce22e967ec3ebdd4657d37673672e621bf0c7eb770655"},
diff --git a/Gemfile.next.lock b/Gemfile.next.lock
index 199dada6aca138f3dc7322bae3f7e49cf4ab113a..615e7b4348300b5d7fb2135e2f56e900fc4b513c 100644
--- a/Gemfile.next.lock
+++ b/Gemfile.next.lock
@@ -10,7 +10,7 @@ PATH
     click_house-client (0.1.0)
       activesupport (< 8)
       addressable (~> 2.8)
-      json (~> 2.7.2)
+      json (~> 2.7)
 
 PATH
   remote: gems/csv_builder
@@ -48,7 +48,7 @@ PATH
       google-protobuf (~> 3.25, >= 3.25.3)
       googleauth (~> 1.8.1)
       grpc (= 1.63.0)
-      json (~> 2.7.2)
+      json (~> 2.7)
       jwt (~> 2.5)
       logger (~> 1.5)
       minitest (~> 5.11.0)
@@ -1065,7 +1065,7 @@ GEM
       character_set (~> 1.4)
       regexp_parser (~> 2.5)
       regexp_property_values (~> 1.0)
-    json (2.7.3)
+    json (2.10.1)
     json-jwt (1.16.6)
       activesupport (>= 4.2)
       aes_key_wrap
@@ -1853,7 +1853,7 @@ GEM
     state_machines-activerecord (0.8.0)
       activerecord (>= 5.1)
       state_machines-activemodel (>= 0.8.0)
-    stringio (3.1.4)
+    stringio (3.1.5)
     strings (0.2.1)
       strings-ansi (~> 0.2)
       unicode-display_width (>= 1.5, < 3.0)
@@ -2202,7 +2202,7 @@ DEPENDENCIES
   ipynbdiff!
   jira-ruby (~> 2.3.0)
   js_regex (~> 3.8)
-  json (~> 2.7.2)
+  json (~> 2.10.0)
   json_schemer (~> 2.3.0)
   jsonb_accessor (~> 1.4)
   jwt (~> 2.9.3)
diff --git a/gems/click_house-client/Gemfile.lock b/gems/click_house-client/Gemfile.lock
index 50396a3f8a2d15322320def502bb5995efb258ee..ddacfb4804bd8d4c413753fac3ef4df56620b090 100644
--- a/gems/click_house-client/Gemfile.lock
+++ b/gems/click_house-client/Gemfile.lock
@@ -4,7 +4,7 @@ PATH
     click_house-client (0.1.0)
       activesupport (< 8)
       addressable (~> 2.8)
-      json (~> 2.7.2)
+      json (~> 2.7)
 
 GEM
   remote: https://rubygems.org/
@@ -28,7 +28,7 @@ GEM
       rubocop-rspec (~> 2.27.1)
     i18n (1.14.1)
       concurrent-ruby (~> 1.0)
-    json (2.7.2)
+    json (2.10.1)
     language_server-protocol (3.17.0.3)
     minitest (5.18.1)
     parallel (1.23.0)
diff --git a/gems/click_house-client/click_house-client.gemspec b/gems/click_house-client/click_house-client.gemspec
index 55f30cbc10f93a751e80766a4704d8047a9d2e12..acab626a7a117bba2202dacde1027f3678baa967 100644
--- a/gems/click_house-client/click_house-client.gemspec
+++ b/gems/click_house-client/click_house-client.gemspec
@@ -14,7 +14,7 @@ Gem::Specification.new do |spec|
 
   spec.add_runtime_dependency "activesupport", "< 8"
   spec.add_runtime_dependency "addressable", "~> 2.8"
-  spec.add_runtime_dependency 'json', '~> 2.7.2'
+  spec.add_runtime_dependency 'json', '~> 2.7'
 
   spec.add_development_dependency 'gitlab-styles', '~> 12.0.1'
   spec.add_development_dependency "rake", "~> 13.0"
diff --git a/gems/gitlab-backup-cli/Gemfile.lock b/gems/gitlab-backup-cli/Gemfile.lock
index fdbffb3fcfffc71d042285cfe5d414ca02af3c9a..e775cad961c931512002bcec5bc3f44319e4f10a 100644
--- a/gems/gitlab-backup-cli/Gemfile.lock
+++ b/gems/gitlab-backup-cli/Gemfile.lock
@@ -19,7 +19,7 @@ PATH
       google-protobuf (~> 3.25, >= 3.25.3)
       googleauth (~> 1.8.1)
       grpc (= 1.63.0)
-      json (~> 2.7.2)
+      json (~> 2.7)
       jwt (~> 2.5)
       logger (~> 1.5)
       minitest (~> 5.11.0)
@@ -111,7 +111,7 @@ GEM
       googleapis-common-protos-types (~> 1.0)
     i18n (1.14.5)
       concurrent-ruby (~> 1.0)
-    json (2.7.2)
+    json (2.10.1)
     jwt (2.8.2)
       base64
     language_server-protocol (3.17.0.3)
diff --git a/gems/gitlab-backup-cli/Gemfile.next.lock b/gems/gitlab-backup-cli/Gemfile.next.lock
index 9cd58864fd1b530dd53590b194c96c9a8bcbf6aa..e9cc14a40e3217c5772e1b08e7a7a867033997cc 100644
--- a/gems/gitlab-backup-cli/Gemfile.next.lock
+++ b/gems/gitlab-backup-cli/Gemfile.next.lock
@@ -19,7 +19,7 @@ PATH
       google-protobuf (~> 3.25, >= 3.25.3)
       googleauth (~> 1.8.1)
       grpc (= 1.63.0)
-      json (~> 2.7.2)
+      json (~> 2.7)
       jwt (~> 2.5)
       logger (~> 1.5)
       minitest (~> 5.11.0)
@@ -133,7 +133,7 @@ GEM
       googleapis-common-protos-types (~> 1.0)
     i18n (1.14.6)
       concurrent-ruby (~> 1.0)
-    json (2.7.2)
+    json (2.10.1)
     jwt (2.9.1)
       base64
     language_server-protocol (3.17.0.3)
diff --git a/gems/gitlab-backup-cli/gitlab-backup-cli.gemspec b/gems/gitlab-backup-cli/gitlab-backup-cli.gemspec
index bcccfd98c539a4ff7c2b816fd81a871e7f48a087..00f1c92719800032cda0213ee34e1cefebe1201d 100644
--- a/gems/gitlab-backup-cli/gitlab-backup-cli.gemspec
+++ b/gems/gitlab-backup-cli/gitlab-backup-cli.gemspec
@@ -39,7 +39,7 @@ Gem::Specification.new do |spec|
   spec.add_dependency "faraday", "~> 2"
   spec.add_dependency "google-protobuf", "~> 3.25", ">= 3.25.3"
   spec.add_dependency "grpc", "= 1.63.0"
-  spec.add_dependency "json", "~> 2.7.2"
+  spec.add_dependency "json", "~> 2.7"
   spec.add_dependency "jwt", "~> 2.5"
   spec.add_dependency "logger", "~> 1.5"
   spec.add_dependency "minitest", "~> 5.11.0"
diff --git a/spec/lib/container_registry/client_spec.rb b/spec/lib/container_registry/client_spec.rb
index c6c763dd283e66122dd5a2ecc4a0f06d2544283f..966f42ed31a53ff1b0f80ee74c2a402fc24138ae 100644
--- a/spec/lib/container_registry/client_spec.rb
+++ b/spec/lib/container_registry/client_spec.rb
@@ -263,21 +263,21 @@
         mediaType: 'application/vnd.docker.distribution.manifest.v2+json',
         config: {
           mediaType: 'application/vnd.docker.container.image.v1+json',
-          size: 21,
-          digest: 'sha256:4435000728ee66e6a80e55637fc22725c256b61de344a2ecdeaac6bdb36e8bc3'
+          size: 18,
+          digest: 'sha256:627025e22fcdc17810e8edb86c703b2359c5b27f72289013793049a92ab735bf'
         }
       }
     end
 
     it 'uploads a random image and returns the manifest' do
-      stub_upload('path', "{\n  \"config\": {\n  }\n}", 'sha256:4435000728ee66e6a80e55637fc22725c256b61de344a2ecdeaac6bdb36e8bc3')
+      stub_upload('path', "{\n  \"config\": {}\n}", 'sha256:627025e22fcdc17810e8edb86c703b2359c5b27f72289013793049a92ab735bf')
 
       expect(subject).to eq(result_manifest)
     end
 
     context 'when upload fails' do
       before do
-        stub_upload('path', "{\n  \"config\": {\n  }\n}", 'sha256:4435000728ee66e6a80e55637fc22725c256b61de344a2ecdeaac6bdb36e8bc3', 500)
+        stub_upload('path', "{\n  \"config\": {}\n}", 'sha256:627025e22fcdc17810e8edb86c703b2359c5b27f72289013793049a92ab735bf', 500)
       end
 
       it { is_expected.to be nil }
diff --git a/spec/lib/gitlab/json_spec.rb b/spec/lib/gitlab/json_spec.rb
index 95deec845fd092ba6be4c392b11ee11466a5982e..e255d25d73aa20a5fbad1dc39499315f2e3714ce 100644
--- a/spec/lib/gitlab/json_spec.rb
+++ b/spec/lib/gitlab/json_spec.rb
@@ -199,11 +199,8 @@
           "more": {
             "test": true
           },
-          "multi_line_empty_array": [
-
-          ],
-          "multi_line_empty_obj": {
-          }
+          "multi_line_empty_array": [],
+          "multi_line_empty_obj": {}
         }
       STR
 
@@ -230,11 +227,8 @@
           "more" : {
             "test" : true
           },
-          "multi_line_empty_array" : [
-
-          ],
-          "multi_line_empty_obj" : {
-          }
+          "multi_line_empty_array" : [],
+          "multi_line_empty_obj" : {}
         }
       STR
 
diff --git a/spec/services/projects/container_repository/third_party/delete_tags_service_spec.rb b/spec/services/projects/container_repository/third_party/delete_tags_service_spec.rb
index d3d3f3bb7ce36c779152eaafaf9b391ad6605d76..7e3a8825367520b17564ddad7d31fb44525fce51 100644
--- a/spec/services/projects/container_repository/third_party/delete_tags_service_spec.rb
+++ b/spec/services/projects/container_repository/third_party/delete_tags_service_spec.rb
@@ -14,7 +14,7 @@
 
     context 'with tags to delete' do
       it 'deletes the tags by name' do
-        stub_upload('sha256:4435000728ee66e6a80e55637fc22725c256b61de344a2ecdeaac6bdb36e8bc3')
+        stub_upload('sha256:627025e22fcdc17810e8edb86c703b2359c5b27f72289013793049a92ab735bf')
 
         tags.each { |tag| stub_put_manifest_request(tag) }
 
@@ -24,7 +24,7 @@
       end
 
       it 'succeeds when tag delete returns 404' do
-        stub_upload('sha256:4435000728ee66e6a80e55637fc22725c256b61de344a2ecdeaac6bdb36e8bc3')
+        stub_upload('sha256:627025e22fcdc17810e8edb86c703b2359c5b27f72289013793049a92ab735bf')
 
         stub_put_manifest_request('A')
         stub_put_manifest_request('Ba')
@@ -38,7 +38,7 @@
       context 'with failures' do
         context 'when the dummy manifest generation fails' do
           before do
-            stub_upload('sha256:4435000728ee66e6a80e55637fc22725c256b61de344a2ecdeaac6bdb36e8bc3', success: false)
+            stub_upload('sha256:627025e22fcdc17810e8edb86c703b2359c5b27f72289013793049a92ab735bf', success: false)
           end
 
           it { is_expected.to eq(status: :error, message: 'could not generate manifest') }
@@ -46,9 +46,9 @@
 
         context 'when updating tags fails' do
           before do
-            stub_upload('sha256:4435000728ee66e6a80e55637fc22725c256b61de344a2ecdeaac6bdb36e8bc3')
+            stub_upload('sha256:627025e22fcdc17810e8edb86c703b2359c5b27f72289013793049a92ab735bf')
 
-            stub_request(:delete, "http://registry.gitlab/v2/#{repository.path}/manifests/sha256:4435000728ee66e6a80e55637fc22725c256b61de344a2ecdeaac6bdb36e8bc3")
+            stub_request(:delete, "http://registry.gitlab/v2/#{repository.path}/manifests/sha256:627025e22fcdc17810e8edb86c703b2359c5b27f72289013793049a92ab735bf")
               .to_return(status: 200, body: '', headers: {})
           end
 
diff --git a/spec/support/shared_contexts/services/projects/container_repository/delete_tags_service_shared_context.rb b/spec/support/shared_contexts/services/projects/container_repository/delete_tags_service_shared_context.rb
index e2e98dfda110b1cd4db056962309f41354989274..bb9e3889d92323d3dede5ac48eb71c199e1f3974 100644
--- a/spec/support/shared_contexts/services/projects/container_repository/delete_tags_service_shared_context.rb
+++ b/spec/support/shared_contexts/services/projects/container_repository/delete_tags_service_shared_context.rb
@@ -52,7 +52,7 @@ def stub_digest_config(digest, created_at)
   end
 
   def stub_upload(digest, success: true)
-    content = "{\n  \"config\": {\n  }\n}"
+    content = "{\n  \"config\": {}\n}"
     expect_any_instance_of(ContainerRegistry::Client)
       .to receive(:upload_blob)
       .with(repository.path, content, digest) { double(success?: success) }
diff --git a/spec/tooling/danger/master_pipeline_status_spec.rb b/spec/tooling/danger/master_pipeline_status_spec.rb
index 4448ddeb783dac4050e821dc0dfe258ba9c1ea8d..2ff1020d823904f864931c8e258c9626d905dce4 100644
--- a/spec/tooling/danger/master_pipeline_status_spec.rb
+++ b/spec/tooling/danger/master_pipeline_status_spec.rb
@@ -164,7 +164,7 @@
         let(:expected_output) do
           <<~MSG
             Failed to parse JSON for #{expected_status_url}. Ignoring. Full error:
-            unexpected token at '{'
+            expected object key, got '
           MSG
         end