防止 Kubernetes 中的 nginx ingress 目录遍历

防止 Kubernetes 中的 nginx ingress 目录遍历

我定义了以下入口:

---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: someName
  namespace: test
  annotations:
    kubernetes.io/ingress.class: "ingress-public"
    nginx.ingress.kubernetes.io/affinity: "cookie"
    nginx.ingress.kubernetes.io/session-cookie-name: "JSESSIONID"
    nginx.ingress.kubernetes.io/connection-proxy-header: "keep-alive"
    nginx.ingress.kubernetes.io/server-snippet: |
      # block if not / or /test or /something
      if ($request_uri !~* "(^\/(?:(?:test|something)(?:\/|$)|$))") {
        return 404 ;
        break;
      }
      # redirect if proto_http
      if ($http_x_forwarded_proto = 'http') {
        return 301 https://$host$request_uri;
        break;
      }

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

spec:
  rules:
  - host: myhost.example.com
    http:
      paths:
      - path: /
        backend:
          serviceName: someservice
          servicePort: 80

正则表达式涵盖了大多数请求的情况,例如/config- 由于这与正则表达式不匹配,因此返回 404。

我目前面临两个问题。

  1. /test%2F..%2Fconfig即使与正则表达式不匹配,请求也不会返回 404。
  2. 请求/test/..%2Fconfig允许您到达/config

那么,是否存在更好的正则表达式可以涵盖这些情况,或者是否有办法将其转换$request_uri为绝对 uri,以便正则表达式可以在其上工作而不是编码 uri?

正则表达式在这里有一些测试用例:https://regex101.com/r/Msu402/1

答案1

您可能想尝试使用location文档) 或者$uri文档),因为它们都匹配规范化的 URI。由于if 是邪恶的我建议一个地点(未经测试):

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

编辑:我重读了你的问题,它应该阻止访问正则表达式中提到的位置。所以我添加了“不”...

相关内容