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

Use htmlspecialchars on trans parameters and deprecate _raw parameter #31900

Merged
merged 3 commits into from Apr 12, 2023

Conversation

mflasquin
Copy link
Contributor

Questions Answers
Branch? develop
Description? Use htmlspecialchars on trans parameters and deprecate _raw parameter, next decision of this PR #30415
Type? improvement
Category? BO
BC breaks? yes
Deprecations? yes
How to test? See #30415 and #28877 and #29959 and #29940
Fixed ticket? Fixes #30539
Related PRs #30415
Sponsor company Prestashop SA

@mflasquin mflasquin requested a review from a team as a code owner March 23, 2023 16:30
@prestonBot prestonBot added develop Branch Improvement Type: Improvement BC break Type: Introduces a backwards-incompatible break labels Mar 23, 2023
Copy link
Contributor

@matthieu-rolland matthieu-rolland left a comment

Choose a reason for hiding this comment

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

looks good to me 👍

lartist
lartist previously approved these changes Mar 28, 2023
@lartist lartist added the Waiting for QA Status: action required, waiting for test feedback label Mar 28, 2023
@florine2623 florine2623 self-assigned this Mar 28, 2023
Copy link
Contributor

@florine2623 florine2623 left a comment

Choose a reason for hiding this comment

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

Hello @mflasquin ,

Checked all of the issues mentioned in the PR : #28877 and #29959 and #29940

One issue still remains : #29959
Screenshot 2023-03-28 at 14 08 30

The rest looks as expected.

Could you check please ?
Thanks!

@florine2623 florine2623 removed their assignment Mar 28, 2023
@florine2623 florine2623 added Waiting for author Status: action required, waiting for author feedback and removed Waiting for QA Status: action required, waiting for test feedback labels Mar 28, 2023
@mflasquin
Copy link
Contributor Author

Hi @florine2623, I can't reproduce the issue :
image

Can you make another test ? Or we can discuss about it directly

@mflasquin mflasquin added Waiting for QA Status: action required, waiting for test feedback and removed Waiting for author Status: action required, waiting for author feedback labels Mar 29, 2023
@florine2623 florine2623 added Waiting for author Status: action required, waiting for author feedback and removed Waiting for QA Status: action required, waiting for test feedback labels Mar 29, 2023
@florine2623
Copy link
Contributor

As discussed with @mflasquin ,

The issue needs more investigation.

Thanks!

@mflasquin mflasquin closed this Mar 29, 2023
@mflasquin mflasquin reopened this Mar 29, 2023
@mflasquin mflasquin removed the Waiting for author Status: action required, waiting for author feedback label Apr 11, 2023
@mflasquin mflasquin added the Waiting for QA Status: action required, waiting for test feedback label Apr 11, 2023
@djoelleuch djoelleuch self-assigned this Apr 11, 2023
Copy link

@djoelleuch djoelleuch left a comment

Choose a reason for hiding this comment

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

Hello @mflasquin ,
The issues are well fixed , It's QA approved ✔️
Automated tests --> OK

Thank you for you PR 🚀

@djoelleuch djoelleuch added QA ✔️ Status: check done, code approved and removed Waiting for QA Status: action required, waiting for test feedback labels Apr 12, 2023
@prestonBot
Copy link
Collaborator

QA approved, well done! Message to the maintainers: do not forget to milestone it before the merge.

@Progi1984 Progi1984 added this to the 9.0.0 milestone Apr 12, 2023
@PululuK
Copy link
Member

PululuK commented Apr 12, 2023

Thanks @mflasquin

@PululuK PululuK merged commit bb2af6e into PrestaShop:develop Apr 12, 2023
43 checks passed
@Tofandel
Copy link
Contributor

Doesn't this PR introduce a security issue, now translations are not HTML escaped, so translations are XSS vulnerable

I believe it should be the opposite, the translation output should be html escaped but parameters should not, like this parameters can contain html but translations never can

Comment on lines +110 to +114
$trans = $transMethod->invoke($newObject, '<a href="test">%d Succesful deletion "%s"</a>', [10, '<b>stringTest</b>'], 'Admin.Notifications.Success');
$this->assertEquals('<a href="test">10 Succesful deletion "<b>stringTest</b>"</a>', $trans);

$trans = $transMethod->invoke($newObject, '<a href="test">%d Succesful deletion "%s"</a>', [10, '<b>stringTest</b>'], 'Admin.Notifications.Success');
$this->assertEquals('&lt;a href="test"&gt;10 Succesful deletion "&lt;b&gt;stringTest&lt;/b&gt;"&lt;/a&gt;', $trans);
$trans = $transMethod->invoke($newObject, '<a href="test">%d Succesful deletion "%s"</a>', [10, htmlspecialchars('<b>stringTest</b>')], 'Admin.Notifications.Success');
$this->assertEquals('<a href="test">10 Succesful deletion "&lt;b&gt;stringTest&lt;/b&gt;"</a>', $trans);
Copy link
Contributor

@Tofandel Tofandel Aug 18, 2023

Choose a reason for hiding this comment

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

This test should normally look like this for XSS to be mitigated, so that when you want to output html tags, you can do so in parameters

        $trans = $transMethod->invoke($newObject, '<a href="test">%d Succesful deletion "%s"</a>', [10, '<b>stringTest</b>'], 'Admin.Notifications.Success');
        $this->assertEquals('&lt;a href="test"&gt;10 Succesful deletion "<b>stringTest</b>"&lt;/a&gt;', $trans);

Like this there is no need for _raw and translations can't by themselves inject html unless the parameters are not escaped, I'd still probably escape each parameter by default and provide a parameter to allow parameters to not be escaped making it much safer

Copy link
Contributor

Choose a reason for hiding this comment

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

@Tofandel This PR is the final result of years long discussion 😄 see #30415 (review)

Yes it introduces a security issue but this is because it fixes a design issue. A necessary security step was added in the wrong place and we now remove it from this wrong place. The escaping should not happen inside trans().

Copy link
Contributor

@Tofandel Tofandel Aug 18, 2023

Choose a reason for hiding this comment

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

The escaping should not happen inside trans()

It should, but the escaping is indeed in the wrong place, you cannot be sure that what you are getting from a translation is safe

So to achieve that you escape the output of the retrieved translation but do not escape the parameters

This is the only way to achieve XSS safety

I can provide a super simple XSS demo with this, and it should not be released like this, that's a 7 out of 10 CVE because it allows translators of a site to inject html anywhere they want and then gain unauthorized access by data exfiltration

Copy link
Contributor

@matks matks Aug 18, 2023

Choose a reason for hiding this comment

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

trans() is a function that is supposed to translate strings. It has nothing to do with security. Security should not be handled inside trans().

Escaping properly HTML before sending it to user is not the responsibility of the translator, it is the responsibility of the controller/view layer.

I can provide a super simple XSS demo with this, and it should not be released like this, that's a 7 out of 10 CVE because it allows translators of a site to inject html anywhere they want and then gain unauthorized access by data exfiltration

From the Back-office, it is possible to upload a SVG image which can carry a XSS too. Translators can only "inject" HTML if they provide translations that are being imported into PrestaShop from the Back-office. That means they have been trusted by the Back-office administrator to be granted access to the Back-office or he trusted them when they provided translation files. If they have been trusted but they use this trust to inject HTML, the problem is that the Back-office administrator trusted the wrong persons, it's not a problem with the Back-office.

You can see translation files as inputs just like modules. If a merchant installs a garbage module, it could crash his shop, it could expose vulnerable code that makes his shop vulnerable. The problem is not that PrestaShop did not "prevent" or "validate" the wrong module: installing only trusted modules is the responsibility of the shop owner.

Copy link
Contributor

@Tofandel Tofandel Aug 19, 2023

Choose a reason for hiding this comment

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

I'll have to disagree, in big companies access control is very important. It's even common to outsource translation to freelancers that should only be given permission to the translation in the back office and nothing else

But if now they start to also have the ability to inject scripts transparently wherever they please without anyone noticing, effectively installing backdoors then there is a big problem

Translation should never allow html in from the translator side, translators have no business touching html markup, so it should be escaped. The global output of the translation though shouldn't be escaped, just the original translation string with the placeholders still in them

If html needs to be used for links or other, that's when the placeholders and parameters come in handy because those which are provided by the code will not be escaped

My point being, this design issue has a much safer possible solution, so why not use that instead of introducing an XSS willingly? That makes no sense

The argument being used is basically, prestashop is already unsafe, so it doesn't matter if we make it more unsafe. When it should be prestashop has some safety issues, we should aim to make it safer

Copy link
Contributor

@matks matks Aug 21, 2023

Choose a reason for hiding this comment

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

This PR is the last step of a discussion and analyzis that has been going on since October 2022 so please trust us when I tell you it's the best compromise we could get 😉

Escaping HTML? It's a good thing.
Doing it inside trans() ? It's not a good idea. It brings you hundred of other problems.

The idea of this PR is not "let's remove HTML escaping" it's "let's move the HTML escaping to the right place".

If you do not understand the reasons behind it, I can show you the history:

Sorry I don't want to continue writing hundred words of explanation ^^ this is a topic that span for 8 months now so I have not enough motivation to tell you every aspects of it that brought us to this conclusion.

If, after reading all of the history, you can provide an interesting solution that meets all criteria, including fixing bug #29940 without breaking something else, then I'll be happy to review it 😉

Copy link
Contributor

@Tofandel Tofandel Aug 21, 2023

Choose a reason for hiding this comment

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

Doing it inside trans() ? It's not a good idea. It brings you hundred of other problems.

It's not doing it inside of trans that gives problems, it's doing it on the whole content of trans

The idea of this PR is not "let's remove HTML escaping" it's "let's move the HTML escaping to the right place".

The problem with this decision is as before, you can only either escape everything or not escape anything, the right place to escape is as I explained, inside trans but not to it's entire content, so that translations and parameters can be escaped separately, so trans needs a parameter to escape the content of the string without escaping the content of parameters, which would move the logic more nested inside the trans function instead of just blindly escaping everything, which would entirely solve the XSS issue and all the problems previously listed

I already read all the history and provided my solution in written form, which now with this PR should be straightforward to implement and would not introduce a breaking change

I'd be happy to make a PR when I have time if you agree with the solution I'm giving, but please do consider the security implications from this and hold on a release until the PR to fix this

Copy link
Contributor

Choose a reason for hiding this comment

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

Hi @Tofandel I just wanted to tell you I don't forget you, this message is inside my todolist and I have requested the help of someone else on this topic because I can't handle everything.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
BC break Type: Introduces a backwards-incompatible break develop Branch Improvement Type: Improvement QA ✔️ Status: check done, code approved
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

Delete _raw parameter in trans methods
10 participants