traefik-modsecurity-plugin icon indicating copy to clipboard operation
traefik-modsecurity-plugin copied to clipboard

500 error for big request body without files

Open igoooor opened this issue 3 years ago • 9 comments

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

igoooor avatar Aug 09 '22 13:08 igoooor

I also tried version 1.1.0 with the same result

Interesting!

Do you have any logging from any container?

acouvreur avatar Aug 09 '22 21:08 acouvreur

No not yet, I will enable logs and check again

igoooor avatar Aug 10 '22 07:08 igoooor

Let me try to summarize all my tests:

  • OWASP container seems to properly handle the request because if request body size is greater than MODSEC_REQ_BODY_NOFILES_LIMIT then the container shows the rule violation, i.e. it does not have issue handling big request
  • if request body size is greater than the plugin maxBodySize traefik container logs show 2022/08/10 09:02:04 body max limit reached: http: request body too large, else the logs does not show anything

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 avatar Aug 10 '22 09:08 igoooor

Have you been able to reproduce it by chance?

igoooor avatar Aug 29 '22 07:08 igoooor

any updates on this?

bitsofinfo avatar Sep 02 '22 15:09 bitsofinfo

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

Enrico204 avatar Sep 04 '22 20:09 Enrico204

definiately need this support as well

bitsofinfo avatar Sep 07 '22 14:09 bitsofinfo

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)

Enrico204 avatar Sep 07 '22 15:09 Enrico204

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)

igoooor avatar Sep 26 '22 15:09 igoooor