Preventing directory traversal in nginx ingress in Kubernetes

I have the following ingress defined:

apiVersion: extensions/v1beta1
kind: Ingress
  name: someName
  namespace: test
  annotations: "ingress-public" "cookie" "JSESSIONID" "keep-alive" |
      # block if not / or /test or /something
      if ($request_uri !~* "(^\/(?:(?:test|something)(?:\/|$)|$))") {
        return 404 ;
      # redirect if proto_http
      if ($http_x_forwarded_proto = 'http') {
        return 301 https://$host$request_uri;

      # hsts required header
      add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

  - host:
      - path: /
          serviceName: someservice
          servicePort: 80

The regex covers most cases where requests are something like /config - as this doesn't match the regex, it returns a 404.

There are two problems that I currently have.

  1. Requesting /test%2F..%2Fconfig does NOT return a 404 even though this doesn't match the regex.
  2. Requesting /test/..%2Fconfig allows you to reach /config.

So is there either a better regex that would cover these cases, or is there a way to convert $request_uri into an absolute uri so the regex can work on that instead of an encoded uri?

The regex is here with some test cases:

You might want to try using a location (doc) or $uri (doc) since both match a normalized URI. Since if is evil I would suggest a location (untested):

location ~* ^/(?!test|something) {
  return 404;

Edit: I reread your question and it should BLOCK access to the mentioned locations in the regex. So I added the "not"...