Skip to content
This repository has been archived by the owner on Sep 24, 2018. It is now read-only.

Use wp_kses in place of wp_filter_post_kses to sanitize post title #2840

Closed
wants to merge 3 commits into from

Conversation

kadamwhite
Copy link
Contributor

May fix #2788

This PR switches from using wp_filter_post_kses() for post_title sanitization to calling wp_kses directly: #2788 describes that the core behavior is to call wp_filter_kses(), but @westonruter notes in that thread that the slash handling in wp_filter_kses is lossy so using the underlying implementation of wp_filter_kses without the de-slashing and re-slashing should provide adequate sanitization without compromising the integrity of the content.

Review requested especially from @rachelbaker or @westonruter

May fix #2788

This PR switches from using `wp_filter_post_kses()` for `post_title`
sanitization to calling `wp_kses` directly: #2788 describes that the
core behavior is to call `wp_filter_kses()`, but @westonruter notes
in that thread that the slash handling in `wp_filter_kses` is lossy so
using the underlying implementation of `wp_filter_kses` without the
de-slashing and re-slashing should provide adequate sanitization without
compromising the integrity of the content.

Review requested especially from @rachelbaker or @westonruter
@@ -824,9 +824,10 @@ protected function prepare_item_for_database( $request ) {
// Post title.
if ( ! empty( $schema['properties']['title'] ) && isset( $request['title'] ) ) {
if ( is_string( $request['title'] ) ) {
$prepared_post->post_title = wp_filter_post_kses( $request['title'] );
// wp_filter_kses slash handling is lossy: use the underlying methods directly
$prepared_post->post_title = wp_kses( $request['title'], current_filter() );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that current_filter() should be replaced with 'post'. I'm not sure if there are filters being applied at this point, but even if they are, for sure they're not going to be the same as what are being applied during a call to sanitize_post().

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought current_filter() here should be title_save_pre because post titles get a stricter set of HTML tags allowed than wp_kses_post()

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're probably right. So the string literal 'title_save_pre' should be used instead of current_filter().

} elseif ( ! empty( $request['title']['raw'] ) ) {
$prepared_post->post_title = wp_filter_post_kses( $request['title']['raw'] );
$prepared_post->post_title = wp_kses( $request['title']['raw'], current_filter() );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kadamwhite
Copy link
Contributor Author

@rachelbaker @westonruter thank you for clarifying, that makes sense. I've updated the patch

@rachelbaker
Copy link
Member

rachelbaker commented Oct 17, 2016

@kadamwhite we use wp_filter_post_kses() in several other places within the endpoints.
So if we are not trusting the slash handling of wp_filter_post_kses() then we should do that consistently, and switch to wp_kses_post() or wp_kses() with the {filter_name}.

Recording this here, but can be done in another PR.

@rachelbaker
Copy link
Member

@kadamwhite Only thing blocking this would be a unit test.

@kadamwhite
Copy link
Contributor Author

Unit test would be e.g. create a post w/ a title including a disallowed HTML tag such as <div>, and ensure it is stripped

$request->set_body_params( $params );
$response = $this->server->dispatch( $request );
$new_data = $response->get_data();
$this->assertEquals( '\o/', $new_data['title']['raw'] );
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@westonruter @rachelbaker This test fails, but I would have expected it to pass based on our discussion previously. Any ideas?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kadamwhite My guess would be thatwp_kses_no_null() (called in wp_kses()) is stripping out the preceding slash.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we can't escape (har har) the unslashing, is the use of wp_kses overkill? if you can suggest a direction I will implement.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kadamwhite crazy idea, what happens if you run this test with wp_filter_kses instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kadamwhite yeah, I tested it too and was not able to get a passing test. 😞
I also WAS able to confirm that within the WP editor I can save a post with a title of Do what I mean \ Not what I say, and that is also exactly how the data is stored in the db. So we are doing something WRONG somewhere here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is potentially an issue because of the unescaped slash? Try \\o/ instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rmccue Same results with '\\o/', with both wp_filter_kses and wp_kses

@kadamwhite
Copy link
Contributor Author

Closing, as I believe this has been superseded by 4.7 trunk

@kadamwhite kadamwhite closed this Dec 5, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
Development

Successfully merging this pull request may close these issues.

Change the post_title database sanitization function towp_filter_kses()
4 participants