Skip to content

feat(blaas): Add subscribe button #167

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jun 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .wordpress-org/screenshot-11.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 12 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

---

## [2.11.0](https://github.com/crowdsecurity/cs-wordpress-bouncer/releases/tag/v2.11.0) - 2025-06-02
[_Compare with previous release_](https://github.com/crowdsecurity/cs-wordpress-bouncer/compare/v2.10.0...v2.11.0)


### Added

- Add Blocklist as a Service (BLaaS) subscription button


---

## [2.10.0](https://github.com/crowdsecurity/cs-wordpress-bouncer/releases/tag/v2.10.0) - 2025-05-09
Expand Down Expand Up @@ -312,7 +323,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[_Compare with previous release_](https://github.com/crowdsecurity/cs-wordpress-bouncer/compare/v1.11.0...v2.0.0)

### Changed
- All source code has been refactored using new CrowdSec PHP librairies:
- All source code has been refactored using new CrowdSec PHP libraries:
- Logs messages have been changed
- User Agent sent to CrowdSec LAPI has been changed to `csphplapi_WordPress/vX.Y.Z`

Expand Down
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*

- [CrowdSec WordPress Bouncer](#crowdsec-wordpress-bouncer)
- [Usage](#usage)
- [Installation](#installation)
- [Technical notes](#technical-notes)
- [Developer guide](#developer-guide)
- [License](#license)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

# CrowdSec WordPress Bouncer

![CrowdSec WordPress Bouncer](https://raw.githubusercontent.com/crowdsecurity/cs-wordpress-bouncer/main/.wordpress-org/banner-1544x500.png "CrowdSec WordPress Bouncer")
Expand Down
4 changes: 2 additions & 2 deletions crowdsec.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Plugin URI: https://github.com/crowdsecurity/cs-wordpress-bouncer
* Description: Safer Together. Protect your WordPress application with CrowdSec.
* Tags: security, captcha, ip-blocker, crowdsec, hacker-protection, appsec
* Version: 2.10.0
* Version: 2.11.0
* Author: CrowdSec
* Author URI: https://www.crowdsec.net/
* Github: https://github.com/crowdsecurity/cs-wordpress-bouncer
Expand All @@ -13,7 +13,7 @@
* Requires PHP: 7.2
* Requires at least: 4.9
* Tested up to: 6.8
* Stable tag: 2.10.0
* Stable tag: 2.11.0
* Text Domain: crowdsec-wp
* First release: 2021.
*/
Expand Down
30 changes: 15 additions & 15 deletions docs/USER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
- [Usage](#usage)
- [Features](#features)
- [Apply a remediation: captcha or ban](#apply-a-remediation-captcha-or-ban)
- [Usage metrics](#usage-metrics)
- [Remediation metrics](#remediation-metrics)
- [Understanding the limitations of the bouncer](#understanding-the-limitations-of-the-bouncer)
- [Configurations](#configurations)
- [General settings](#general-settings)
Expand Down Expand Up @@ -71,9 +71,9 @@ Please note that it is possible to customize all the colors of these pages in a

On the other hand, all texts are also fully customizable. This will allow you, for example, to present translated pages in your users’ language.

#### Usage metrics
#### Remediation metrics

If you activate usage metrics push, the bouncer will provide usage data to the Local API, allowing for a unified view of its behavior and insights.
If you activate remediation metrics push, the bouncer will provide usage data to the Local API, allowing for a unified view of its behavior and insights.

Please see [below setting](#advanced-settings) and [CrowdSec documentation](https://doc.crowdsec.net/docs/next/observability/usage_metrics/) for more information.

Expand Down Expand Up @@ -140,8 +140,8 @@ If you are using a Block as a Service (BLaaS) LAPI URL (i.e. starting with `http
note the following:

- The Authentication type must be "Bouncer API key"
- Stream mode must be enabled (see Communication mode with the Local API in Advanced Settings)
- Usage Metrics cannot be sent (see Usage Metrics in [Advanced settings](#advanced-settings)).
- Stream mode must be enabled (see Communication mode with the Local API in [Advanced settings](#advanced-settings)).
- Remediation Metrics cannot be sent (see Remediation Metrics in [Advanced settings](#advanced-settings)).
- AppSec component cannot be used (see Appsec Component in [Advanced settings](#advanced-settings))

***
Expand Down Expand Up @@ -272,7 +272,7 @@ In the `Theme customization` part, you can modify texts and colors of ban and ca

#### Advanced settings

In the `Advanced` part, you can enable/disable the stream mode, enable/disable usage metrics, choose your cache system for your CrowdSec Local API, handle your remediation policy, manage geolocation feature, adjust some debug parameters and testing parameters.
In the `Advanced` part, you can enable/disable the stream mode, enable/disable remediation metrics, choose your cache system for your CrowdSec Local API, handle your remediation policy, manage geolocation feature, adjust some debug parameters and testing parameters.

![Communication mode](images/screenshots/config-communication-mode.png)

Expand All @@ -298,17 +298,17 @@ With the stream mode, every decision is retrieved in an asynchronous way. Here y

***

![Usage Metrics](images/screenshots/config-usage-metrics.png)
![Remediation Metrics](images/screenshots/config-usage-metrics.png)

***

`Usage Metrics → Enable the Usage Metrics`
`Remediation Metrics → Enable the Remediation Metrics`

Enable usage metrics to gain visibility: monitor incoming traffic and blocked threats for better security insights.
Enable remediation metrics to gain visibility: monitor incoming traffic and blocked threats for better security insights.

If this option is enabled, a cron job will push usage metrics to the Local API every 15 minutes.
If this option is enabled, a cron job will push remediation metrics to the Local API every 15 minutes.

**N.B** : There is also a push button if you want to push usage metrics manually.
**N.B** : There is also a push button if you want to push remediation metrics manually.

***

Expand All @@ -322,23 +322,23 @@ Choose the cache technology that will use your CrowdSec Local API.

The File system cache is faster than calling Local API. Redis or Memcached is faster than the File System cache.

**N.B**. : There are also a `Clear now` button fo all cache technologies and a `Prune now` button dedicated to the file system cache.
**N.B**. : There are also a `Clear now` button for all cache technologies and a `Prune now` button dedicated to the file system cache.

***

`Caching configuration → Recheck clean IPs each (live mode only)`

The duration between re-asking Local API about an already checked clean IP.

Minimum 1 second. Note that this setting can not be apply in stream mode.
Minimum 1 second. Note that this setting cannot be used in stream mode.

***

`Caching configuration → Recheck bad IPs each (live mode only)`

The duration between re-asking Local API about an already checked bad IP.

Minimum 1 second. Note that this setting can not be apply in stream mode.
Minimum 1 second. Note that this setting cannot be used in stream mode.


***
Expand Down Expand Up @@ -378,7 +378,7 @@ Example of DSN: memcached://localhost:11211.

Enable if you want to ask the AppSec component for a remediation based on the current request, in case the initial LAPI remediation is a bypass.

Not available if you use TLS certficates as authentication type.
Not available if you use TLS certificates as authentication type.

For more information on the AppSec component, please refer to the [documentation](https://docs.crowdsec.net/docs/appsec/intro/).

Expand Down
Binary file modified docs/images/screenshots/config-usage-metrics.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 7 additions & 6 deletions inc/Admin/advanced-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,15 +157,16 @@ function crowdsec_multi_save_advanced_settings()
** Section "Usage Metrics" **
**************************/
$isUsageMetricsEnabled = is_multisite() ? get_site_option('crowdsec_usage_metrics') : get_option('crowdsec_usage_metrics');
add_settings_section('crowdsec_admin_advanced_usage_metrics', 'Usage Metrics', function () {
add_settings_section('crowdsec_admin_advanced_usage_metrics', 'Remediation Metrics', function () {
}, 'crowdsec_advanced_settings',['after_section' => '<hr>']);

// Field "crowdsec_usage_metrics"
addFieldCheckbox('crowdsec_usage_metrics', 'Enable Usage Metrics', 'crowdsec_plugin_advanced_settings', 'crowdsec_advanced_settings', 'crowdsec_admin_advanced_usage_metrics', function () {
addFieldCheckbox('crowdsec_usage_metrics', 'Enable Remediation Metrics', 'crowdsec_plugin_advanced_settings', 'crowdsec_advanced_settings', 'crowdsec_admin_advanced_usage_metrics', function () {
// Usage metrics push just activated.
$lapiUrl = is_multisite() ? get_site_option('crowdsec_api_url') : get_option('crowdsec_api_url');
if (0 === strpos($lapiUrl, Constants::BAAS_URL)) {
AdminNotice::displayError('Pushing usage metrics with a Block as a Service LAPI ('.esc_html($lapiUrl).') is not supported. ');
AdminNotice::displayError('Pushing remediation metrics with a Block as a Service LAPI ('.esc_html
($lapiUrl).') is not supported. ');
return false;
}
scheduleUsageMetricsPush();
Expand All @@ -175,9 +176,9 @@ function crowdsec_multi_save_advanced_settings()
unscheduleUsageMetricsPush();
return false;
}, '
<p>Enable usage metrics to gain visibility: monitor incoming traffic and blocked threats for better security insights.</p>
<p>If this option is enabled, a cron job will push usage metrics to the Local API every 15 minutes.</p>
<p>For more information about usage metrics, please refer to the <a href="https://doc.crowdsec.net/docs/next/observability/usage_metrics/" target="_blank">documentation</a>.</p>
<p>Enable remediation metrics to gain visibility: monitor incoming traffic and blocked threats for better security insights.</p>
<p>If this option is enabled, a cron job will push remediation metrics to the Local API every 15 minutes.</p>
<p>For more information about remediation metrics, please refer to the <a href="https://doc.crowdsec.net/docs/next/observability/usage_metrics/" target="_blank">documentation</a>.</p>
<div id="usage-metrics-report">
<p>'.displayBouncerMetricsInAdminPage().'</p>
</div>
Expand Down
20 changes: 10 additions & 10 deletions inc/Admin/init.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ function clearBouncerCacheInAdminPage()
{
try {
$configs = getDatabaseConfigs();
// If usage metrics are enabled, we need to push them before clearing the cache.
// If remediation metrics are enabled, we need to push them before clearing the cache.
$isUsageMetricsEnabled = is_multisite() ? get_site_option('crowdsec_usage_metrics') : get_option('crowdsec_usage_metrics');
$bouncer = new Bouncer($configs);
if ($isUsageMetricsEnabled) {
Expand All @@ -42,7 +42,7 @@ function clearBouncerCacheInAdminPage()
$bouncer->clearCache();
$message = __('CrowdSec cache has just been cleared.');
if ($isUsageMetricsEnabled){
$message .= __('<br>As usage metrics push is enabled, metrics have been pushed before clearing the cache.');
$message .= __('<br>As remediation metrics push is enabled, metrics have been pushed before clearing the cache.');
}
// In stream mode, immediately warm the cache up.
$streamMode = is_multisite() ? get_site_option('crowdsec_stream_mode') : get_option('crowdsec_stream_mode');
Expand Down Expand Up @@ -106,7 +106,7 @@ function pushBouncerMetricsInAdminPage()
$configs = getDatabaseConfigs();
$bouncer = new Bouncer($configs);
$bouncer->pushUsageMetrics(Constants::BOUNCER_NAME, Constants::VERSION);
AdminNotice::displaySuccess(__('CrowdSec usage metrics have just been pushed.'));
AdminNotice::displaySuccess(__('CrowdSec remediation metrics have just been pushed.'));
} catch (Exception $e) {
if(isset($bouncer) && $bouncer->getLogger()) {
$bouncer->getLogger()->error('', [
Expand All @@ -117,7 +117,7 @@ function pushBouncerMetricsInAdminPage()
'line' => $e->getLine(),
]);
}
AdminNotice::displayError('Technical error while pushing usage metrics: '.$e->getMessage());
AdminNotice::displayError('Technical error while pushing remediation metrics: '.$e->getMessage());
}
}

Expand All @@ -127,7 +127,7 @@ function resetBouncerMetricsInAdminPage()
$configs = getDatabaseConfigs();
$bouncer = new Bouncer($configs);
$bouncer->resetUsageMetrics();
AdminNotice::displaySuccess(__('CrowdSec usage metrics have been reset successfully.'));
AdminNotice::displaySuccess(__('CrowdSec remediation metrics have been reset successfully.'));
} catch (Exception $e) {
if(isset($bouncer) && $bouncer->getLogger()) {
$bouncer->getLogger()->error('', [
Expand All @@ -138,7 +138,7 @@ function resetBouncerMetricsInAdminPage()
'line' => $e->getLine(),
]);
}
AdminNotice::displayError('Technical error while resetting usage metrics: '.$e->getMessage());
AdminNotice::displayError('Technical error while resetting remediation metrics: '.$e->getMessage());
}
}

Expand Down Expand Up @@ -258,7 +258,7 @@ function displayBouncerMetricsInAdminPage()
]);
}

AdminNotice::displayError('Technical error while displaying usage metrics: ' . esc_html($e->getMessage()));
AdminNotice::displayError('Technical error while displaying remediation metrics: ' . esc_html($e->getMessage()));
return '';
}
}
Expand All @@ -270,7 +270,7 @@ function displayResetMetricsInAdminPage()
$configs = getDatabaseConfigs();
$bouncer = new Bouncer($configs);
if ($bouncer->hasBaasUri()) {
return '<p><input id="crowdsec_reset_usage_metrics" style="margin-right:10px" type="button" value="Reset usage metrics now" class="button button-secondary button-small" onclick="document.getElementById(\'crowdsec_action_reset_usage_metrics\').submit();"></p>';
return '<p><input id="crowdsec_reset_usage_metrics" style="margin-right:10px" type="button" value="Reset remediation metrics now" class="button button-secondary button-small" onclick="document.getElementById(\'crowdsec_action_reset_usage_metrics\').submit();"></p>';
}

return '';
Expand Down Expand Up @@ -301,9 +301,9 @@ function displayPushMetricsInAdminPage($isPushEnabled = false)
return '';
}
if( $isPushEnabled) {
return '<p><input id="crowdsec_push_usage_metrics" style="margin-right:10px" type="button" value="Push usage metrics now" class="button button-secondary button-small" onclick="document.getElementById(\'crowdsec_action_push_usage_metrics\').submit();"></p>';
return '<p><input id="crowdsec_push_usage_metrics" style="margin-right:10px" type="button" value="Push remediation metrics now" class="button button-secondary button-small" onclick="document.getElementById(\'crowdsec_action_push_usage_metrics\').submit();"></p>';
}
return '<p><input id="crowdsec_push_usage_metrics" style="margin-right:10px" type="button" disabled="disabled" value="Push usage metrics now" class="button button-secondary button-small"></p>';
return '<p><input id="crowdsec_push_usage_metrics" style="margin-right:10px" type="button" disabled="disabled" value="Push remediation metrics now" class="button button-secondary button-small"></p>';

}
catch (Exception $e) {
Expand Down
15 changes: 14 additions & 1 deletion inc/Admin/settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,22 @@ function crowdsec_multi_save_settings()
** Section "Connection details" **
*********************************/

function getIntro()
{

$intro ='<p>The <b>Instant WordPress Blocklist</b> is an exclusive feature available through the CrowdSec plugin. <br>
<p class="submit blaas-button"><a class="button button-primary crowdsec-button" href="https://buy.stripe.com/00g3cIcu59JVfewaES"
target="_blank">Subscribe now</a></p>for only $5/month, proactively block thousands of attackers\' IPs currently targeting WordPress sites.
</p>'
. '<p><i>Instructions are available in the <a target="_blank" href="https://doc.crowdsec.net/u/bouncers/wordpress#instant-wordpress-blocklist">public documentation</a></i></p>'
;

return $intro;
}

add_settings_section('crowdsec_admin_connection', 'Connection details', function () {
echo 'Connect WordPress to your CrowdSec Local API.';
}, 'crowdsec_settings', ['after_section' => '<hr>']);
}, 'crowdsec_settings', ['after_section' => '<hr>', 'before_section' => getIntro()]);

// Field "crowdsec_api_url"
addFieldString('crowdsec_api_url', 'Local API URL', 'crowdsec_plugin_settings', 'crowdsec_settings', 'crowdsec_admin_connection', function ($input, $default ='') {
Expand Down
4 changes: 2 additions & 2 deletions inc/Constants.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use CrowdSecBouncer\Constants as LibConstants;

/**
* Every constant of the plugin are set here.
* All plugin constants are defined here.
*
* @author CrowdSec team
*
Expand All @@ -21,5 +21,5 @@ class Constants extends LibConstants
public const BOUNCER_NAME = 'wordpress-bouncer';
public const DEFAULT_BASE_FILE_PATH = __DIR__ . '/../../../../wp-content/uploads/crowdsec/';
public const STANDALONE_CONFIG_PATH = __DIR__ . '/standalone-settings.php';
public const VERSION = 'v2.10.0';
public const VERSION = 'v2.11.0';
}
37 changes: 37 additions & 0 deletions inc/assets/crowdsec.css
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,40 @@ div.ui-toggle label>div:hover {
.time-text {
width: 5%;
}

.crowdsec-button.button-primary {
height: 48px;
box-shadow: 0 2px 24px 0 rgba(248,171,19,.1),0 2px 12px 0 rgba(248,171,19,.25),0 2px 8px 0 rgba(248,171,19,.3),0 2px 4px 0 rgba(4,4,31,.15),0 1px 2px 0 rgba(4,4,31,.2),inset 0 1px 2px 0 hsla(48,95%,74%,.5);
background-image: linear-gradient(180deg,hsla(0,0%,100%,.1) 0,hsla(0,0%,100%,0) 92%),linear-gradient(180deg,#f8ab13,#f8ab13);
display: inline-flex;
cursor: pointer;
align-items: center;
justify-content: center;
border-radius: .5rem;
padding: .5rem 1.25rem;
font-size: 1rem;
font-weight: 500;
line-height: 1.5rem;
color: rgb(17, 24, 28);
transition-property: all;
transition-timing-function: cubic-bezier(.4,0,.2,1);
transition-duration: .3s;
opacity: .9;
}

.crowdsec-button.button-primary:hover, .crowdsec-button.button-primary:focus, .crowdsec-button.button-primary:active {
opacity: 1;
background-image: linear-gradient(180deg,hsla(0,0%,100%,.1) 0,hsla(0,0%,100%,0) 92%),linear-gradient(180deg,#f8ab13,#f8ab13);
color: rgb(17, 24, 28);
}

.crowdsec-button.button-primary:focus{
box-shadow: 0 2px 24px 0 rgba(248,171,19,.1),0 2px 12px 0 rgba(248,171,19,.25),0 2px 8px 0 rgba(248,171,19,.3),0 2px 4px 0 rgba(4,4,31,.15),0 1px 2px 0 rgba(4,4,31,.2),inset 0 1px 2px 0 hsla(48,95%,74%,.5);
}

p.submit.blaas-button {
margin-right: 10px;
padding: 0;
display: inline;
}

Loading