summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-07-01 00:49:57 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-07-01 00:49:57 +0000
commitc31c9f964a81f104f4c265b6082b469361fb1653 (patch)
treeff99939150d948ed8e8a1fb1139eb8fac778e69b /app
parentc6c26f3b730d4bbc567aee33b4c6fd621517055e (diff)
downloadgitlab-ce-c31c9f964a81f104f4c265b6082b469361fb1653.tar.gz
Add latest changes from gitlab-org/security/gitlab@14-0-stable-ee
Diffstat (limited to 'app')
-rw-r--r--app/controllers/graphql_controller.rb29
-rw-r--r--app/graphql/mutations/echo.rb33
-rw-r--r--app/graphql/types/mutation_type.rb1
3 files changed, 61 insertions, 2 deletions
diff --git a/app/controllers/graphql_controller.rb b/app/controllers/graphql_controller.rb
index 725d8b62c77..515fbd7b482 100644
--- a/app/controllers/graphql_controller.rb
+++ b/app/controllers/graphql_controller.rb
@@ -20,12 +20,16 @@ class GraphqlController < ApplicationController
# around in GraphiQL.
protect_from_forgery with: :null_session, only: :execute
- before_action :authorize_access_api!
+ # must come first: current_user is set up here
before_action(only: [:execute]) { authenticate_sessionless_user!(:api) }
+
+ before_action :authorize_access_api!
before_action :set_user_last_activity
before_action :track_vs_code_usage
before_action :disable_query_limiting
+ before_action :disallow_mutations_for_get
+
# Since we deactivate authentication from the main ApplicationController and
# defer it to :authorize_access_api!, we need to override the bypass session
# callback execution order here
@@ -62,6 +66,25 @@ class GraphqlController < ApplicationController
private
+ def disallow_mutations_for_get
+ return unless request.get? || request.head?
+ return unless any_mutating_query?
+
+ raise ::Gitlab::Graphql::Errors::ArgumentError, "Mutations are forbidden in #{request.request_method} requests"
+ end
+
+ def any_mutating_query?
+ if multiplex?
+ multiplex_queries.any? { |q| mutation?(q[:query], q[:operation_name]) }
+ else
+ mutation?(query)
+ end
+ end
+
+ def mutation?(query_string, operation_name = params[:operationName])
+ ::GraphQL::Query.new(GitlabSchema, query_string, operation_name: operation_name).mutation?
+ end
+
# Tests may mark some GraphQL queries as exempt from SQL query limits
def disable_query_limiting
return unless Gitlab::QueryLimiting.enabled_for_env?
@@ -130,7 +153,9 @@ class GraphqlController < ApplicationController
end
def authorize_access_api!
- access_denied!("API not accessible for user.") unless can?(current_user, :access_api)
+ return if can?(current_user, :access_api)
+
+ render_error('API not accessible for user', status: :forbidden)
end
# Overridden from the ApplicationController to make the response look like
diff --git a/app/graphql/mutations/echo.rb b/app/graphql/mutations/echo.rb
new file mode 100644
index 00000000000..61d39009ba4
--- /dev/null
+++ b/app/graphql/mutations/echo.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module Mutations
+ class Echo < BaseMutation
+ graphql_name 'EchoCreate'
+ description <<~DOC
+ A mutation that does not perform any changes.
+
+ This is expected to be used for testing of endpoints, to verify
+ that a user has mutation access.
+ DOC
+
+ argument :errors,
+ type: [::GraphQL::STRING_TYPE],
+ required: false,
+ description: 'Errors to return to the user.'
+
+ argument :messages,
+ type: [::GraphQL::STRING_TYPE],
+ as: :echoes,
+ required: false,
+ description: 'Messages to return to the user.'
+
+ field :echoes,
+ type: [::GraphQL::STRING_TYPE],
+ null: true,
+ description: 'Messages returned to the user.'
+
+ def resolve(**args)
+ args
+ end
+ end
+end
diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb
index 6b1146f8f09..6d3327f9735 100644
--- a/app/graphql/types/mutation_type.rb
+++ b/app/graphql/types/mutation_type.rb
@@ -104,6 +104,7 @@ module Types
mount_mutation Mutations::Ci::RunnersRegistrationToken::Reset, feature_flag: :runner_graphql_query
mount_mutation Mutations::Namespace::PackageSettings::Update
mount_mutation Mutations::UserCallouts::Create
+ mount_mutation Mutations::Echo
end
end