Skip to content

Commit 5d67792

Browse files
authored
waf: document APPSEC_DROP_UNREADABLE_BODY for nginx/openresty (#1078)
1 parent b592e21 commit 5d67792

2 files changed

Lines changed: 156 additions & 68 deletions

File tree

crowdsec-docs/unversioned/bouncers/nginx.mdx

Lines changed: 67 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ sidebar_position: 1
77
import Tabs from "@theme/Tabs";
88
import TabItem from "@theme/TabItem";
99
import useBaseUrl from "@docusaurus/useBaseUrl";
10-
import RemediationSupportBadges from '@site/src/components/remediation-support-badge';
10+
import RemediationSupportBadges from "@site/src/components/remediation-support-badge";
1111

1212
<p align="center">
1313
<img
@@ -28,12 +28,7 @@ import RemediationSupportBadges from '@site/src/components/remediation-support-b
2828
&#128172; <a href="https://discourse.crowdsec.net">Discourse </a>
2929
</p>
3030

31-
<RemediationSupportBadges
32-
Mode
33-
Appsec
34-
Metrics
35-
MTLS
36-
/>
31+
<RemediationSupportBadges Mode Appsec Metrics MTLS />
3732

3833
A lua Remediation Component for nginx.
3934

@@ -210,11 +205,12 @@ TLS_CLIENT_KEY=
210205
## Application Security Component Configuration
211206
APPSEC_URL=
212207
#### default ###
213-
APPSEC_FAILURE_ACTION=passthrough
214-
APPSEC_CONNECT_TIMEOUT=100
215-
APPSEC_SEND_TIMEOUT=100
216-
APPSEC_PROCESS_TIMEOUT=1000
217-
ALWAYS_SEND_TO_APPSEC=false
208+
APPSEC_FAILURE_ACTION=passthrough
209+
APPSEC_CONNECT_TIMEOUT=100
210+
APPSEC_SEND_TIMEOUT=100
211+
APPSEC_PROCESS_TIMEOUT=1000
212+
ALWAYS_SEND_TO_APPSEC=false
213+
APPSEC_DROP_UNREADABLE_BODY=false
218214
SSL_VERIFY=true
219215
################
220216
```
@@ -308,9 +304,17 @@ APPSEC_CONNECT_TIMEOUT=100 # default
308304
APPSEC_SEND_TIMEOUT=100 # default
309305
APPSEC_PROCESS_TIMEOUT=1000 # default
310306
ALWAYS_SEND_TO_APPSEC=false # default
307+
APPSEC_DROP_UNREADABLE_BODY=false # default
311308
SSL_VERIFY=true # default
312309
```
313310
311+
:::warning
312+
313+
Due to limitations in the underlying library used by the remediation component, by default, the body of any HTTP2/HTTP3 request without a Content-Length will not be analyzed.
314+
To avoid potential bypasses of the WAF, you can set the option `APPSEC_DROP_UNREADABLE_BODY` to `true` to drop any request whose body cannot be inspected.
315+
316+
:::
317+
314318
### Setup captcha
315319
316320
> Currently, we have support for 3 providers: recaptcha, hcaptcha or turnstile
@@ -357,6 +361,7 @@ Here is a config example, but you can change values:
357361
resolver 8.8.8.8 ipv6=off;
358362
lua_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
359363
```
364+
360365
And restart Nginx.
361366
362367
### Ubuntu 22.xx getting lua error
@@ -371,7 +376,8 @@ You have a few options to resolve this issue:
371376
The `lua` module is included again in newer Ubuntu releases.
372377
373378
- **Use OpenResty instead of NGINX**
374-
OpenResty is a drop-in replacement for NGINX that includes the `lua` module by default.
379+
OpenResty is a drop-in replacement for NGINX that includes the `lua` module by default.
380+
375381
> Note: OpenResty uses slightly different service names and paths, but configuration remains compatible with standard NGINX.
376382
377383
- **Manually compile the lua module**
@@ -380,6 +386,7 @@ You have a few options to resolve this issue:
380386
## Configuration Reference
381387
382388
### `API_KEY`
389+
383390
> string
384391
385392
```bash
@@ -391,6 +398,7 @@ CrowdSec Local API key.
391398
Generated with [`sudo cscli bouncers add`](/u/getting_started/installation/linux) command.
392399
393400
### `API_URL`
401+
394402
> string
395403
396404
```bash
@@ -430,6 +438,7 @@ TLS_CLIENT_KEY=<path_to_key>
430438
Path to the client certificate's private key file for mTLS authentication. This option is only used when `USE_TLS_AUTH` is set to `true`.
431439
432440
### `BOUNCING_ON_TYPE`
441+
433442
> all | ban | captcha
434443
435444
```bash
@@ -440,6 +449,7 @@ Type of remediation we want to bounce.
440449
If you choose `ban` only and receive a decision with `captcha` as remediation, the component will skip the decision.
441450
442451
### `FALLBACK_REMEDIATION`
452+
443453
> ban | captcha
444454
445455
```bash
@@ -449,6 +459,7 @@ FALLBACK_REMEDIATION=ban
449459
The fallback remediation is applied if the component receives a decision with an unknown remediation.
450460
451461
### `MODE`
462+
452463
> stream | live
453464
454465
```bash
@@ -458,14 +469,16 @@ MODE=stream
458469
The default mode is `live`.
459470
460471
The component mode:
461-
- stream: The component will pull new/old decisions from the local API every X seconds (`UPDATE_FREQUENCY` parameter).
462-
- live: The component will query the local API for each requests (if IP is not in cache) and will store the IP in cache for X seconds (`CACHE_EXPIRATION` parameter).
472+
473+
- stream: The component will pull new/old decisions from the local API every X seconds (`UPDATE_FREQUENCY` parameter).
474+
- live: The component will query the local API for each requests (if IP is not in cache) and will store the IP in cache for X seconds (`CACHE_EXPIRATION` parameter).
463475
464476
:::note
465477
The timer that pull the local API will be triggered after the first request.
466478
:::
467479
468480
### `REQUEST_TIMEOUT`
481+
469482
> int
470483
471484
```bash
@@ -475,6 +488,7 @@ REQUEST_TIMEOUT=1000
475488
Timeout in milliseconds for the HTTP requests done by the component to query CrowdSec local API or captcha provider (for the captcha verification).
476489
477490
### `EXCLUDE_LOCATION`
491+
478492
> string (comma separated)
479493
480494
```bash
@@ -486,6 +500,7 @@ The locations to exclude while bouncing. It is a list of location, separated by
486500
:warning: It is not recommended to put `EXCLUDE_LOCATION=/`.
487501
488502
### `ENABLE_INTERNAL`
503+
489504
> bool
490505
491506
```bash
@@ -496,8 +511,8 @@ Whether to process internal requests or not (after a rewrite for example).
496511
497512
Disabled by default.
498513
499-
500514
### `CACHE_EXPIRATION`
515+
501516
> int
502517
503518
> This option is only for the `live` mode.
@@ -509,6 +524,7 @@ CACHE_EXPIRATION=1
509524
The cache expiration, in second, for IPs that the remediation store in cache in `live` mode.
510525
511526
### `UPDATE_FREQUENCY`
527+
512528
> int
513529
514530
> This option is only for the `stream` mode.
@@ -520,6 +536,7 @@ UPDATE_FREQUENCY=10
520536
The frequency of update, in second, to pull new/old IPs from the CrowdSec local API.
521537
522538
### `REDIRECT_LOCATION`
539+
523540
> string
524541
525542
> This option is only for the `ban` remediation.
@@ -533,6 +550,7 @@ The location to redirect the user when there is a ban.
533550
If it is not set, the component will return the page defined in the `BAN_TEMPLATE_PATH` with the `RET_CODE` (403 by default).
534551
535552
### `BAN_TEMPLATE_PATH`
553+
536554
> string (path to file)
537555
538556
> This option is only for the `ban` remediation.
@@ -546,6 +564,7 @@ The path to a HTML page to return to IPs that trigger `ban` remediation.
546564
By default, the HTML template is located in `/var/lib/crowdsec/lua/templates/ban.html`.
547565
548566
### `RET_CODE`
567+
549568
> int
550569
551570
> This option is only for the `ban` remediation.
@@ -558,6 +577,7 @@ The HTTP code to return for IPs that trigger a `ban` remediation.
558577
If nothing specified, it will return a 403.
559578
560579
### `CAPTCHA_PROVIDER`
580+
561581
> recaptcha | hcaptcha | turnstile
562582
563583
> This option is only for the `captcha` remediation.
@@ -571,6 +591,7 @@ For backwards compatibility reasons `recaptcha` is the default if no value is se
571591
:::
572592
573593
### `SECRET_KEY`
594+
574595
> string
575596
576597
> This option is only for the `captcha` remediation.
@@ -582,6 +603,7 @@ SECRET_KEY=<captcha_secret_key>
582603
The captcha secret key.
583604
584605
### `SITE_KEY`
606+
585607
> string
586608
587609
> This option is only for the `captcha` remediation.
@@ -593,6 +615,7 @@ SITE_KEY=<captcha_site_key>
593615
The captcha site key.
594616
595617
### `CAPTCHA_TEMPLATE_PATH`
618+
596619
> string (path to file)
597620
598621
> This option is only for the `captcha` remediation.
@@ -608,6 +631,7 @@ The component will try to replace `{{captcha_site_key}}` in the template with `S
608631
By default, the HTML template is located in `/var/lib/crowdsec/lua/templates/captcha.html`.
609632
610633
### `CAPTCHA_EXPIRATION`
634+
611635
> int
612636
613637
> This option is only for the `captcha` remediation.
@@ -619,6 +643,7 @@ CAPTCHA_EXPIRATION=3600
619643
The time for which the captcha will be validated. After this duration, if the decision is still present in CrowdSec local API, the IPs address will get a captcha again.
620644
621645
### `CAPTCHA_RET_CODE`
646+
622647
> int
623648
624649
> This option is only for the `captcha` remediation.
@@ -630,6 +655,7 @@ CAPTCHA_RET_CODE=200
630655
Specifies the HTTP status code that should be returned to the client when a CAPTCHA challenge is required. This is especially useful when your traffic is routed through a CDN (like Cloudflare), where you may want to avoid triggering caching based on non-200 status codes. By default if no value is provided it will use 200 status code.
631656
632657
### `APPSEC_URL`
658+
633659
> string
634660
635661
> URL of the Application Security Component
@@ -639,6 +665,7 @@ APPSEC_URL=http://127.0.0.1:7422
639665
```
640666
641667
### `APPSEC_FAILURE_ACTION`
668+
642669
> passthrough | deny
643670
644671
```bash
@@ -648,6 +675,7 @@ APPSEC_FAILURE_ACTION=passthrough # default
648675
Behavior when the AppSec Component return a 500. Can let the request passthrough or deny it.
649676
650677
### `ALWAYS_SEND_TO_APPSEC`
678+
651679
> boolean
652680
653681
```bash
@@ -657,6 +685,7 @@ ALWAYS_SEND_TO_APPSEC=false # default
657685
Send the request to the AppSec Component even if there is a decision for the IP.
658686
659687
### `SSL_VERIFY`
688+
660689
> boolean
661690
662691
```bash
@@ -666,6 +695,7 @@ SSL_VERIFY=false # default
666695
Verify the AppSec Component SSL certificate validity.
667696
668697
### `APPSEC_CONNECT_TIMEOUT`
698+
669699
> int (milliseconds)
670700
671701
```bash
@@ -674,8 +704,8 @@ APPSEC_CONNECT_TIMEOUT=100 # default
674704
675705
The timeout of the connection between the Remediation Component and AppSec Component.
676706
677-
678707
### `APPSEC_SEND_TIMEOUT`
708+
679709
> int (milliseconds)
680710
681711
```bash
@@ -685,6 +715,7 @@ APPSEC_SEND_TIMEOUT=100 # default
685715
The timeout to send data from the Remediation Component to the AppSec Component.
686716
687717
### `APPSEC_PROCESS_TIMEOUT`
718+
688719
> int (milliseconds)
689720
690721
```bash
@@ -693,17 +724,30 @@ APPSEC_PROCESS_TIMEOUT=500 # default
693724
694725
The timeout to process the request from the Remediation Component to the AppSec Component.
695726
727+
### `APPSEC_DROP_UNREADABLE_BODY`
728+
729+
> bool
730+
731+
```bash
732+
APPSEC_DROP_UNREADABLE_BODY=false #default
733+
```
734+
735+
If the bouncer cannot read the request body (eg, HTTP2 without Content-Length header), drop or not the request without forwarding it to the WAF.
736+
737+
If set to `false` (the default), the request will be evaluated by the WAF without the body content.
738+
If set to `true`, the request will be blocked directly by nginx.
739+
696740
### Nginx variables
697741
698742
Nginx variables can be used to adapt behaviour and or more flexible configurations:
699-
* `ngx.var.crowdsec_disable_bouncer`: set to 1, it will disable the bouncer
700-
* `ngx.var.crowdsec_enable_bouncer`: set to 1, it will disable the bouncer
701-
* `ngx.var.crowdsec_enable_appsec`: set to 1, it will enable the appsec even if it's disabled by configuration or if bouncer is disabled
702-
* `ngx.var.crowdsec_disable_appsec`: set to 1, it will disable the appsec
703-
* `ngx.var.crowdsec_always_send_to_appsec`: set 1, it will always send the request to appsec, even if a decision already exist for the ip requesting
743+
744+
- `ngx.var.crowdsec_disable_bouncer`: set to 1, it will disable the bouncer
745+
- `ngx.var.crowdsec_enable_bouncer`: set to 1, it will disable the bouncer
746+
- `ngx.var.crowdsec_enable_appsec`: set to 1, it will enable the appsec even if it's disabled by configuration or if bouncer is disabled
747+
- `ngx.var.crowdsec_disable_appsec`: set to 1, it will disable the appsec
748+
- `ngx.var.crowdsec_always_send_to_appsec`: set 1, it will always send the request to appsec, even if a decision already exist for the ip requesting
704749
705750
If both `ngx.var.crowdsec_disable_bouncer` and
706751
`ngx.var.crowdsec_enable_bouncer`, or both `ngx.var.crowdsec_disable_appsec` and
707752
`ngx.var.crowdsec_enable_appsec` are set to 1, it's the disable configuration
708753
that prevails.
709-

0 commit comments

Comments
 (0)