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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/middleware/path_traversal_check.rb')
-rw-r--r--lib/gitlab/middleware/path_traversal_check.rb58
1 files changed, 58 insertions, 0 deletions
diff --git a/lib/gitlab/middleware/path_traversal_check.rb b/lib/gitlab/middleware/path_traversal_check.rb
new file mode 100644
index 00000000000..79465f3cb30
--- /dev/null
+++ b/lib/gitlab/middleware/path_traversal_check.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Middleware
+ class PathTraversalCheck
+ PATH_TRAVERSAL_MESSAGE = 'Potential path traversal attempt detected'
+
+ def initialize(app)
+ @app = app
+ end
+
+ def call(env)
+ if Feature.enabled?(:check_path_traversal_middleware, Feature.current_request)
+ log_params = {}
+
+ execution_time = measure_execution_time do
+ check(env, log_params)
+ end
+
+ log_params[:duration_ms] = execution_time.round(5) if execution_time
+
+ log(log_params) unless log_params.empty?
+ end
+
+ @app.call(env)
+ end
+
+ private
+
+ def measure_execution_time(&blk)
+ if Feature.enabled?(:log_execution_time_path_traversal_middleware, Feature.current_request)
+ Benchmark.ms(&blk)
+ else
+ yield
+
+ nil
+ end
+ end
+
+ def check(env, log_params)
+ request = ::Rack::Request.new(env)
+ fullpath = request.fullpath
+ decoded_fullpath = CGI.unescape(fullpath)
+ ::Gitlab::PathTraversal.check_path_traversal!(decoded_fullpath, skip_decoding: true)
+
+ rescue ::Gitlab::PathTraversal::PathTraversalAttackError
+ log_params[:fullpath] = fullpath
+ log_params[:message] = PATH_TRAVERSAL_MESSAGE
+ end
+
+ def log(payload)
+ Gitlab::AppLogger.warn(
+ payload.merge(class_name: self.class.name)
+ )
+ end
+ end
+ end
+end