Skip to content

Reject requests with path traversal attempts

David Fernandez requested to merge 483098-reject-requests into master

🔭 Context

We are slowing rolling out the Rack middleware for path traversal checks. See https://gitlab.com/groups/gitlab-org/-/epics/13437+.

The middleware is only logging attempts (requests are not rejected). At the time of this writing, it is behind a feature flag that has been enabled globally on gitlab.com.

Over time, we improved its accuracy to make sure that we didn't have any false positive (valid requests that would be flagged as attempts).

Since, we don't see any new false positive, it is now time to implement the "active" part of the middleware: reject the requests if there is an attempt.

Obviously, we don't want to deploy this change in one go and we're going to use another feature flag. We will thus have two feature flag s:

  • One global switch to disable the middleware completely.
  • One to switch between "only log attempts" (current behavior) and "log and reject attempts" (new behavior).

This MR introduces the new behavior and the second feature flag.

Rollout issue: https://gitlab.com/gitlab-org/gitlab/-/issues/415460.

Related issue: https://gitlab.com/gitlab-org/gitlab/-/issues/483098.

🤔 What does this MR do and why?

  • Update lib/gitlab/middleware/path_traversal_check.rb to reject requests when an attempt is detected.
    • Gate this behind a new feature flag : check_path_traversal_middleware_reject_requests.
  • Update the related specs.

🏁 MR acceptance checklist

Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

🖥 Screenshots or screen recordings

No UI changes.

How to set up and validate locally

In a rails console:

  1. Enable the global switch: Feature.enable(:check_path_traversal_middleware).
  2. Enable the reject logic: Feature.enable(:check_path_traversal_middleware_reject_requests)

Now, try to access the GitLab instance with a path traversal attempt: in your browser, http://gdk.test:8000/foo%2F..%2Fbar

You're greeted with: Potential path traversal attempt detected.

You can try with $ curl:

$ curl -vvv http://gdk.test:8000/foo%2F..%2Fbar
* Host gdk.test:8000 was resolved.
* IPv6: (none)
* IPv4: 172.16.123.1
*   Trying 172.16.123.1:8000...
* Connected to gdk.test (172.16.123.1) port 8000
> GET /foo%2F..%2Fbar HTTP/1.1
> Host: gdk.test:8000
> User-Agent: curl/8.6.0
> Accept: */*
> 
< HTTP/1.1 400 Bad Request
< Content-Length: 42
< Content-Type: text/plain
< X-Gitlab-Meta: {"correlation_id":"01J7346AZH4NZQG8MRM4Q8JP4C","version":"1"}
< X-Request-Id: 01J7346AZH4NZQG8MRM4Q8JP4C
< X-Runtime: 0.002350
< Date: Fri, 06 Sep 2024 07:36:16 GMT
< 
* Connection #0 to host gdk.test left intact
Potential path traversal attempt detected.
Edited by David Fernandez

Merge request reports

Loading