Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: prevent special characters from url #1266

Conversation

lauramargar
Copy link
Contributor

@lauramargar lauramargar commented Aug 28, 2023

Pull request template

To prevent a Cross-site Scripting attack, we must be careful with the characters we allow to type a query. We already have a function to avoid that when a user types in the search box. But we also need to check if there are any special characters when a query is typed through the URL.

Motivation and context

  • Dependencies. If any, specify:
  • Open issue. If applicable, link: EMP-1745

Type of change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that causes existing functionality to not work as expected)
  • Change requires a documentation update

What is the destination branch of this PR?

  • Main
  • Other. Specify:

How has this been tested?

Try to type a special character (<>) in the URL query.

Checklist:

  • My code follows the style guidelines of this project.
  • I have performed a self-review on my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have made corresponding changes to the documentation.
  • My changes generate no new warnings.
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes.

feat: prevent special characters from url
@lauramargar lauramargar requested a review from a team as a code owner August 28, 2023 12:19
@annacv
Copy link
Contributor

annacv commented Aug 28, 2023

Hi! I have 2 doubts:

  • Should we remove the code between <> from the URL?
  • Should this prevent special keys be applied also for extraParams?? I tried with http://localhost:8080/?q=sunglasses&store=%3Cdetails%20%253e%20open%3D1%20ontoggle%3D%22n%3D%2Fal%2F.source.concat%28%2Fert%2F.source%29%2Cx%3Ddocument%2Ca%3Dwindow%5Bn%5D%2Ca%28x.domain%29%22%3E, and when I deleted the query and typed again (this or another query), it kept those characters in the new search.

@@ -156,7 +163,10 @@
protected emitEvents(): void {
const { all, extra } = this.parseUrlParams();
const metadata = this.createWireMetadata();
this.$x.emit('ParamsLoadedFromUrl', all, metadata);
this.preventSpecialKey(all.query);
if (!this.hasSpecialKeys) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Just curious, I think I like the approach, but why are we preventing to emit the event if we have special keys instead of removing them, and send send it without them?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do you prefer to remove the special keys instead of the whole query? I mean, if you have this query round <hola> shirt, it would be transformed into round shirt and sent into the ParamsLoadedFromUrlevent.

I use this approach because, in the task description, I understood that we have to clean/remove the whole query. But for me makes more sense to remove only the special characters and the string inside them.

@@ -165,6 +175,18 @@
this.urlLoaded = true;
}

/**
* Prevents the user from either typing or pasting special characters in the url query.
Copy link
Contributor

Choose a reason for hiding this comment

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

I would say:

Suggested change
* Prevents the user from either typing or pasting special characters in the url query.
* Detects if the user is typing or pasting special/forbidden characters in the URL query

*/
protected preventSpecialKey(query: string): void {
if (/[<>]/.test(query ?? '')) {
this.hasSpecialKeys = true;
Copy link
Contributor

Choose a reason for hiding this comment

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

Why storing this value in hasSpecialKeys protected property instead of returning true/false in this function and then test it on line 167. I mean, I would change this function name to hasSpecialKeys and then test:

if (!this.hasSpecialKeys(this query)) {

Comment on lines 166 to 167
this.preventSpecialKey(all.query);
if (!this.hasSpecialKeys) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
this.preventSpecialKey(all.query);
if (!this.hasSpecialKeys) {
if (this.hasSpecialKeys(all.query)) {

Comment on lines 184 to 187
protected preventSpecialKey(query: string): void {
if (/[<>]/.test(query ?? '')) {
this.hasSpecialKeys = true;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
protected preventSpecialKey(query: string): void {
if (/[<>]/.test(query ?? '')) {
this.hasSpecialKeys = true;
}
protected hasSpecialKeys(query: string): void {
return (/[<>]/.test(query ?? ''))

@annacv
Copy link
Contributor

annacv commented Sep 5, 2023

Hi! I will add this reference here, maybe it would be worth to give it a chance: https://github.com/braintree/sanitize-url/blob/main/src/index.ts

@lauramargar
Copy link
Contributor Author

Hi! I will add this reference here, maybe it would be worth to give it a chance: https://github.com/braintree/sanitize-url/blob/main/src/index.ts

We have an util in X https://github.com/empathyco/x/blob/main/packages/x-components/src/utils/sanitize.ts . I have already made the new approach.

@diegopf diegopf self-requested a review September 5, 2023 12:33
@@ -255,10 +256,13 @@
const urlKey = this.getUrlKey(name);
if (urlSearchParams.has(urlKey)) {
if (name in initialUrlState) {
const urlValue = urlSearchParams.getAll(urlKey);
let urlValue = urlSearchParams.getAll(urlKey);
urlValue[0] = sanitize(urlValue[0]);
Copy link
Contributor

Choose a reason for hiding this comment

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

To be safe we should sanitize all values and not just the first one. The query only has one occurrence but potentially any parameter could be malicious.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

urlValue is not only query param, all URL params are passing one by one. [0] is necessary because urlValue is an array of only one element, the param that is being checked.

For example, try to search for a query and select a filter, then write the special characters (<>) in the filter and in the query.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry, I think I did not explain properly 😅 What I meant is that a url param can have more than one occurrence. Think about filters, you can select more than one filter at the same time. In that scenario you get an array with multiple entries like:

['categoryIds:12fad53d7', 'price:1600.0-2000.0']

so if you only pick the first element, you will fail to sanitize the other values.

@herrardo herrardo closed this Sep 12, 2023
@herrardo
Copy link
Contributor

This PR is being closed as we decided that we will solve this problem in the Archetype, not letting certain information to be applied to the website through v-html directives

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants