Merge pull request #327 from Automattic/fix/sanitization

This commit is contained in:
Matthias Pfefferle 2023-05-24 21:13:11 +02:00 committed by GitHub
commit c809dc2cb5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 126 additions and 109 deletions

View file

@ -3,7 +3,7 @@ namespace Activitypub;
class Shortcodes { class Shortcodes {
/** /**
* Initialize the class, registering WordPress hooks * Class constructor, registering WordPress then Shortcodes
*/ */
public static function init() { public static function init() {
foreach ( get_class_methods( self::class ) as $shortcode ) { foreach ( get_class_methods( self::class ) as $shortcode ) {
@ -14,13 +14,13 @@ class Shortcodes {
} }
/** /**
* Generates output for the ap_hashtags shortcode * Generates output for the 'ap_hashtags' shortcode
* *
* @param array $atts shortcode attributes * @param array $atts The Shortcode attributes.
* @param string $content shortcode content * @param string $content The ActivityPub post-content.
* @param string $tag shortcode tag name * @param string $tag The tag/name of the Shortcode.
* *
* @return string * @return string The post tags as hashtags.
*/ */
public static function hashtags( $atts, $content, $tag ) { public static function hashtags( $atts, $content, $tag ) {
$post_id = get_the_ID(); $post_id = get_the_ID();
@ -40,8 +40,8 @@ class Shortcodes {
foreach ( $tags as $tag ) { foreach ( $tags as $tag ) {
$hash_tags[] = \sprintf( $hash_tags[] = \sprintf(
'<a rel="tag" class="u-tag u-category" href="%s">#%s</a>', '<a rel="tag" class="u-tag u-category" href="%s">#%s</a>',
\get_tag_link( $tag ), \esc_url( \get_tag_link( $tag ) ),
$tag->slug \wp_strip_all_tags( $tag->slug )
); );
} }
@ -49,13 +49,13 @@ class Shortcodes {
} }
/** /**
* Generates output for the ap_title shortcode * Generates output for the 'ap_title' Shortcode
* *
* @param array $atts shortcode attributes * @param array $atts The Shortcode attributes.
* @param string $content shortcode content * @param string $content The ActivityPub post-content.
* @param string $tag shortcode tag name * @param string $tag The tag/name of the Shortcode.
* *
* @return string * @return string The post title.
*/ */
public static function title( $atts, $content, $tag ) { public static function title( $atts, $content, $tag ) {
$post_id = get_the_ID(); $post_id = get_the_ID();
@ -64,18 +64,18 @@ class Shortcodes {
return ''; return '';
} }
return \get_the_title( $post_id ); return \wp_strip_all_tags( \get_the_title( $post_id ), true );
} }
/** /**
* Generates output for the ap_excerpt shortcode * Generates output for the 'ap_excerpt' Shortcode
* *
* @param array $atts shortcode attributes * @param array $atts The Shortcode attributes.
* @param string $content shortcode content * @param string $content The ActivityPub post-content.
* @param string $tag shortcode tag name * @param string $tag The tag/name of the Shortcode.
* *
* @return string * @return string The post excerpt.
*/ */
public static function excerpt( $atts, $content, $tag ) { public static function excerpt( $atts, $content, $tag ) {
$post = get_post(); $post = get_post();
@ -172,15 +172,18 @@ class Shortcodes {
} }
/** /**
* Generates output for the ap_content shortcode * Generates output for the 'ap_content' Shortcode
* *
* @param array $atts shortcode attributes * @param array $atts The Shortcode attributes.
* @param string $content shortcode content * @param string $content The ActivityPub post-content.
* @param string $tag shortcode tag name * @param string $tag The tag/name of the Shortcode.
* *
* @return string * @return string The post content.
*/ */
public static function content( $atts, $content, $tag ) { public static function content( $atts, $content, $tag ) {
// prevent inception
remove_shortcode( 'ap_content' );
$post = get_post(); $post = get_post();
if ( ! $post || \post_password_required( $post ) ) { if ( ! $post || \post_password_required( $post ) ) {
@ -205,20 +208,22 @@ class Shortcodes {
// replace script and style elements // replace script and style elements
$content = \preg_replace( '@<(script|style)[^>]*?>.*?</\\1>@si', '', $content ); $content = \preg_replace( '@<(script|style)[^>]*?>.*?</\\1>@si', '', $content );
$content = strip_shortcodes( $content );
$content = \trim( \preg_replace( '/[\n\r\t]/', '', $content ) ); $content = \trim( \preg_replace( '/[\n\r\t]/', '', $content ) );
add_shortcode( 'ap_content', array( 'Activitypub\Shortcodes', 'content' ) );
return $content; return $content;
} }
/** /**
* Generates output for the ap_permalink shortcode * Generates output for the 'ap_permalink' Shortcode
* *
* @param array $atts shortcode attributes * @param array $atts The Shortcode attributes.
* @param string $content shortcode content * @param string $content The ActivityPub post-content.
* @param string $tag shortcode tag name * @param string $tag The tag/name of the Shortcode.
* *
* @return string * @return string The post permalink.
*/ */
public static function permalink( $atts, $content, $tag ) { public static function permalink( $atts, $content, $tag ) {
$post = get_post(); $post = get_post();
@ -239,17 +244,20 @@ class Shortcodes {
return \esc_url( \get_permalink( $post->ID ) ); return \esc_url( \get_permalink( $post->ID ) );
} }
return \sprintf( '<a href="%1$s">%1$s</a>', \esc_url( \get_permalink( $post->ID ) ) ); return \sprintf(
'<a href="%1$s">%1$s</a>',
\esc_url( \get_permalink( $post->ID ) )
);
} }
/** /**
* Generates output for the ap_shortlink shortcode * Generates output for the 'ap_shortlink' Shortcode
* *
* @param array $atts shortcode attributes * @param array $atts The Shortcode attributes.
* @param string $content shortcode content * @param string $content The ActivityPub post-content.
* @param string $tag shortcode tag name * @param string $tag The tag/name of the Shortcode.
* *
* @return string * @return string The post shortlink.
*/ */
public static function shortlink( $atts, $content, $tag ) { public static function shortlink( $atts, $content, $tag ) {
$post = get_post(); $post = get_post();
@ -270,15 +278,18 @@ class Shortcodes {
return \esc_url( \wp_get_shortlink( $post->ID ) ); return \esc_url( \wp_get_shortlink( $post->ID ) );
} }
return \sprintf( '<a href="%1$s">%1$s</a>', \esc_url( \wp_get_shortlink( $post->ID ) ) ); return \sprintf(
'<a href="%1$s">%1$s</a>',
\esc_url( \wp_get_shortlink( $post->ID ) )
);
} }
/** /**
* Generates output for the ap_image shortcode * Generates output for the 'ap_image' Shortcode
* *
* @param array $atts shortcode attributes * @param array $atts The Shortcode attributes.
* @param string $content shortcode content * @param string $content The ActivityPub post-content.
* @param string $tag shortcode tag name * @param string $tag The tag/name of the Shortcode.
* *
* @return string * @return string
*/ */
@ -317,13 +328,13 @@ class Shortcodes {
} }
/** /**
* Generates output for the ap_hashcats shortcode * Generates output for the 'ap_hashcats' Shortcode
* *
* @param array $atts shortcode attributes * @param array $atts The Shortcode attributes.
* @param string $content shortcode content * @param string $content The ActivityPub post-content.
* @param string $tag shortcode tag name * @param string $tag The tag/name of the Shortcode.
* *
* @return string * @return string The post categories as hashtags.
*/ */
public static function hashcats( $atts, $content, $tag ) { public static function hashcats( $atts, $content, $tag ) {
$post_id = get_the_ID(); $post_id = get_the_ID();
@ -341,20 +352,24 @@ class Shortcodes {
$hash_tags = array(); $hash_tags = array();
foreach ( $categories as $category ) { foreach ( $categories as $category ) {
$hash_tags[] = \sprintf( '<a rel="tag" class="u-tag u-category" href="%s">#%s</a>', \get_category_link( $category ), $category->slug ); $hash_tags[] = \sprintf(
'<a rel="tag" class="u-tag u-category" href="%s">#%s</a>',
\esc_url( \get_category_link( $category ) ),
\wp_strip_all_tags( $category->slug )
);
} }
return \implode( ' ', $hash_tags ); return \implode( ' ', $hash_tags );
} }
/** /**
* Generates output for the ap_author shortcode * Generates output for the 'ap_author' Shortcode
* *
* @param array $atts shortcode attributes * @param array $atts The Shortcode attributes.
* @param string $content shortcode content * @param string $content The ActivityPub post-content.
* @param string $tag shortcode tag name * @param string $tag The tag/name of the Shortcode.
* *
* @return string * @return string The author name.
*/ */
public static function author( $atts, $content, $tag ) { public static function author( $atts, $content, $tag ) {
$post = get_post(); $post = get_post();
@ -369,17 +384,17 @@ class Shortcodes {
return ''; return '';
} }
return $name; return wp_strip_all_tags( $name );
} }
/** /**
* Generates output for the ap_authorurl shortcode * Generates output for the 'ap_authorurl' Shortcode
* *
* @param array $atts shortcode attributes * @param array $atts The Shortcode attributes.
* @param string $content shortcode content * @param string $content The ActivityPub post-content.
* @param string $tag shortcode tag name * @param string $tag The tag/name of the Shortcode.
* *
* @return string * @return string The author URL.
*/ */
public static function authorurl( $atts, $content, $tag ) { public static function authorurl( $atts, $content, $tag ) {
$post = get_post(); $post = get_post();
@ -398,52 +413,52 @@ class Shortcodes {
} }
/** /**
* Generates output for the ap_blogurl shortcode * Generates output for the 'ap_blogurl' Shortcode
* *
* @param array $atts shortcode attributes * @param array $atts The Shortcode attributes.
* @param string $content shortcode content * @param string $content The ActivityPub post-content.
* @param string $tag shortcode tag name * @param string $tag The tag/name of the Shortcode.
* *
* @return string * @return string The site URL.
*/ */
public static function blogurl( $atts, $content, $tag ) { public static function blogurl( $atts, $content, $tag ) {
return \esc_url( \get_bloginfo( 'url' ) ); return \esc_url( \get_bloginfo( 'url' ) );
} }
/** /**
* Generates output for the ap_blogname shortcode * Generates output for the 'ap_blogname' Shortcode
* *
* @param array $atts shortcode attributes * @param array $atts The Shortcode attributes.
* @param string $content shortcode content * @param string $content The ActivityPub post-content.
* @param string $tag shortcode tag name * @param string $tag The tag/name of the Shortcode.
* *
* @return string * @return string
*/ */
public static function blogname( $atts, $content, $tag ) { public static function blogname( $atts, $content, $tag ) {
return \get_bloginfo( 'name' ); return \wp_strip_all_tags( \get_bloginfo( 'name' ) );
} }
/** /**
* Generates output for the ap_blogdesc shortcode * Generates output for the 'ap_blogdesc' Shortcode
* *
* @param array $atts shortcode attributes * @param array $atts The Shortcode attributes.
* @param string $content shortcode content * @param string $content The ActivityPub post-content.
* @param string $tag shortcode tag name * @param string $tag The tag/name of the Shortcode.
* *
* @return string * @return string The site description.
*/ */
public static function blogdesc( $atts, $content, $tag ) { public static function blogdesc( $atts, $content, $tag ) {
return \get_bloginfo( 'description' ); return \wp_strip_all_tags( \get_bloginfo( 'description' ) );
} }
/** /**
* Generates output for the ap_date shortcode * Generates output for the 'ap_date' Shortcode
* *
* @param array $atts shortcode attributes * @param array $atts The Shortcode attributes.
* @param string $content shortcode content * @param string $content The ActivityPub post-content.
* @param string $tag shortcode tag name * @param string $tag The tag/name of the Shortcode.
* *
* @return string * @return string The post date.
*/ */
public static function date( $atts, $content, $tag ) { public static function date( $atts, $content, $tag ) {
$post = get_post(); $post = get_post();
@ -466,13 +481,13 @@ class Shortcodes {
} }
/** /**
* Generates output for the ap_time shortcode * Generates output for the 'ap_time' Shortcode
* *
* @param array $atts shortcode attributes * @param array $atts The Shortcode attributes.
* @param string $content shortcode content * @param string $content The ActivityPub post-content.
* @param string $tag shortcode tag name * @param string $tag The tag/name of the Shortcode.
* *
* @return string * @return string The post time.
*/ */
public static function time( $atts, $content, $tag ) { public static function time( $atts, $content, $tag ) {
$post = get_post(); $post = get_post();
@ -495,13 +510,13 @@ class Shortcodes {
} }
/** /**
* Generates output for the ap_datetime shortcode * Generates output for the 'ap_datetime' Shortcode
* *
* @param array $atts shortcode attributes * @param array $atts The Shortcode attributes.
* @param string $content shortcode content * @param string $content The ActivityPub post-content.
* @param string $tag shortcode tag name * @param string $tag The tag/name of the Shortcode.
* *
* @return string * @return string The post date/time.
*/ */
public static function datetime( $atts, $content, $tag ) { public static function datetime( $atts, $content, $tag ) {
$post = get_post(); $post = get_post();

View file

@ -8,37 +8,37 @@
'<p>' . __( 'The following Template Tags are available:', 'activitypub' ) . '</p>' . '<p>' . __( 'The following Template Tags are available:', 'activitypub' ) . '</p>' .
'<dl>' . '<dl>' .
'<dt><code>[ap_title]</code></dt>' . '<dt><code>[ap_title]</code></dt>' .
'<dd>' . \wp_kses( __( 'The post\'s title.', 'activitypub' ), 'default' ) . '</dd>' . '<dd>' . \wp_kses( __( 'The post\'s title.', 'activitypub' ), array( 'code' => array() ) ) . '</dd>' .
'<dt><code>[ap_content apply_filters="yes"]</code></dt>' . '<dt><code>[ap_content apply_filters="yes"]</code></dt>' .
'<dd>' . \wp_kses( __( 'The post\'s content. With <code>apply_filters</code> you can decide if filters should be applied or not (default is <code>yes</code>). The values can be <code>yes</code> or <code>no</code>. <code>apply_filters</code> attribute is optional.', 'activitypub' ), 'default' ) . '</dd>' . '<dd>' . \wp_kses( __( 'The post\'s content. With <code>apply_filters</code> you can decide if filters (<code>apply_filters( \'the_content\', $content )</code>) should be applied or not (default is <code>yes</code>). The values can be <code>yes</code> or <code>no</code>. <code>apply_filters</code> attribute is optional.', 'activitypub' ), array( 'code' => array() ) ) . '</dd>' .
'<dt><code>[ap_excerpt lenght="400"]</code></dt>' . '<dt><code>[ap_excerpt lenght="400"]</code></dt>' .
'<dd>' . \wp_kses( __( 'The post\'s excerpt (default 400 chars). <code>length</code> attribute is optional.', 'activitypub' ), 'default' ) . '</dd>' . '<dd>' . \wp_kses( __( 'The post\'s excerpt (default 400 chars). <code>length</code> attribute is optional.', 'activitypub' ), array( 'code' => array() ) ) . '</dd>' .
'<dt><code>[ap_permalink type="url"]</code></dt>' . '<dt><code>[ap_permalink type="url"]</code></dt>' .
'<dd>' . \wp_kses( __( 'The post\'s permalink. <code>type</code> can be either: <code>url</code> or <code>html</code> (an &lt;a /&gt; tag). <code>type</code> attribute is optional.', 'activitypub' ), 'default' ) . '</dd>' . '<dd>' . \wp_kses( __( 'The post\'s permalink. <code>type</code> can be either: <code>url</code> or <code>html</code> (an &lt;a /&gt; tag). <code>type</code> attribute is optional.', 'activitypub' ), array( 'code' => array() ) ) . '</dd>' .
'<dt><code>[ap_shortlink type="url"]</code></dt>' . '<dt><code>[ap_shortlink type="url"]</code></dt>' .
'<dd>' . \wp_kses( __( 'The post\'s shortlink. <code>type</code> can be either <code>url</code> or <code>html</code> (an &lt;a /&gt; tag). I can recommend <a href="https://wordpress.org/plugins/hum/" target="_blank">Hum</a>, to prettify the Shortlinks. <code>type</code> attribute is optional.', 'activitypub' ), 'default' ) . '</dd>' . '<dd>' . \wp_kses( __( 'The post\'s shortlink. <code>type</code> can be either <code>url</code> or <code>html</code> (an &lt;a /&gt; tag). I can recommend <a href="https://wordpress.org/plugins/hum/" target="_blank">Hum</a>, to prettify the Shortlinks. <code>type</code> attribute is optional.', 'activitypub' ), array( 'code' => array() ) ) . '</dd>' .
'<dt><code>[ap_hashtags]</code></dt>' . '<dt><code>[ap_hashtags]</code></dt>' .
'<dd>' . \wp_kses( __( 'The post\'s tags as hashtags.', 'activitypub' ), 'default' ) . '</dd>' . '<dd>' . \wp_kses( __( 'The post\'s tags as hashtags.', 'activitypub' ), array( 'code' => array() ) ) . '</dd>' .
'<dt><code>[ap_hashcats]</code></dt>' . '<dt><code>[ap_hashcats]</code></dt>' .
'<dd>' . \wp_kses( __( 'The post\'s categories as hashtags.', 'activitypub' ), 'default' ) . '</dd>' . '<dd>' . \wp_kses( __( 'The post\'s categories as hashtags.', 'activitypub' ), array( 'code' => array() ) ) . '</dd>' .
'<dt><code>[ap_image type=full]</code></dt>' . '<dt><code>[ap_image type=full]</code></dt>' .
'<dd>' . \wp_kses( __( 'The URL for the post\'s featured image, defaults to full size. The type attribute can be any of the following: <code>thumbnail</code>, <code>medium</code>, <code>large</code>, <code>full</code>. <code>type</code> attribute is optional.', 'activitypub' ), 'default' ) . '</dd>' . '<dd>' . \wp_kses( __( 'The URL for the post\'s featured image, defaults to full size. The type attribute can be any of the following: <code>thumbnail</code>, <code>medium</code>, <code>large</code>, <code>full</code>. <code>type</code> attribute is optional.', 'activitypub' ), array( 'code' => array() ) ) . '</dd>' .
'<dt><code>[ap_author]</code></dt>' . '<dt><code>[ap_author]</code></dt>' .
'<dd>' . \wp_kses( __( 'The author\'s name.', 'activitypub' ), 'default' ) . '</dd>' . '<dd>' . \wp_kses( __( 'The author\'s name.', 'activitypub' ), array( 'code' => array() ) ) . '</dd>' .
'<dt><code>[ap_authorurl]</code></dt>' . '<dt><code>[ap_authorurl]</code></dt>' .
'<dd>' . \wp_kses( __( 'The URL to the author\'s profile page.', 'activitypub' ), 'default' ) . '</dd>' . '<dd>' . \wp_kses( __( 'The URL to the author\'s profile page.', 'activitypub' ), array( 'code' => array() ) ) . '</dd>' .
'<dt><code>[ap_date]</code></dt>' . '<dt><code>[ap_date]</code></dt>' .
'<dd>' . \wp_kses( __( 'The post\'s date.', 'activitypub' ), 'default' ) . '</dd>' . '<dd>' . \wp_kses( __( 'The post\'s date.', 'activitypub' ), array( 'code' => array() ) ) . '</dd>' .
'<dt><code>[ap_time]</code></dt>' . '<dt><code>[ap_time]</code></dt>' .
'<dd>' . \wp_kses( __( 'The post\'s time.', 'activitypub' ), 'default' ) . '</dd>' . '<dd>' . \wp_kses( __( 'The post\'s time.', 'activitypub' ), array( 'code' => array() ) ) . '</dd>' .
'<dt><code>[ap_datetime]</code></dt>' . '<dt><code>[ap_datetime]</code></dt>' .
'<dd>' . \wp_kses( __( 'The post\'s date/time formated as "date @ time".', 'activitypub' ), 'default' ) . '</dd>' . '<dd>' . \wp_kses( __( 'The post\'s date/time formated as "date @ time".', 'activitypub' ), array( 'code' => array() ) ) . '</dd>' .
'<dt><code>[ap_blogurl]</code></dt>' . '<dt><code>[ap_blogurl]</code></dt>' .
'<dd>' . \wp_kses( __( 'The URL to the site.', 'activitypub' ), 'default' ) . '</dd>' . '<dd>' . \wp_kses( __( 'The URL to the site.', 'activitypub' ), array( 'code' => array() ) ) . '</dd>' .
'<dt><code>[ap_blogname]</code></dt>' . '<dt><code>[ap_blogname]</code></dt>' .
'<dd>' . \wp_kses( __( 'The name of the site.', 'activitypub' ), 'default' ) . '</dd>' . '<dd>' . \wp_kses( __( 'The name of the site.', 'activitypub' ), array( 'code' => array() ) ) . '</dd>' .
'<dt><code>[ap_blogdesc]</code></dt>' . '<dt><code>[ap_blogdesc]</code></dt>' .
'<dd>' . \wp_kses( __( 'The description of the site.', 'activitypub' ), 'default' ) . '</dd>' . '<dd>' . \wp_kses( __( 'The description of the site.', 'activitypub' ), array( 'code' => array() ) ) . '</dd>' .
'</dl>' . '</dl>' .
'<p>' . __( 'You may also use any Shortcode normally available to you on your site, however be aware that Shortcodes may significantly increase the size of your content depending on what they do.', 'activitypub' ) . '</p>' . '<p>' . __( 'You may also use any Shortcode normally available to you on your site, however be aware that Shortcodes may significantly increase the size of your content depending on what they do.', 'activitypub' ) . '</p>' .
'<p>' . __( 'Note: the old Template Tags are now deprecated and automatically converted to the new ones.', 'activitypub' ) . '</p>' . '<p>' . __( 'Note: the old Template Tags are now deprecated and automatically converted to the new ones.', 'activitypub' ) . '</p>' .
@ -48,8 +48,8 @@
\get_current_screen()->add_help_tab( \get_current_screen()->add_help_tab(
array( array(
'id' => 'glossar', 'id' => 'glossary',
'title' => \__( 'Glossar', 'activitypub' ), 'title' => \__( 'Glossary', 'activitypub' ),
'content' => 'content' =>
'<p><h2>' . \__( 'Fediverse', 'activitypub' ) . '</h2></p>' . '<p><h2>' . \__( 'Fediverse', 'activitypub' ) . '</h2></p>' .
'<p>' . \__( 'The Fediverse is a new word made of two words: "federation" + "universe"', 'activitypub' ) . '</p>' . '<p>' . \__( 'The Fediverse is a new word made of two words: "federation" + "universe"', 'activitypub' ) . '</p>' .

View file

@ -516,8 +516,10 @@ class Post {
$content = do_shortcode( $content ); $content = do_shortcode( $content );
wp_reset_postdata(); wp_reset_postdata();
$content = \wpautop( \wp_kses( $content, $this->allowed_tags ) ); $content = \wp_kses( $content, $this->allowed_tags );
$content = \trim( \preg_replace( '/[\n\r\t]/', '', $content ) ); $content = \wpautop( $content );
$content = \preg_replace( '/[\n\r\t]/', '', $content );
$content = \trim( $content );
$content = \apply_filters( 'activitypub_the_content', $content, $post ); $content = \apply_filters( 'activitypub_the_content', $content, $post );
$content = \html_entity_decode( $content, \ENT_QUOTES, 'UTF-8' ); $content = \html_entity_decode( $content, \ENT_QUOTES, 'UTF-8' );