Skip to content

Commit 54d7052

Browse files
committed
Use SCRIPT_NAME instead of REQUEST_URI to check path (#585) (#589)
The script is currently checking if the `REQUEST_URI` is containing `wp-comments-post.php`, the default script to handle the submission of a comment. Some security plugins have options to rename this file to disguise that WordPress is used. With this fix, the `SCRIPT_NAME` is used instead. Since many security plugins do use rewrite rules, while the `REQUEST_URI` value is changed, the `SCRIPT_NAME` value stays the same. Therefor the condition would still recognize if a comment was submitted. Original fix by @2ndkauboy in #589, adapted to v3.
1 parent 260756e commit 54d7052

File tree

4 files changed

+129
-2
lines changed

4 files changed

+129
-2
lines changed

src/Handlers/Comment.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public static function process( $comment ) {
5656

5757
$comment['comment_author_IP'] = IpHelper::get_client_ip();
5858

59-
$request_uri = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : null;
59+
$request_uri = isset( $_SERVER['SCRIPT_NAME'] ) ? esc_url_raw( wp_unslash( $_SERVER['SCRIPT_NAME'] ) ) : null;
6060
$request_path = DataHelper::parse_url( $request_uri, 'path' );
6161

6262
if ( empty( $request_path ) ) {

src/Rules/Honeypot.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public static function precheck() {
8181
return;
8282
}
8383

84-
$request_uri = Settings::get_key( $_SERVER, 'REQUEST_URI' );
84+
$request_uri = Settings::get_key( $_SERVER, 'SCRIPT_NAME' );
8585
$request_path = DataHelper::parse_url( $request_uri, 'path' );
8686

8787
if ( strpos( $request_path, 'wp-comments-post.php' ) === false ) {

tests/Unit/Handlers/CommentTest.php

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
3+
namespace AntispamBee\Tests\Unit\Handlers;
4+
5+
use AntispamBee\Handlers\Comment;
6+
use AntispamBee\Handlers\Reaction;
7+
use Yoast\WPTestUtils\BrainMonkey\TestCase;
8+
9+
use function Brain\Monkey\Functions\stubs;
10+
/**
11+
* Unit tests for {@see Comment}.
12+
*/
13+
class CommentTest extends TestCase {
14+
15+
public function test_process() {
16+
global $_POST;
17+
global $_SERVER;
18+
19+
$_POST = null;
20+
$_SERVER = [
21+
'HTTP_CLIENT_IP' => '192.0.2.100',
22+
'SCRIPT_NAME' => '/index.php'
23+
];
24+
25+
stubs(
26+
[
27+
'esc_url_raw' => function (string $url) {
28+
return $url;
29+
},
30+
'wp_parse_url' => 'parse_url',
31+
'wp_unslash' => function ($value) {
32+
return $value;
33+
},
34+
]
35+
);
36+
37+
$processed = [];
38+
mock('overload:' . Reaction::class )
39+
->expects( 'process' )
40+
->withArgs( function( $input ) use ( &$processed ) {
41+
$processed[] = $input;
42+
return true;
43+
} );
44+
45+
$comment = [ 'comment_type' => 'comment' ];
46+
47+
$result = Comment::process( $comment );
48+
self::assertSame( '192.0.2.100', $result['comment_author_IP'], 'Unexpected author IP on index.php' );
49+
self::assertEmpty( $processed, 'Comment should no have been processed on index.php' );
50+
51+
$_SERVER['SCRIPT_NAME'] = '';
52+
$result = Comment::process( $comment );
53+
self::assertSame( '192.0.2.100', $result['comment_author_IP'], 'Unexpected author IP on invalid request' );
54+
self::assertSame( 1, $result['ab_spam__invalid_request'], 'Invalid request not detected' );
55+
self::assertEmpty( $processed, 'Comment should no have been processed on invalid request' );
56+
57+
$_SERVER['SCRIPT_NAME'] = '/wp-comments-post.php';
58+
$result = Comment::process( $comment );
59+
self::assertSame( '192.0.2.100', $result['comment_author_IP'], 'Unexpected author IP on invalid request' );
60+
self::assertArrayNotHasKey( 'processed', $result, 'Comment should no have been processed without POST data' );
61+
62+
$_POST = 'test me';
63+
$result = Comment::process( $comment );
64+
self::assertSame( [ $result ], $processed, 'Comment was not processed' );
65+
66+
$comment = [ 'comment_type' => 'linkback' ];
67+
$result = Comment::process( $comment );
68+
self::assertSame( $comment, $result, 'Linkback should not be modified by comment handler' );
69+
}
70+
}

tests/Unit/Rules/HoneypotTest.php

+57
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
use AntispamBee\Rules\Honeypot;
66

7+
use function Brain\Monkey\Functions\stubs;
8+
79
/**
810
* Unit tests for {@see Honeypot}.
911
*
@@ -35,4 +37,59 @@ public function test_init() {
3537
'comment_form_field_comment filter was not added'
3638
);
3739
}
40+
41+
public function test_precheck() {
42+
global $_POST;
43+
global $_SERVER;
44+
45+
stubs(
46+
[
47+
'esc_url_raw' => function (string $url) {
48+
return $url;
49+
},
50+
'is_feed' => false,
51+
'is_trackback' => false,
52+
'wp_parse_url' => 'parse_url',
53+
'wp_unslash' => function ($value) {
54+
return $value;
55+
},
56+
]
57+
);
58+
mock( 'overload:' . \AntispamBee\Helpers\Honeypot::class )
59+
->expects( 'get_secret_name_for_post' )
60+
->andReturns( 'my-secret' );
61+
62+
$_POST = [];
63+
$_SERVER = [ 'SCRIPT_NAME' => '/index.php' ];
64+
65+
Honeypot::precheck();
66+
self::assertEmpty( $_POST, 'Empty POST data modified unexpectedly' );
67+
68+
$_POST = [ 'foo' => 'bar' ];
69+
Honeypot::precheck();
70+
self::assertSame( ['foo' => 'bar' ], $_POST, 'POST data modified on index.php' );
71+
72+
$_SERVER = [ 'SCRIPT_NAME' => '/wp-comments-post.php' ];
73+
Honeypot::precheck();
74+
self::assertSame( 1, $_POST[ 'ab_spam__invalid_request' ], 'request without missing fields not detected' );
75+
76+
$_POST = [
77+
'my-secret' => 'S3cr3t',
78+
'my-hidden' => 'H1dd3n',
79+
];
80+
Honeypot::precheck();
81+
self::assertSame( 1, $_POST[ 'ab_spam__hidden_field' ], 'non-empty hidden fiend not detected' );
82+
83+
$_POST = [
84+
'my-secret' => 'S3cr3t',
85+
'my-hidden' => '',
86+
];
87+
Honeypot::precheck();
88+
self::assertSame(
89+
[ 'my-hidden' => 'S3cr3t' ],
90+
$_POST,
91+
'secret was not moved to hidden field'
92+
);
93+
94+
}
3895
}

0 commit comments

Comments
 (0)