Skip to content
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
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"license": "GPL-2.0-or-later",
"require": {
"php": ">=8.1",
"getsupertab/connect-sdk-php": "1.4.0-beta.6"
"getsupertab/connect-sdk-php": "1.4.0-beta.9"
},
"require-dev": {
"automattic/vipwpcs": "^3.0",
Expand Down
14 changes: 7 additions & 7 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

60 changes: 55 additions & 5 deletions src/class-bot-protection.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
}

use Supertab\Connect\Result\BlockResult;
use Supertab\Connect\Result\RespondResult;
use Supertab\Connect\SupertabConnect;

/**
Expand Down Expand Up @@ -101,6 +102,11 @@ public function maybe_handle_request( \WP $wp ): void {
return;
}

if ( $result instanceof RespondResult ) {
$this->send_respond_response( $result );
return;
}

$this->signal_headers = $result->headers;
}

Expand Down Expand Up @@ -147,15 +153,59 @@ private function is_path_active( string $request_path ): bool {
*/
private function send_block_response( BlockResult $result ): void {
status_header( $result->status );
$this->send_headers( $result->headers );

echo esc_html( $result->body );
exit;
}

/**
* Send the SDK's own response (e.g. the status endpoint) and terminate.
*
* @param RespondResult $result The respond result from the SDK.
* @return void
*/
private function send_respond_response( RespondResult $result ): void {
status_header( $result->status );
$this->send_headers( $result->headers );

// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- JSON produced by the SDK itself for its status endpoint, must be served verbatim.
echo $result->body;
exit;
}

foreach ( $result->headers as $name => $value ) {
if ( ! preg_match( '/^[a-zA-Z0-9-]+$/', $name ) ) {
/**
* Sanitize and emit response headers.
*
* Rejects header names containing anything other than letters, digits,
* and hyphens, and strips CR/LF from values to prevent header injection.
*
* @param array<string, string> $headers Raw headers from an SDK result.
* @return void
*/
private function send_headers( array $headers ): void {
foreach ( $this->filter_safe_headers( $headers ) as $name => $value ) {
header( "{$name}: {$value}" );
}
}

/**
* Filter out unsafe header names and strip CR/LF from values.
*
* @param array<string, string> $headers Raw headers from an SDK result.
* @return array<string, string> Sanitized headers safe to pass to header().
*/
private function filter_safe_headers( array $headers ): array {
$safe_headers = array();

foreach ( $headers as $name => $value ) {
if ( ! preg_match( '/^[a-zA-Z0-9-]+$/', (string) $name ) ) {
continue;
}
header( str_replace( array( "\r", "\n" ), '', "{$name}: {$value}" ) );

$safe_headers[ $name ] = str_replace( array( "\r", "\n" ), '', (string) $value );
}

echo esc_html( $result->body );
exit;
return $safe_headers;
}
}
5 changes: 4 additions & 1 deletion src/class-plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ public function init(): void {
$license_handler = new RSL_License_Handler( $settings, SUPERTAB_CONNECT_API_BASE_URL, $http_client );
$license_handler->register();

$status_handler = new Status_Handler( $settings, SUPERTAB_CONNECT_API_BASE_URL, $http_client );
$status_handler->register();

$analytics_enabled = $settings->has_merchant_api_key() && $settings->is_bot_protection_enabled();

$dispatcher = null;
Expand Down Expand Up @@ -187,7 +190,7 @@ private function init_bot_protection( Settings $settings, HttpClientInterface $h
*
* @return EnforcementMode
*/
private static function get_enforcement_mode(): EnforcementMode {
public static function get_enforcement_mode(): EnforcementMode {
$default = EnforcementMode::OBSERVE;

if ( defined( 'SUPERTAB_CONNECT_ENFORCEMENT_MODE' ) ) {
Expand Down
Loading
Loading