Privacy: Be less restrictive of the HTML tags allowed in user data exports.
Previously, only `a` and `br` tags were allowed in the `value` table cell for each field included in the HTML file generated when a user is exporting their personal data. Instead of relying on a hardcoded list of allowed tags, the `wp_kses()` call in `wp_privacy_generate_personal_data_export_group_html()` will now fallback to the default list of allowed tags (which includes `i`, `strong`, `em`, and other basic HTML formatting tags). Also, a new context of `personal_data_export` will now be passed to the `wp_kses()` call. As a result, the list of HTML tags and attributes allowed in the export file can now be filtered using the `wp_kses_allowed_html` filter and checking for the `personal_data_export` context. Fixes #44044. Props tz-media, desrosj, pento, birgire, garrett-eclipse. git-svn-id: https://develop.svn.wordpress.org/trunk@44824 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
a71fece6b8
commit
1615233fa2
@ -1956,17 +1956,7 @@ function wp_print_request_filesystem_credentials_modal() {
|
||||
* @return string The HTML for this group and its items.
|
||||
*/
|
||||
function wp_privacy_generate_personal_data_export_group_html( $group_data ) {
|
||||
$allowed_tags = array(
|
||||
'a' => array(
|
||||
'href' => array(),
|
||||
'target' => array(),
|
||||
),
|
||||
'br' => array(),
|
||||
);
|
||||
$allowed_protocols = array( 'http', 'https' );
|
||||
$group_html = '';
|
||||
|
||||
$group_html .= '<h2>' . esc_html( $group_data['group_label'] ) . '</h2>';
|
||||
$group_html = '<h2>' . esc_html( $group_data['group_label'] ) . '</h2>';
|
||||
$group_html .= '<div>';
|
||||
|
||||
foreach ( (array) $group_data['items'] as $group_item_id => $group_item_data ) {
|
||||
@ -1975,14 +1965,14 @@ function wp_privacy_generate_personal_data_export_group_html( $group_data ) {
|
||||
|
||||
foreach ( (array) $group_item_data as $group_item_datum ) {
|
||||
$value = $group_item_datum['value'];
|
||||
// If it looks like a link, make it a link
|
||||
// If it looks like a link, make it a link.
|
||||
if ( false === strpos( $value, ' ' ) && ( 0 === strpos( $value, 'http://' ) || 0 === strpos( $value, 'https://' ) ) ) {
|
||||
$value = '<a href="' . esc_url( $value ) . '">' . esc_html( $value ) . '</a>';
|
||||
}
|
||||
|
||||
$group_html .= '<tr>';
|
||||
$group_html .= '<th>' . esc_html( $group_item_datum['name'] ) . '</th>';
|
||||
$group_html .= '<td>' . wp_kses( $value, $allowed_tags, $allowed_protocols ) . '</td>';
|
||||
$group_html .= '<td>' . wp_kses( $value, 'personal_data_export' ) . '</td>';
|
||||
$group_html .= '</tr>';
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,200 @@
|
||||
<?php
|
||||
/**
|
||||
* Test cases for the `wp_privacy_generate_personal_data_export_group_html()` function.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage UnitTests
|
||||
* @since 5.2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Tests_Privacy_WpPrivacyGeneratePersonalDataExportGroupHtml class.
|
||||
*
|
||||
* @group privacy
|
||||
* @covers ::wp_privacy_generate_personal_data_export_group_html
|
||||
*
|
||||
* @since 5.2.0
|
||||
*/
|
||||
class Tests_Privacy_WpPrivacyGeneratePersonalDataExportGroupHtml extends WP_UnitTestCase {
|
||||
|
||||
/**
|
||||
* Test when a single data item is passed.
|
||||
*
|
||||
* @ticket 44044
|
||||
*/
|
||||
public function test_group_html_generation_single_data_item() {
|
||||
$data = array(
|
||||
'group_label' => 'Test Data Group',
|
||||
'items' => array(
|
||||
array(
|
||||
array(
|
||||
'name' => 'Field 1 Name',
|
||||
'value' => 'Field 1 Value',
|
||||
),
|
||||
array(
|
||||
'name' => 'Field 2 Name',
|
||||
'value' => 'Field 2 Value',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$actual = wp_privacy_generate_personal_data_export_group_html( $data );
|
||||
$expected_table_markup = '<table><tbody><tr><th>Field 1 Name</th><td>Field 1 Value</td></tr><tr><th>Field 2 Name</th><td>Field 2 Value</td></tr></tbody></table>';
|
||||
|
||||
$this->assertContains( '<h2>Test Data Group</h2>', $actual );
|
||||
$this->assertContains( $expected_table_markup, $actual );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test when a multiple data items are passed.
|
||||
*
|
||||
* @ticket 44044
|
||||
*/
|
||||
public function test_group_html_generation_multiple_data_items() {
|
||||
$data = array(
|
||||
'group_label' => 'Test Data Group',
|
||||
'items' => array(
|
||||
array(
|
||||
array(
|
||||
'name' => 'Field 1 Name',
|
||||
'value' => 'Field 1 Value',
|
||||
),
|
||||
array(
|
||||
'name' => 'Field 2 Name',
|
||||
'value' => 'Field 2 Value',
|
||||
),
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'name' => 'Field 1 Name',
|
||||
'value' => 'Another Field 1 Value',
|
||||
),
|
||||
array(
|
||||
'name' => 'Field 2 Name',
|
||||
'value' => 'Another Field 2 Value',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$actual = wp_privacy_generate_personal_data_export_group_html( $data );
|
||||
|
||||
$this->assertContains( '<h2>Test Data Group</h2>', $actual );
|
||||
$this->assertContains( '<td>Field 1 Value', $actual );
|
||||
$this->assertContains( '<td>Another Field 1 Value', $actual );
|
||||
$this->assertContains( '<td>Field 2 Value', $actual );
|
||||
$this->assertContains( '<td>Another Field 2 Value', $actual );
|
||||
$this->assertSame( 2, substr_count( $actual, '<th>Field 1 Name' ) );
|
||||
$this->assertSame( 2, substr_count( $actual, '<th>Field 2 Name' ) );
|
||||
$this->assertSame( 4, substr_count( $actual, '<tr>' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Values that appear to be links should be wrapped in `<a>` tags.
|
||||
*
|
||||
* @ticket 44044
|
||||
*/
|
||||
public function test_links_become_anchors() {
|
||||
$data = array(
|
||||
'group_label' => 'Test Data Group',
|
||||
'items' => array(
|
||||
array(
|
||||
array(
|
||||
'name' => 'HTTP Link',
|
||||
'value' => 'http://wordpress.org',
|
||||
),
|
||||
array(
|
||||
'name' => 'HTTPS Link',
|
||||
'value' => 'https://wordpress.org',
|
||||
),
|
||||
array(
|
||||
'name' => 'Link with Spaces',
|
||||
'value' => 'https://wordpress.org not a link.',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$actual = wp_privacy_generate_personal_data_export_group_html( $data );
|
||||
|
||||
$this->assertContains( '<a href="http://wordpress.org">http://wordpress.org</a>', $actual );
|
||||
$this->assertContains( '<a href="https://wordpress.org">https://wordpress.org</a>', $actual );
|
||||
$this->assertContains( 'https://wordpress.org not a link.', $actual );
|
||||
}
|
||||
|
||||
/**
|
||||
* HTML in group labels should be escaped.
|
||||
*
|
||||
* @ticket 44044
|
||||
*/
|
||||
public function test_group_labels_escaped() {
|
||||
$data = array(
|
||||
'group_label' => '<div>Escape HTML in group lavels</div>',
|
||||
'items' => array(),
|
||||
);
|
||||
|
||||
$actual = wp_privacy_generate_personal_data_export_group_html( $data );
|
||||
|
||||
$this->assertContains( '<h2><div>Escape HTML in group lavels</div></h2>', $actual );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the exported data should contain allowed HTML.
|
||||
*
|
||||
* @ticket 44044
|
||||
*/
|
||||
public function test_allowed_html_not_stripped() {
|
||||
$data = array(
|
||||
'group_label' => 'Test Data Group',
|
||||
'items' => array(
|
||||
array(
|
||||
'links' => array(
|
||||
'name' => 'Links are allowed',
|
||||
'value' => '<a href="http://wordpress.org">http://wordpress.org</a>',
|
||||
),
|
||||
'formatting' => array(
|
||||
'name' => 'Simple formatting is allowed',
|
||||
'value' => '<b>bold</b>, <em>emphasis</em>, <i>italics</i>, and <strong>strong</strong> are allowed.',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$actual = wp_privacy_generate_personal_data_export_group_html( $data );
|
||||
|
||||
$this->assertContains( $data['items'][0]['links']['value'], $actual );
|
||||
$this->assertContains( $data['items'][0]['formatting']['value'], $actual );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the exported data should not contain disallowed HTML.
|
||||
*
|
||||
* @ticket 44044
|
||||
*/
|
||||
public function test_disallowed_html_is_stripped() {
|
||||
$data = array(
|
||||
'group_label' => 'Test Data Group',
|
||||
'items' => array(
|
||||
array(
|
||||
'scripts' => array(
|
||||
'name' => 'Script tags are not allowed.',
|
||||
'value' => '<script>Testing that script tags are stripped.</script>',
|
||||
),
|
||||
'images' => array(
|
||||
'name' => 'Images are not allowed',
|
||||
'value' => '<img src="https://example.com/logo.jpg" alt="Alt text" />',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$actual = wp_privacy_generate_personal_data_export_group_html( $data );
|
||||
|
||||
$this->assertNotContains( $data['items'][0]['scripts']['value'], $actual );
|
||||
$this->assertContains( '<td>Testing that script tags are stripped.</td>', $actual );
|
||||
|
||||
$this->assertNotContains( $data['items'][0]['images']['value'], $actual );
|
||||
$this->assertContains( '<th>Images are not allowed</th><td></td>', $actual );
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user