Skip to content

Commit 11270b6

Browse files
authored
Inbox: Apply disallowed list before processing (#1590)
1 parent 9d664d6 commit 11270b6

File tree

3 files changed

+78
-21
lines changed

3 files changed

+78
-21
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Significance: minor
2+
Type: changed
3+
4+
Added WordPress disallowed list filtering to block unwanted ActivityPub interactions.

includes/rest/class-inbox-controller.php

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
namespace Activitypub\Rest;
99

1010
use Activitypub\Activity\Activity;
11+
use Activitypub\Debug;
1112

1213
/**
1314
* Inbox_Controller class.
@@ -127,27 +128,31 @@ public function register_routes() {
127128
public function create_item( $request ) {
128129
$data = $request->get_json_params();
129130
$activity = Activity::init_from_array( $data );
130-
$type = $request->get_param( 'type' );
131-
$type = \strtolower( $type );
132-
133-
/**
134-
* ActivityPub inbox action.
135-
*
136-
* @param array $data The data array.
137-
* @param int|null $user_id The user ID.
138-
* @param string $type The type of the activity.
139-
* @param Activity|\WP_Error $activity The Activity object.
140-
*/
141-
\do_action( 'activitypub_inbox', $data, null, $type, $activity );
142-
143-
/**
144-
* ActivityPub inbox action for specific activity types.
145-
*
146-
* @param array $data The data array.
147-
* @param int|null $user_id The user ID.
148-
* @param Activity|\WP_Error $activity The Activity object.
149-
*/
150-
\do_action( 'activitypub_inbox_' . $type, $data, null, $activity );
131+
$type = \strtolower( $request->get_param( 'type' ) );
132+
133+
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput
134+
if ( wp_check_comment_disallowed_list( $activity->to_json( false ), '', '', '', $_SERVER['REMOTE_ADDR'], $_SERVER['HTTP_USER_AGENT'] ?? '' ) ) {
135+
Debug::write_log( 'Blocked activity from: ' . $activity->get_actor() );
136+
} else {
137+
/**
138+
* ActivityPub inbox action.
139+
*
140+
* @param array $data The data array.
141+
* @param int|null $user_id The user ID.
142+
* @param string $type The type of the activity.
143+
* @param Activity|\WP_Error $activity The Activity object.
144+
*/
145+
\do_action( 'activitypub_inbox', $data, null, $type, $activity );
146+
147+
/**
148+
* ActivityPub inbox action for specific activity types.
149+
*
150+
* @param array $data The data array.
151+
* @param int|null $user_id The user ID.
152+
* @param Activity|\WP_Error $activity The Activity object.
153+
*/
154+
\do_action( 'activitypub_inbox_' . $type, $data, null, $activity );
155+
}
151156

152157
$response = \rest_ensure_response( array() );
153158
$response->set_status( 202 );

tests/includes/rest/class-test-inbox-controller.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,54 @@ public function test_create_item() {
8484
\remove_filter( 'activitypub_defer_signature_verification', '__return_true' );
8585
}
8686

87+
/**
88+
* Test disallow list block.
89+
*
90+
* @covers ::create_item
91+
*/
92+
public function test_disallow_list_block() {
93+
\add_filter( 'activitypub_defer_signature_verification', '__return_true' );
94+
95+
// Add a keyword that will be in our test content.
96+
\update_option( 'disallowed_keys', 'https://remote.example/@test' );
97+
98+
// Set up mock action.
99+
$inbox_action = new \MockAction();
100+
\add_action( 'activitypub_inbox', array( $inbox_action, 'action' ) );
101+
102+
// Create a valid request with content that contains the disallowed keyword.
103+
$json = array(
104+
'id' => 'https://remote.example/@id',
105+
'type' => 'Create',
106+
'actor' => 'https://remote.example/@test',
107+
'object' => array(
108+
'id' => 'https://remote.example/post/test',
109+
'type' => 'Note',
110+
'content' => 'Hello, World!',
111+
'inReplyTo' => 'https://local.example/post/test',
112+
'published' => '2020-01-01T00:00:00Z',
113+
),
114+
);
115+
116+
$request = new \WP_REST_Request( 'POST', '/' . ACTIVITYPUB_REST_NAMESPACE . '/inbox' );
117+
$request->set_header( 'Content-Type', 'application/activity+json' );
118+
$request->set_body( \wp_json_encode( $json ) );
119+
120+
// Dispatch the request.
121+
$response = \rest_do_request( $request );
122+
123+
// Verify the response is still successful (202).
124+
$this->assertEquals( 202, $response->get_status() );
125+
126+
// Verify that the hooks were not called.
127+
$this->assertEquals( 0, $inbox_action->get_call_count(), 'activitypub_inbox hook should not be called when content is disallowed' );
128+
129+
// Clean up.
130+
\delete_option( 'disallowed_keys' );
131+
\remove_filter( 'activitypub_defer_signature_verification', '__return_true' );
132+
\remove_action( 'activitypub_inbox', array( $inbox_action, 'action' ) );
133+
}
134+
87135
/**
88136
* Test whether an activity is public.
89137
*

0 commit comments

Comments
 (0)