acouvreur / traefik-modsecurity-plugin

Traefik plugin to proxy requests to owasp/modsecurity-crs:apache container
https://plugins.traefik.io/plugins/628c9eadffc0cd18356a9799/modsecurity-plugin
Apache License 2.0
142 stars 25 forks source link

500 error for big request body without files #11

Open igoooor opened 2 years ago

igoooor commented 2 years ago

I'm not sure if the plugin is causing this, or if it's the owasp container. That's why I opened the same issue on the owasp container: https://github.com/coreruleset/modsecurity-crs-docker/issues/85

I have a form which submits base64 images, so the request body size is somewhere in the 8Mb. On the owasp container, If I don't specify MODSEC_REQ_BODY_NOFILES_LIMIT with a big number, then I will see the modsec rule 200002 to fire. If I specify MODSEC_REQ_BODY_NOFILES_LIMIT with a big enough number (25Mb in my case), the modsec container will not show any errors, however my page will display a 500 Internal Server Error.

If I don't use modsec at all, my page does not show any error. Would anyone have a clue why this is happening?

To be clear, I'm not uploading files, just big text body content.

The reason I'm also posting here, is because the rule will correctly fire if I leave its default value of 128Kb. So I assume it can correctly handle such big request body. So if it can handle it, it must fail somewhere else I would guess. And when the rule correctly fires, I still see a 500 error on my webpage, so I assume there is still something wrong going on somewhere

I am using the plugin in its version 1.2.1, with maxBodySize: 26214400 I also tried version 1.1.0 with the same result

acouvreur commented 2 years ago

I also tried version 1.1.0 with the same result

Interesting!

Do you have any logging from any container?

igoooor commented 2 years ago

No not yet, I will enable logs and check again

igoooor commented 2 years ago

Let me try to summarize all my tests:

All of the above seems correct right, that's what we expect from them. However, in any of the cases above, the final response received by the browser is a 500 Internal Server Error And the only way to have a valid response (i.e. not the 500 error, with a big request body without files), is to disable the plugin

igoooor commented 2 years ago

Have you been able to reproduce it by chance?

bitsofinfo commented 2 years ago

any updates on this?

Enrico204 commented 2 years ago

I might be encountering this issue in prod. Maybe it's better to write some test and try to trigger this error using docker-compose, or any other method that is reproducible

bitsofinfo commented 2 years ago

definiately need this support as well

Enrico204 commented 2 years ago

Have you been able to reproduce it by chance?

I'm trying but I can't reproduce.

Can you share your traefik configuration? Something that we can reproduce? (docker-compose / kubernetes)

igoooor commented 2 years ago

I removed everything which is not relevant for the problem, so that you can directly see the relevant configuration:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: traefik
spec:
  template:
    spec:
      containers:
      - args:
        - --experimental.plugins.traefik-modsecurity-plugin.modulename=github.com/acouvreur/traefik-modsecurity-plugin
        - --experimental.plugins.traefik-modsecurity-plugin.version=v1.2.1
        - --entrypoints.web.Address=:80
        - --entrypoints.websecure.Address=:443
        - --entrypoints.websecure.forwardedHeaders.insecure=true
        - --providers.kubernetescrd
        - --providers.kubernetescrd.allowExternalNameServices=true
        - --providers.kubernetescrd.allowCrossNamespace=true
        - --providers.kubernetesingress=true
        - --providers.kubernetesingress.allowExternalNameServices=true
        - --providers.kubernetesingress.ingressclass=traefik-cert-manager
        image: traefik:v2.8
        imagePullPolicy: Always
        name: traefik
        ports:
        - containerPort: 80
          name: web
          protocol: TCP
        - containerPort: 443
          name: websecure
          protocol: TCP
        - containerPort: 8080
          name: admin
          protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
  name: traefik
spec:
  ports:
  - name: web
    nodePort: 31893
    port: 80
    protocol: TCP
    targetPort: 80
  - name: websecure
    nodePort: 30746
    port: 443
    protocol: TCP
    targetPort: 443
  - name: admin
    nodePort: 30997
    port: 8080
    protocol: TCP
    targetPort: 8080
  type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: owasp-modsec
spec:
    spec:
      containers:
      - env:
        - name: PARANOIA
          value: "1"
        - name: ANOMALY_INBOUND
          value: "5"
        - name: ANOMALY_OUTBOUND
          value: "5"
        - name: BACKEND
          value: http://dummy-owasp:80
        - name: MAX_FILE_SIZE
          value: "26214400"
        - name: COMBINED_FILE_SIZES
          value: "26214400"
        - name: MODSEC_REQ_BODY_LIMIT
          value: "26214400"
        - name: MODSEC_REQ_BODY_NOFILES_LIMIT
          value: "26214400"
        - name: MODSEC_RESP_BODY_LIMIT
          value: "26214400"
        image: owasp/modsecurity-crs:apache-alpine
        ports:
        - containerPort: 80
          name: http
          protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
  name: owasp-modsec
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: http
  type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dummy-owasp
spec:
  template:
    spec:
      containers:
      - image: nginx:1.21
        name: dummy-owasp
        ports:
        - containerPort: 8000
          name: http
          protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
  name: dummy-owasp
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: http
  type: ClusterIP
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: md-owasp-modsec
spec:
  plugin:
    traefik-modsecurity-plugin:
      maxBodySize: 26214400
      modSecurityUrl: http://owasp-modsec
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: example.com
spec:
  entryPoints:
  - websecure
  routes:
  - kind: Rule
    match: Host(`example.com`) && PathPrefix(`/`)
    middlewares:
    - name: md-owasp-modsec
    services:
    - name: application-frontend-nginx
      port: 8000

Please note that POSTing a file bigger than maxBodySize works perfectly fine. The problem comes when POSTing a request without file, but the size of that request is greater than maxBodySize (so for example POSTing a textarea with enough characters to be above maxBodySize (or a base64 encoded image for example)