Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Sanitize error message html #7145

Merged
merged 7 commits into from
Sep 23, 2022
Merged

Sanitize error message html #7145

merged 7 commits into from
Sep 23, 2022

Conversation

hsingyuc
Copy link
Contributor

@hsingyuc hsingyuc commented Sep 13, 2022

This PR is sanitizing the merchant store link in the error message added in this PR. Because in some (rare) cases the customer could run into an issue where we need to tell them an error occurred and they have to go back to the merchant store and reinitialize WooPay to fix the issue. In these cases, it'd be great to include a link back to the merchant store.

Fixes 1130-gh-Automattic/woopay
Related PR 1287-gh-Automattic/woopay

Accessibility

Other Checks

  • This PR adds/removes a feature flag & I've updated this doc.
  • This PR adds/removes an experimental interfaces and I've updated this doc.
  • I tagged two reviewers because this PR makes queries to the database or I think it might have some security impact.

Screenshots

before

Testing

  1. Test together with 1287-gh-Automattic/woopay
  2. Get a valid checkout_session by checking out with a valid email and filling in the OTP code.
  3. After you are on woopay's checkout page, update the code:
    In src/Checkout/PaymentsHandler.php, comment or remove the if around the exception:
// if ( empty( $customer_id ) ) {
    $session_data      = WooPaySession::UNSANITIZED_get_data();
    $blog_checkout_url = esc_url( add_query_arg( 'skip_platform_checkout', 'true', $session_data['store_data']['blog_checkout_url'] ) );
    /* translators: %1$s opening anchor tag with url, %2$s closing anchor tag */
    $error_message = __( 'we were unable to process your payment. Please %1$s go back to the merchant store %2$s and log into WooPay again.', 'woopay' );
    $open_tag      = '<a href="' . $blog_checkout_url . '">';
    $close_tag     = '</a>';
    throw new InvalidSessionException(
		sprintf( $error_message, $open_tag, $close_tag ),
    );
// }
  1. Test the link in the error message

Automated Tests

  • Changes in this PR are covered by Automated Tests.

    • Unit tests
    • E2E tests
  • Do not include in the Testing Notes

WooCommerce Visibility

  • WooCommerce Core
  • Feature plugin
  • Experimental

Performance Impact

Changelog

WooPay: fixed a compatibility issue with some error messages shown by WooPay.

@hsingyuc hsingyuc requested review from nerrad, opr and reykjalin and removed request for nerrad and opr September 13, 2022 19:51
@github-actions
Copy link
Contributor

The release ZIP for this PR is accessible via:

https://wcblocks.wpcomstaging.com/wp-content/uploads/woocommerce-gutenberg-products-block-7145.zip

@github-actions
Copy link
Contributor

github-actions bot commented Sep 13, 2022

Size Change: +41.1 kB (+5%) 🔍

Total Size: 934 kB

Filename Size Change
build/active-filters-frontend.js 7.61 kB -1 B (0%)
build/all-products-frontend.js 26.5 kB +8.32 kB (+46%) 🚨
build/all-products.js 34.1 kB +112 B (0%)
build/cart-blocks/cart-cross-sells-products--product-add-to-cart-frontend.js 5.43 kB -1 B (0%)
build/cart-blocks/cart-cross-sells-products-frontend.js 4.65 kB -5 B (0%)
build/cart-blocks/cart-line-items--mini-cart-contents-block/products-table-frontend.js 5.27 kB -3 B (0%)
build/cart-blocks/cart-totals-frontend.js 323 B +1 B (0%)
build/cart-blocks/empty-cart-frontend.js 346 B +1 B (0%)
build/cart-blocks/filled-cart-frontend.js 783 B +2 B (0%)
build/cart-blocks/order-summary-coupon-form-frontend.js 2.65 kB +2 B (0%)
build/cart-blocks/order-summary-discount-frontend.js 2.15 kB -1 B (0%)
build/cart-blocks/order-summary-fee-frontend.js 274 B +1 B (0%)
build/cart-blocks/order-summary-shipping--checkout-blocks/order-summary-shipping-frontend.js 6.36 kB -10 B (0%)
build/cart-blocks/order-summary-taxes-frontend.js 435 B +1 B (0%)
build/cart-blocks/proceed-to-checkout-frontend.js 1.16 kB +2 B (0%)
build/cart-frontend.js 56.2 kB +8.2 kB (+17%) ⚠️
build/cart.js 50.4 kB +120 B (0%)
build/checkout-blocks/billing-address-frontend.js 889 B -1 B (0%)
build/checkout-blocks/contact-information-frontend.js 2.83 kB -1 B (0%)
build/checkout-blocks/express-payment-frontend.js 5.37 kB +3 B (0%)
build/checkout-blocks/order-summary-cart-items-frontend.js 3.66 kB -4 B (0%)
build/checkout-blocks/order-summary-coupon-form-frontend.js 2.79 kB +1 B (0%)
build/checkout-blocks/order-summary-discount-frontend.js 2.27 kB +1 B (0%)
build/checkout-blocks/order-summary-shipping-frontend.js 601 B +1 B (0%)
build/checkout-blocks/payment-frontend.js 7.68 kB -1 B (0%)
build/checkout-blocks/shipping-methods-frontend.js 4.75 kB +2 B (0%)
build/checkout-blocks/terms-frontend.js 1.23 kB -1 B (0%)
build/checkout-frontend.js 58.1 kB +8.21 kB (+16%) ⚠️
build/checkout.js 43.8 kB +148 B (0%)
build/featured-category.js 13.2 kB +2 B (0%)
build/featured-product.js 13.4 kB -4 B (0%)
build/legacy-template.js 2.84 kB -3 B (0%)
build/mini-cart-component-frontend.js 16.9 kB -11 B (0%)
build/mini-cart-contents-block/footer--mini-cart-contents-block/products-table-frontend.js 4.69 kB +1 B (0%)
build/mini-cart-contents-block/footer-frontend.js 7.39 kB -1 B (0%)
build/mini-cart-contents-block/products-table-frontend.js 291 B +1 B (0%)
build/mini-cart-contents-block/title-frontend.js 368 B +1 B (0%)
build/mini-cart-frontend.js 1.72 kB -1 B (0%)
build/mini-cart.js 4.57 kB -1 B (0%)
build/price-filter.js 9.36 kB +3 B (0%)
build/product-add-to-cart--product-button--product-image--product-title.js 2.69 kB +1 B (0%)
build/product-add-to-cart-frontend.js 2.6 kB -2 B (0%)
build/product-add-to-cart.js 6.88 kB +4 B (0%)
build/product-best-sellers.js 7.7 kB +1 B (0%)
build/product-button-frontend.js 1.89 kB +3 B (0%)
build/product-categories.js 2.36 kB +2 B (0%)
build/product-category-list-frontend.js 881 B +2 B (0%)
build/product-category.js 8.69 kB +1 B (0%)
build/product-image.js 1.62 kB +4 B (0%)
build/product-new.js 7.69 kB +3 B (0%)
build/product-on-sale.js 8.02 kB -1 B (0%)
build/product-price-frontend.js 1.91 kB +1 B (0%)
build/product-price.js 1.53 kB -1 B (0%)
build/product-query.js 647 B +1 B (0%)
build/product-rating-frontend.js 1.18 kB -1 B (0%)
build/product-rating.js 773 B +2 B (0%)
build/product-sale-badge-frontend.js 1.14 kB +1 B (0%)
build/product-sale-badge.js 818 B +2 B (0%)
build/product-search.js 2.62 kB +2 B (0%)
build/product-stock-indicator-frontend.js 994 B +2 B (0%)
build/product-summary-frontend.js 1.28 kB +1 B (0%)
build/product-summary.js 921 B +1 B (0%)
build/product-tag-list-frontend.js 874 B +1 B (0%)
build/product-tag.js 8.05 kB -2 B (0%)
build/product-title-frontend.js 1.34 kB -1 B (0%)
build/product-top-rated.js 7.93 kB +1 B (0%)
build/products-by-attribute.js 8.62 kB +2 B (0%)
build/reviews-by-category.js 11.3 kB -1 B (0%)
build/reviews-by-product.js 12.4 kB -2 B (0%)
build/reviews-frontend.js 7.01 kB -9 B (0%)
build/single-product-frontend.js 29.4 kB +7.9 kB (+37%) 🚨
build/single-product.js 10.1 kB +1 B (0%)
build/stock-filter.js 7.56 kB +1 B (0%)
build/vendors--cart-blocks/cart-cross-sells-products--cart-blocks/order-summary-shipping--checkout-blocks--18f9376a-frontend.js 19.1 kB -2 B (0%)
build/vendors--cart-blocks/cart-cross-sells-products--product-add-to-cart-frontend.js 6.91 kB -3 B (0%)
build/vendors--cart-blocks/order-summary-shipping--checkout-blocks/billing-address--checkout-blocks/order--5b8feb0b-frontend.js 4.85 kB -2 B (0%)
build/wc-blocks-style-rtl.css 24 kB +130 B (+1%)
build/wc-blocks-style.css 23.9 kB +65 B (0%)
build/wc-blocks-vendors.js 62.4 kB +7.92 kB (+15%) ⚠️
ℹ️ View Unchanged
Filename Size
build/active-filters.js 8.29 kB
build/all-reviews.js 7.79 kB
build/attribute-filter-frontend.js 22.3 kB
build/attribute-filter.js 13.3 kB
build/blocks-checkout.js 17.5 kB
build/cart-blocks/cart-accepted-payment-methods-frontend.js 1.17 kB
build/cart-blocks/cart-cross-sells-frontend.js 253 B
build/cart-blocks/cart-express-payment-frontend.js 5.08 kB
build/cart-blocks/cart-items-frontend.js 299 B
build/cart-blocks/cart-line-items-frontend.js 430 B
build/cart-blocks/cart-order-summary-frontend.js 1.1 kB
build/cart-blocks/order-summary-heading-frontend.js 454 B
build/cart-blocks/order-summary-shipping-frontend.js 427 B
build/cart-blocks/order-summary-subtotal-frontend.js 274 B
build/checkout-blocks/actions-frontend.js 1.42 kB
build/checkout-blocks/billing-address--checkout-blocks/shipping-address-frontend.js 4.11 kB
build/checkout-blocks/fields-frontend.js 345 B
build/checkout-blocks/order-note-frontend.js 1.08 kB
build/checkout-blocks/order-summary-fee-frontend.js 276 B
build/checkout-blocks/order-summary-frontend.js 1.11 kB
build/checkout-blocks/order-summary-subtotal-frontend.js 275 B
build/checkout-blocks/order-summary-taxes-frontend.js 435 B
build/checkout-blocks/shipping-address-frontend.js 1.03 kB
build/checkout-blocks/totals-frontend.js 325 B
build/general-style-rtl.css 1.29 kB
build/general-style.css 1.29 kB
build/handpicked-products.js 7.33 kB
build/mini-cart-contents-block/empty-cart-frontend.js 366 B
build/mini-cart-contents-block/filled-cart-frontend.js 229 B
build/mini-cart-contents-block/items-frontend.js 237 B
build/mini-cart-contents-block/shopping-button-frontend.js 288 B
build/mini-cart-contents.js 23.4 kB
build/price-filter-frontend.js 13.4 kB
build/price-format.js 1.19 kB
build/product-add-to-cart--product-button--product-category-list--product-image--product-price--product-r--a0326d00.js 226 B
build/product-button--product-category-list--product-image--product-price--product-rating--product-sale-b--e17c7c01.js 432 B
build/product-button--product-image--product-rating--product-sale-badge--product-title.js 302 B
build/product-button.js 1.58 kB
build/product-category-list.js 503 B
build/product-image-frontend.js 1.91 kB
build/product-sku-frontend.js 380 B
build/product-sku.js 380 B
build/product-stock-indicator.js 623 B
build/product-tag-list.js 497 B
build/product-title.js 938 B
build/stock-filter-frontend.js 7.61 kB
build/vendors--cart-blocks/cart-cross-sells-products--cart-blocks/cart-line-items--cart-blocks/cart-order--04fe80d1-frontend.js 5.26 kB
build/vendors--cart-blocks/cart-line-items--checkout-blocks/order-summary-cart-items--mini-cart-contents---233ab542-frontend.js 3.14 kB
build/vendors--mini-cart-contents-block/footer-frontend.js 6.86 kB
build/wc-blocks-data.js 9.9 kB
build/wc-blocks-editor-style-rtl.css 5.24 kB
build/wc-blocks-editor-style.css 5.24 kB
build/wc-blocks-google-analytics.js 1.56 kB
build/wc-blocks-middleware.js 931 B
build/wc-blocks-registry.js 2.7 kB
build/wc-blocks-shared-context.js 1.51 kB
build/wc-blocks-shared-hocs.js 1.71 kB
build/wc-blocks-vendors-style-rtl.css 1.95 kB
build/wc-blocks-vendors-style.css 1.95 kB
build/wc-blocks.js 2.63 kB
build/wc-payment-method-bacs.js 816 B
build/wc-payment-method-cheque.js 811 B
build/wc-payment-method-cod.js 909 B
build/wc-payment-method-paypal.js 837 B
build/wc-settings.js 2.6 kB

compressed-size-action

@opr
Copy link
Contributor

opr commented Sep 14, 2022

Hey @hsingyuc could you check the first step of your testing instructions - looks like there's some shorthand there that didn't parse correctly and I want to be sure we're getting the right instructions.

Thanks!

@hsingyuc
Copy link
Contributor Author

@opr Thank you for pointing that out! I've updated the instructions.

@opr
Copy link
Contributor

opr commented Sep 14, 2022

@opr Thank you for pointing that out! I've updated the instructions.

Hey, I don't see the updated URL, could you let me know what PR you're referring to in step 1? Thanks!

@hsingyuc
Copy link
Contributor Author

@opr I think it's working now, can you try again? Thank you!

Copy link
Contributor

@opr opr left a comment

Choose a reason for hiding this comment

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

@hsingyuc thanks, the code looks good to me, @wavvves do you think this will solve #6800?

@@ -230,6 +230,7 @@
"config": "3.3.7",
"dataloader": "2.1.0",
"dinero.js": "1.9.1",
"dompurify": "^2.4.0",
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like dompurify already exists in the node_modules directory - we have it from @woocommerce/data. I don't think it's a problem to add it here.

Copy link
Contributor

Choose a reason for hiding this comment

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

It is not redundant if it becomes a dependency for this project, and then it should definitely be added here. Removing @woocommerce/data or it stopping being a dependency for it won't bubble up into problems here

@github-actions github-actions bot added this to the 8.6.0 milestone Sep 15, 2022
@wavvves
Copy link
Contributor

wavvves commented Sep 16, 2022

@hsingyuc thanks, the code looks good to me, @wavvves do you think this will solve #6800?

We could make use also of dompurify 👍🏼 , apart from that dangerouslySetInnerHTML sounds a lot like __unstableHtml.
Terrible naming from my pov, especially if we're whitelisting HTML elems and attributes while using it. Why not implement something that takes in HTML and whitelisted elements and attrib config, and then sets the content safely and properly for example?

@wavvves wavvves self-requested a review September 21, 2022 11:03
Copy link
Member

@nielslange nielslange left a comment

Choose a reason for hiding this comment

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

@hsingyuc I just added a comment regarding the use of sanitize() as I'm uncertain if the current implementation will work as expected.

Comment on lines +15 to +22
const ALLOWED_TAGS = [ 'a', 'b', 'em', 'i', 'strong', 'p', 'br' ];
const ALLOWED_ATTR = [ 'target', 'href', 'rel', 'name', 'download' ];

const sanitizeHTML = ( html ) => {
return {
__html: sanitize( html, { ALLOWED_TAGS, ALLOWED_ATTR } ),
};
};
Copy link
Member

Choose a reason for hiding this comment

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

@hsingyuc While working on #7147, I was reusing this part. When looking at ALLOWED_TAGS and ALLOWED_ATTR, I noticed that they're not working as expected. https://github.com/cure53/DOMPurify#can-i-configure-dompurify shows the following example:

// allow only <b> and <q> with style attributes
var clean = DOMPurify.sanitize(dirty, {ALLOWED_TAGS: ['b', 'q'], ALLOWED_ATTR: ['style']});

Looking at the implementation above, I'd say that the current implementation would lead to this function call:

const sanitizeHTML = ( html ) => {
	return {
		__html: sanitize( html, { 
			[ 'a', 'b', 'em', 'i', 'strong', 'p', 'br' ],
			[ 'target', 'href', 'rel', 'name', 'download' ]
		} ),
	};
};

I believe the function should be called like this instead:

const sanitizeHTML = ( html ) => {
	return {
		__html: sanitize( html, { 
			ALLOWED_TAGS: [ 'a', 'b', 'em', 'i', 'strong', 'p', 'br' ],
			ALLOWED_ATTR: [ 'target', 'href', 'rel', 'name', 'download' ]
		} ),
	};
};

If that assumption is correct, I suggest the following change:

Suggested change
const ALLOWED_TAGS = [ 'a', 'b', 'em', 'i', 'strong', 'p', 'br' ];
const ALLOWED_ATTR = [ 'target', 'href', 'rel', 'name', 'download' ];
const sanitizeHTML = ( html ) => {
return {
__html: sanitize( html, { ALLOWED_TAGS, ALLOWED_ATTR } ),
};
};
const tags = [ 'a', 'b', 'em', 'i', 'strong', 'p', 'br' ];
const attr = [ 'target', 'href', 'rel', 'name', 'download' ];
const sanitizeHTML = ( html ) => {
return {
__html: sanitize( html, { ALLOWED_TAGS: tags, ALLOWED_ATTR: attr } ),
};
};

cc: @opr and @wavvves

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@nielslange, in ES6, it converts to below. If converted to the way you wrote, I believe we will get an error.

{ 
    ALLOWED_TAGS:   [ 'a', 'b', 'em', 'i', 'strong', 'p', 'br' ]
} 

@sunyatasattva sunyatasattva merged commit 0038f60 into trunk Sep 23, 2022
@sunyatasattva sunyatasattva deleted the fix/woopay-1130 branch September 23, 2022 18:48
@sunyatasattva
Copy link
Contributor

Merged this despite false positive of CI jobs failing. The main culprit was the linter not finding a report file:

The report-json file "${report}" could not be resolved.

This is unlikely to be due to this PR, although in retrospective it might be related to the change in package-lock.json. I'll keep an eye on this and see whether this is the case.

senadir pushed a commit to senadir/woocommerce-blocks that referenced this pull request Nov 12, 2022
Sanitizing the merchant store link in the error message added in WooPay when in some
cases the customer could run into an issue where we need to tell them an error occurred
and they have to go back to the merchant store and re-initialize WooPay to fix it.

Because previously we were only expecting strings, the text was not sanitized.
senadir pushed a commit to senadir/woocommerce-blocks that referenced this pull request Nov 12, 2022
Sanitizing the merchant store link in the error message added in WooPay when in some
cases the customer could run into an issue where we need to tell them an error occurred
and they have to go back to the merchant store and re-initialize WooPay to fix it.

Because previously we were only expecting strings, the text was not sanitized.
senadir pushed a commit to senadir/woocommerce-blocks that referenced this pull request Nov 20, 2022
Sanitizing the merchant store link in the error message added in WooPay when in some
cases the customer could run into an issue where we need to tell them an error occurred
and they have to go back to the merchant store and re-initialize WooPay to fix it.

Because previously we were only expecting strings, the text was not sanitized.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants