|
| 1 | +--- |
| 2 | +id: wordpress |
| 3 | +title: WordPress |
| 4 | +--- |
| 5 | + |
| 6 | +import Tabs from '@theme/Tabs'; |
| 7 | +import TabItem from '@theme/TabItem'; |
| 8 | +import CodeBlock from '@theme/CodeBlock'; |
| 9 | +import UnderlineTooltip from '@site/src/components/underline-tooltip'; |
| 10 | + |
| 11 | +# CrowdSec WAF QuickStart for WordPress |
| 12 | + |
| 13 | +## Objectives |
| 14 | + |
| 15 | +The goal of this quickstart is to set up the [AppSec Component](/appsec/intro.md#introduction) to safeguard web applications running on [WordPress](https://wordpress.org) sites. |
| 16 | + |
| 17 | +We'll deploy a [set of rules](https://app.crowdsec.net/hub/author/crowdsecurity/collections/appsec-virtual-patching) designed to block [well-known attacks](https://app.crowdsec.net/hub/author/crowdsecurity/collections/appsec-generic-rules) and [currently exploited vulnerabilities](https://app.crowdsec.net/hub/author/crowdsecurity/collections/appsec-virtual-patching). |
| 18 | + |
| 19 | +Additionally, we'll show how to monitor these alerts through the [console](https://app.crowdsec.net/). |
| 20 | + |
| 21 | +## Pre-requisites |
| 22 | + |
| 23 | +1. If you're new to the [AppSec Component](/appsec/intro.md#introduction) or **W**eb **A**pplication **F**irewalls, start with the [Introduction](/appsec/intro.md#introduction) for a better understanding. |
| 24 | + |
| 25 | +2. It's assumed that you have already installed: |
| 26 | + - **CrowdSec [Security Engine](intro.mdx)**: for installation, refer to the [QuickStart guide](/u/getting_started/installation/linux). The AppSec Component, which analyzes HTTP requests, is included within the security engine as a [Acquisition](/log_processor/data_sources/appsec.md). |
| 27 | + - **WordPress [Remediation Component](/u/bouncers/intro)**: installation instructions are available in the [WordPress bouncer guide](/u/bouncers/wordpress). The CrowdSec WordPress plugin enables you to protect your WordPress site against malicious traffic using CrowdSec's advanced threat detection and blocklist capabilities. |
| 28 | + |
| 29 | + This component intercepts HTTP requests at the WordPress level and forwards them to the AppSec Component for analysis and action. |
| 30 | + |
| 31 | + |
| 32 | +## AppSec Component Setup |
| 33 | + |
| 34 | +### Collection installation |
| 35 | + |
| 36 | +To begin setting up the AppSec Component, the initial step is to install a relevant set of rules. |
| 37 | + |
| 38 | +We will utilize the [`crowdsecurity/appsec-virtual-patching`](https://app.crowdsec.net/hub/author/crowdsecurity/collections/appsec-virtual-patching) collection, which offers a wide range of rules aimed at identifying and preventing the exploitation of known vulnerabilities. |
| 39 | + |
| 40 | +This <UnderlineTooltip tooltip="Collections are bundle of parsers, scenarios, postoverflows that form a coherent package.">collection</UnderlineTooltip> is regularly updated to include protection against newly discovered vulnerabilities. Upon installation, it receives automatic daily updates to ensure your protection is always current. |
| 41 | +Furthermore we also install the [`crowdsecurity/appsec-generic-rules`](https://app.crowdsec.net/hub/author/crowdsecurity/collections/appsec-generic-rules) collection. This collection contains detection scenarios for generic attack vectors. It provides some protection in cases where specific scenarios for vulnerabilities do not exist (yet). |
| 42 | + |
| 43 | +On the machine where the Security Engine is installed, just execute the following command: |
| 44 | + |
| 45 | +:::info |
| 46 | +You can always view the content of a [collection on the hub](https://app.crowdsec.net/hub/author/crowdsecurity/collections/appsec-virtual-patching) |
| 47 | +::: |
| 48 | + |
| 49 | +```bash |
| 50 | +sudo cscli collections install crowdsecurity/appsec-virtual-patching crowdsecurity/appsec-generic-rules |
| 51 | +``` |
| 52 | + |
| 53 | +Executing this command will install the following items: |
| 54 | + |
| 55 | +- The [*AppSec Rules*](/appsec/rules_syntax.md) contain the definition of malevolent requests to be matched and stopped |
| 56 | +- The [*AppSec Configuration*](/appsec/configuration.md#appsec-configuration) links together a set of rules to provide a coherent set |
| 57 | +- The <UnderlineTooltip tooltip="YAML files that extract relevant data from logs, such as IP addresses, timestamps, or request paths.">CrowdSec Parser</UnderlineTooltip> and <UnderlineTooltip tooltip="Behavioral rules written in a domain-specific language that define what malicious activity looks like, such as multiple failed logins in a short time.">CrowdSec Scenario(s)</UnderlineTooltip> bans for a longer duration repeating offenders |
| 58 | + |
| 59 | +### Setup the Acquisition |
| 60 | + |
| 61 | +Having installed the required components, it's time to configure the CrowdSec <UnderlineTooltip tooltip="Acquisition files tell CrowdSec where to find logs and which application they belong to.">Acquisition</UnderlineTooltip> to expose the Application Security Component to our WordPress site. This configuration allows our WordPress site to send requests to the AppSec Component for evaluation and decision-making. |
| 62 | + |
| 63 | +Steps: |
| 64 | + 1. Create the `/etc/crowdsec/acquis.d/` directory (if it doesn't exist on your machine) |
| 65 | + ```bash |
| 66 | + mkdir -p /etc/crowdsec/acquis.d/ |
| 67 | + ``` |
| 68 | + 2. Create a file `/etc/crowdsec/acquis.d/appsec.yaml` with the following content: |
| 69 | + ```yaml title="/etc/crowdsec/acquis.d/appsec.yaml" |
| 70 | + appsec_config: crowdsecurity/appsec-default |
| 71 | + labels: |
| 72 | + type: appsec |
| 73 | + listen_addr: 127.0.0.1:7422 |
| 74 | + source: appsec |
| 75 | + ``` |
| 76 | + |
| 77 | +The two important directives in this configuration file are: |
| 78 | + |
| 79 | + - `appsec_config` is the name of the [*AppSec Configuration*](appsec/configuration.md#appsec-configuration) that was included in the <UnderlineTooltip tooltip="Collections are bundle of parsers, scenarios, postoverflows that form a coherent package.">Collection</UnderlineTooltip> we just installed. |
| 80 | + - the `listen_addr` is the IP and port the AppSec Component will listen to. |
| 81 | + |
| 82 | +:::warning |
| 83 | +We do not recommend exposing the AppSec Component to the internet. It should only be accessible from the web server or WordPress application. |
| 84 | +::: |
| 85 | + |
| 86 | +:::info |
| 87 | +You can find more about the [supported options for the acquisition here](/log_processor/data_sources/appsec.md) |
| 88 | +::: |
| 89 | + |
| 90 | +You can now restart CrowdSec: |
| 91 | + |
| 92 | +```bash |
| 93 | +sudo systemctl restart crowdsec |
| 94 | +``` |
| 95 | + |
| 96 | +#### Testing the AppSec Component |
| 97 | + |
| 98 | +##### Verify the AppSec Component is listening |
| 99 | + |
| 100 | +To verify that the AppSec Component is running correctly, we can first check that the port `7422` is open and listening: |
| 101 | + |
| 102 | +:::note |
| 103 | +If you have changed the port in the configuration file, replace `7422` with the new port number. |
| 104 | +::: |
| 105 | + |
| 106 | +<Tabs |
| 107 | + defaultValue="netstat" |
| 108 | + groupId="listening-ports" |
| 109 | + values={[ |
| 110 | + {label: 'Netstat', value: 'netstat'}, |
| 111 | + {label: 'SS', value: 'ss'}, |
| 112 | + ]}> |
| 113 | + |
| 114 | + <TabItem value="netstat"> |
| 115 | + <CodeBlock className="language-bash">sudo netstat -tlpn | grep 7422</CodeBlock> |
| 116 | + </TabItem> |
| 117 | + |
| 118 | + <TabItem value="ss"> |
| 119 | + <CodeBlock className="language-bash">sudo ss -tlpn | grep 7422</CodeBlock> |
| 120 | + </TabItem> |
| 121 | +</Tabs> |
| 122 | + |
| 123 | +<details> |
| 124 | + |
| 125 | +<summary>Output example</summary> |
| 126 | + |
| 127 | +```bash |
| 128 | +tcp 0 0 127.0.0.1:7422 0.0.0.0:* LISTEN 12345/crowdsec |
| 129 | +``` |
| 130 | + |
| 131 | +:::note |
| 132 | +The output may look differently depending on which command you used but as long as you see the port and the process `crowdsec`, it means the AppSec Component is running. |
| 133 | +::: |
| 134 | + |
| 135 | +</details> |
| 136 | + |
| 137 | +##### (Optional) Manually testing the AppSec Component with `curl` |
| 138 | + |
| 139 | +<details> |
| 140 | + <summary>Expand for short guide</summary> |
| 141 | + |
| 142 | +Before we proceed with configuring the Remediation Component, let's verify that all our current setups are functioning correctly. |
| 143 | + |
| 144 | +1. Create a Remediation Component (Bouncer) API Key: |
| 145 | + |
| 146 | +```bash |
| 147 | +sudo cscli bouncers add test_waf -k this_is_a_bad_password |
| 148 | +API key for 'test_waf': |
| 149 | + |
| 150 | + this_is_a_bad_password |
| 151 | + |
| 152 | +Please keep this key since you will not be able to retrieve it! |
| 153 | +``` |
| 154 | + |
| 155 | +2. Emit a legitimate request to the AppSec Component: |
| 156 | + |
| 157 | +```bash |
| 158 | +curl -X POST localhost:7422/ -i -H 'x-crowdsec-appsec-uri: /test' -H 'x-crowdsec-appsec-ip: 192.168.1.1' -H 'x-crowdsec-appsec-host: foobar.com' -H 'x-crowdsec-appsec-verb: POST' -H 'x-crowdsec-appsec-api-key: this_is_a_bad_password' |
| 159 | +``` |
| 160 | + |
| 161 | +Which will give us an answer such as: |
| 162 | + |
| 163 | +```bash |
| 164 | +HTTP/1.1 200 OK |
| 165 | +Date: Tue, 30 Jan 2024 15:43:50 GMT |
| 166 | +Content-Length: 36 |
| 167 | +Content-Type: text/plain; charset=utf-8 |
| 168 | + |
| 169 | +{"action":"allow","http_status":200} |
| 170 | +``` |
| 171 | + |
| 172 | +3. Emit a malevolent request to the Appsec Component: |
| 173 | + |
| 174 | +:::info |
| 175 | +We're trying to access a `.env` file, a [common way to get access to some credentials forgotten by a developer.](https://app.crowdsec.net/hub/author/crowdsecurity/appsec-rules/vpatch-env-access) |
| 176 | +::: |
| 177 | + |
| 178 | +```bash |
| 179 | +curl -X POST localhost:7422/ -i -H 'x-crowdsec-appsec-uri: /.env' -H 'x-crowdsec-appsec-ip: 192.168.1.1' -H 'x-crowdsec-appsec-host: foobar.com' -H 'x-crowdsec-appsec-verb: POST' -H 'x-crowdsec-appsec-api-key: this_is_a_bad_password' |
| 180 | + |
| 181 | +``` |
| 182 | + |
| 183 | +Our request is detected and blocked by the AppSec Component: |
| 184 | + |
| 185 | +```bash |
| 186 | +HTTP/1.1 403 Forbidden |
| 187 | +Date: Tue, 30 Jan 2024 15:57:08 GMT |
| 188 | +Content-Length: 34 |
| 189 | +Content-Type: text/plain; charset=utf-8 |
| 190 | + |
| 191 | +{"action":"ban","http_status":403} |
| 192 | +``` |
| 193 | + |
| 194 | +Let's now delete our test API Key: |
| 195 | + |
| 196 | +```bash |
| 197 | +sudo cscli bouncers delete test_waf |
| 198 | +``` |
| 199 | + |
| 200 | +</details> |
| 201 | + |
| 202 | +## Remediation Component Setup |
| 203 | + |
| 204 | +Since our AppSec Component is active and listening, we can now configure the WordPress Remediation Component to forward requests to it. |
| 205 | + |
| 206 | +The WordPress bouncer includes built-in AppSec support that can be enabled through the plugin's admin interface. |
| 207 | + |
| 208 | +### Enable AppSec in WordPress Plugin |
| 209 | + |
| 210 | +1. Log in to your WordPress admin panel |
| 211 | +2. Navigate to the CrowdSec plugin settings (`CrowdSec` in your admin menu) |
| 212 | +3. Go to the `Advanced` section |
| 213 | +4. Find the `AppSec component` configuration section |
| 214 | +5. Enable AppSec and configure the connection: |
| 215 | + |
| 216 | + - **Enable AppSec**: Check this box to enable AppSec functionality |
| 217 | + - **URL**: Set to `http://127.0.0.1:7422` (or your custom AppSec Component address) |
| 218 | + - **Request timeout**: Default is 400 milliseconds (adjust as needed) |
| 219 | + - **Fallback to**: Choose `captcha` (recommended) for when AppSec calls fail |
| 220 | + - **Maximum body size**: Default is 1024 KB |
| 221 | + - **Body size exceeded action**: Choose `headers_only` (recommended) |
| 222 | + |
| 223 | + |
| 224 | + |
| 225 | + |
| 226 | +:::info |
| 227 | +AppSec functionality is only available when using API key authentication (not TLS certificates) in the WordPress plugin. |
| 228 | +::: |
| 229 | + |
| 230 | +:::note |
| 231 | +The AppSec Component will only be consulted when the initial LAPI remediation returns a bypass decision. |
| 232 | +::: |
| 233 | + |
| 234 | +## Testing the AppSec Component + Remediation Component |
| 235 | + |
| 236 | +:::note |
| 237 | +We're assuming WordPress is running on your local machine. Please adjust your testing accordingly if this is not the case. |
| 238 | +::: |
| 239 | + |
| 240 | +To test the AppSec functionality, you need to make a request that will go through the WordPress loading process. Try accessing a WordPress page with a malicious payload in the URL parameters or body. |
| 241 | +For example, we can try to post a request with a body that contains a malicious payload, known as a [Remote Code Execution (CVE-2022-22965)](https://app.crowdsec.net/hub/author/crowdsecurity/appsec-rules/vpatch-CVE-2022-22965) attempt. |
| 242 | + |
| 243 | +```bash |
| 244 | +curl -X POST https://<your-wordpress-uri>/ -d "class.module.classLoader.resources." -o /dev/null -s -w "%{http_code}" |
| 245 | +``` |
| 246 | + |
| 247 | + |
| 248 | +When the AppSec Component detects such a malicious request, you'll see that the response is a 403 (Forbidden) status code, indicating that the request was blocked. |
| 249 | + |
| 250 | +If your test is not successful, please refer to the [Health check and troubleshoot guide](/u/getting_started/health_check/) for help. |
| 251 | + |
| 252 | + |
| 253 | +You can also look at the metrics from `cscli metrics show appsec` which will display: |
| 254 | + - the number of requests processed by the AppSec Component |
| 255 | + - Individual rule matches |
| 256 | + |
| 257 | + <details> |
| 258 | + <summary>Example Output</summary> |
| 259 | + |
| 260 | + |
| 261 | +```bash title="sudo cscli metrics show appsec" |
| 262 | +Appsec Metrics: |
| 263 | +╭─────────────────┬───────────┬─────────╮ |
| 264 | +│ Appsec Engine │ Processed │ Blocked │ |
| 265 | +├─────────────────┼───────────┼─────────┤ |
| 266 | +│ 127.0.0.1:7422/ │ 2 │ 1 │ |
| 267 | +╰─────────────────┴───────────┴─────────╯ |
| 268 | + |
| 269 | +Appsec '127.0.0.1:7422/' Rules Metrics: |
| 270 | +╭─────────────────────────────────────┬───────────╮ |
| 271 | +│ Rule ID │ Triggered │ |
| 272 | +├─────────────────────────────────────┼───────────┤ |
| 273 | +│ crowdsecurity/vpatch-CVE-2022-22965 │ 1 │ |
| 274 | +╰─────────────────────────────────────┴───────────╯ |
| 275 | +``` |
| 276 | + |
| 277 | +</details> |
| 278 | + |
| 279 | +### Explanation |
| 280 | + |
| 281 | +What happened in the test that we just did is: |
| 282 | + |
| 283 | + 1. We made a request with malicious payload to our WordPress site |
| 284 | + 2. The WordPress bouncer plugin intercepted the request as part of the WordPress loading process |
| 285 | + 3. The bouncer first checked with the local CrowdSec API for any existing decisions |
| 286 | + 4. Since there was no existing ban decision, the bouncer forwarded the request to the AppSec Component at `http://127.0.0.1:7422` |
| 287 | + 5. Our AppSec Component analyzed the request and matched it against the appropriate AppSec rules (here `crowdsecurity/vpatch-CVE-2022-22965` rule) |
| 288 | + 6. The AppSec Component returned an HTTP 403 response to the WordPress bouncer, indicating that the request must be blocked |
| 289 | + 7. The WordPress bouncer then presented the visitor with the configured ban page |
| 290 | + |
| 291 | + ## Integration with the console |
| 292 | + |
| 293 | +If you haven't yet, follow the guide about [how to enroll your Security Engine in the console](/u/getting_started/post_installation/console). |
| 294 | + |
| 295 | +Once done, all your alerts, including the ones generated by the AppSec Component, are going to appear in the console: |
| 296 | + |
| 297 | + |
| 298 | + |
| 299 | +## WordPress-Specific Considerations |
| 300 | + |
| 301 | +### Understanding Plugin Limitations |
| 302 | + |
| 303 | +The WordPress bouncer has some inherent limitations you should be aware of: |
| 304 | + |
| 305 | +1. **WordPress Loading Process**: The plugin only protects requests that go through the WordPress core loading process. Direct access to PHP files outside of WordPress won't be protected. |
| 306 | + |
| 307 | +2. **Static Files**: Requests for non-PHP files (like `.env`, `.sql`, or other static files) won't be processed by the plugin since they don't go through PHP. |
| 308 | + |
| 309 | +3. **Auto Prepend File Mode**: For comprehensive protection, consider enabling [auto prepend file mode](/u/bouncers/wordpress#auto-prepend-file-mode) in the plugin settings to ensure all PHP scripts are protected. |
| 310 | + |
| 311 | + |
| 312 | +## Next steps |
| 313 | + |
| 314 | +You are now running the AppSec Component on your WordPress site with CrowdSec Security Engine, congrats! |
| 315 | + |
| 316 | +As the next steps, you can: |
| 317 | + - [Explore the hub](https://hub.crowdsec.net) to find more rules for your use case |
| 318 | + - Look at the [Rules syntax](/appsec/rules_syntax.md) and [creation process](/appsec/create_rules.md) to create your own and contribute |
0 commit comments