Closed Bug 1757977 Opened 4 years ago Closed 4 years ago

Remote Code Execution via hg argument injection

Categories

(Websites :: Pontoon Security Issues, defect)

Production
defect

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: alessio.dellalibera, Assigned: mathjazz)

Details

(Keywords: reporter-external, sec-high, wsec-injection)

Steps to reproduce:

Hi, my name is Alessio and I am contacting you on behalf of Snyk Security team.
I am contacting you in regards to a Remote Code Execution vulnerability within your maintained project https://github.com/mozilla/pontoon

Steps to Reproduce:

  1. Install pontoon locally (I used Docker)
  1. RCE Exploitation
    In order to demonstrate this vulnerability, the output of the command id will be redirected in a static resource that is accessible from the web application
  • visit http://localhost:8000/admin/projects/
  • set Name and slug project
  • select one Locales
  • In the Repositories section, select Type HG
  • in the URL field paste --config=alias.clone=!id>/app/pontoon/base/static/img/output_rce.html (it will redirect the output of the command id to output_rce.html that is accessible by the web app)
  • set the Public Repository Website with a valid url (i.e http://localhost)
  • click Save Project
  • click Sync
  • the output of the id command will be available at http://localhost:8000/static/img/output_rce.html

Actual results:

It's possible to get remote code execution via argument injection.

When creating a new project, the unsanitized user input source (the URL) is used in the hg clone command (https://github.com/mozilla/pontoon/blob/f000a47d7ff18cdae1c84b306711d34816f1db52/pontoon/sync/vcs/repositories.py#L80).
hg allows to define hooks or aliases:

If the user controlled value (url) is for example --config=alias.clone=!id , and the shell command executed is hg clone <user_input>, the command id will be executed.

Regarding the ! here you can find more reference (https://www.mercurial-scm.org/doc/hgrc.5.html#alias)

By following the previous steps, it was possible to execute arbitrary commands using the create new projects functionality.

Expected results:

A new project should have been created (instead of executing arbitrary commands).

I followed the SECURITY policy here https://github.com/mozilla/pontoon/blob/master/SECURITY.md to submit a security vulnerability.
Please let me know if something is not clear.

Hello Matjaz,

I haven't tried to reproduce this issue yet but it sounded critical so it might help if you can take a look too.

Thanks,
Frida

Flags: needinfo?(m)

Hello Alessio,

Thank you so much for your detailed report, and for using a local version of Pontoon to test. We appreciate the care that went into reporting the issue.

We will try to reproduce the issue to confirm.

Thanks,
Frida

Hello Alessio,

I am trying to understand how the resulting command is executed, would it look like the below command?

hg clone --config=alias.clone=!id test-target

and then subsequent commands that use clone, would actually execute id?

Hi Team,

I hope you are well.

From the documentation: aliases "allow you to define your own commands in terms of other commands (or aliases), optionally including arguments. .... An alias can start with an exclamation point ("!") to make it a shell alias. A shell alias is executed with the shell and will let you run arbitrary commands. As an example,
echo = !echo $@
will let you do "hg echo foo" to have "foo" printed in your terminal.
" (https://www.mercurial-scm.org/doc/hgrc.5.html#alias)

On the other hand, hooks "commands or Python functions that get automatically executed by various actions such as starting or finishing a commit." (https://www.mercurial-scm.org/doc/hgrc.5.html#hooks). So for example you can execute a command before (using the pre prefix) a mercurial command.

Aliases example.
Running the following code in the terminal will execute the touch command:

hg clone --config=alias.clone=""'!'"touch HELLO1"

From a code perspective, it will look like the following:

import subprocess

user_input = "--config=alias.clone=!touch HELLO2"
subprocess.Popen(["hg", "clone", user_input], shell=False)

Hooks example.
Alternatively, it's possible to use hooks to execute arbitrary commands.
In the following case the command touch is executed before the command hg clone is executed (it's executed before because of the pre hook - https://www.mercurial-scm.org/doc/hgrc.5.html#hooks):

hg clone --config=hooks.pre-clone="touch HELLO3"

From a code perspective, it will look like the following:

import subprocess

user_input = "--config=hooks.pre-clone=touch HELLO4"
subprocess.Popen(["hg", "clone", user_input], shell=False)

In case you are interested here there are some references to similar issues:

Please let me know if you need any help with the PoC.

Thanks a lot and have a nice day.
Alessio

Flags: needinfo?(m)

Alessio, thank you for your excellent catch and report!

While the vulnerability can only be exploited by users we trust and hence have permission to cause other issues if they choose to do so (e.g. delete projects, users, translations, etc.), this is certainly a valid security bug that needs to be addressed.

We've released an update for Pontoon which validates the Repository URL field, as well as notified other users of Pontoon to update their instances, including on our forum.

Assignee: nobody → m
Status: UNCONFIRMED → RESOLVED
Closed: 4 years ago
Resolution: --- → FIXED

Hi Matjaz and Team,

Thanks a lot for your prompt reply and for the update!

It has been really a pleasure.

If you don't mind, I have a couple of questions:

  1. Would it be possible to be mentioned/credited in the announcement (https://discourse.mozilla.org/t/security-fix-repository-url-validation/94362)?
  2. Since we are planning to publish a blog post (late April/May) about a research into argument injections vulnerabilities, we would like to mention the aforementioned issue as a case study (PoC, details, vulnerable code, how it has been fixed, etc..) in our blog post, but before doing so, I would like to know if for you it's ok or if you have any objection.
  3. Just out of curiosity, does this security vulnerability apply for the "Mozilla Web and Services Bug Bounty Program" (https://www.mozilla.org/en-US/security/web-bug-bounty/) or at least for being listed in your Hall of Fame? I quickly checked and the pontoon.mozilla.org service it's under the core services eligible by that program (https://www.mozilla.org/en-US/security/bug-bounty/web-eligible-sites/#core-sites). I just want to make it clear that I'm not asking this for the bounty (if this security issue will be eligible, in any case I will propose to donate the total amount), but just for my personal curiosity.

I want to thank you so much for your efforts and very quick response to this.
Have a nice day,
Alessio Della Libera

Hi Alessio,

Thank you once again for your great contribution to make our products safer!

  1. Happy to! I've just updated the blog post. Please let me know if you'd like me to make any amendments, point URL elsewhere etc.

  2. I'm fine with that. I think it makes sense to give other users some time to update, and publishing in April allows for that.

  3. I'll let :frida or somebody from the security team answer your last question.

Flags: needinfo?(fkiriakos)
Flags: needinfo?(fkiriakos) → sec-bounty+

Hello Alessio,

I just flagged this report to be considered for bug bounty.

For future reference, we recommend sending us reports using our web bug bounty form. You can find the form on this link: https://bugzilla.mozilla.org/form.web.bounty.

We can disclose the bug in April so you can include it in your documentation.

Thanks,
Frida

Flags: sec-bounty+ → sec-bounty?
Whiteboard: [disclosure in April]

(In reply to Matjaz Horvat [:mathjazz] from comment #7)

Hi Alessio,

Thank you once again for your great contribution to make our products safer!

  1. Happy to! I've just updated the blog post. Please let me know if you'd like me to make any amendments, point URL elsewhere etc.

  2. I'm fine with that. I think it makes sense to give other users some time to update, and publishing in April allows for that.

  3. I'll let :frida or somebody from the security team answer your last question.

Hi Matjaz,

thanks a lot for your prompt reply (I'm impressed) and also thanks a lot for updating the announcement.

Again, thanks a lot for everything.
Kind Regards,
Alessio

(In reply to Frida Kiriakos [:frida] from comment #8)

Hello Alessio,

I just flagged this report to be considered for bug bounty.

For future reference, we recommend sending us reports using our web bug bounty form. You can find the form on this link: https://bugzilla.mozilla.org/form.web.bounty.

We can disclose the bug in April so you can include it in your documentation.

Thanks,
Frida

Hi Frida,

thanks a lot for taking a look at this and sorry if I haven't reported in the other form (I followed the SECURITY policy here https://github.com/mozilla/pontoon/blob/master/SECURITY.md in the project repository).

Thanks.
Kind Regards,
Alessio

no worries at all, following the security policy in the repo is also correct.

Flags: sec-bounty? → sec-bounty+

Hi Team,
I just saw an update of the ticket.

Thanks for answering all the questions.
I see this report is eligible for the bounty! Due to our internal policies at Snyk, may I please request that the bounty will be donated to a charity of your choice?

Thank you so much for everything.
Kind Regards,
Alessio

Thanks Alessio, I think we can take care of that but will confirm with the bounty team to be sure.

Usually bugs eligible for bounty are also eligible for mention in our hall of fame, how would you like to be mentioned there? https://www.mozilla.org/en-US/security/bug-bounty/web-hall-of-fame/

Hi Frida,

thanks a lot for your prompt reply. Great!
About the mention in your hall of fame, you can use my name and surname: Alessio Della Libera .

Thanks a lot.
Kind Regards,
Alessio

Note for reference, based on Pontoon risk profile, we re-categorized it as a Critical site. Critical sites have a higher bounty payout and I just modified the bounty to reflect that.

Hi Team,

this is simply amazing! Thanks for the update. As stated in a previous message, due to our internal policies at Snyk, may I please request that the bounty will be donated to a charity of your choice?
If possible, it would be great (due to the current events) to support a Ukrainian charity.

Thanks a lot again the update!!
Kind Regards,
Alessio

Hello Alessio,

Our bounty team are working on donating the bounty, I am not very involved in this aspect so unfortunately, I don't have a lot of info.

Thanks,
Frida

Hi Team,

I hope you are well.
I was wondering, would it be possible to disclose this report?

If it's not possible, there is absolutely no problem.

Thanks a lot and have a nice day.
Kind Regards,
Alessio

Group: websites-security
Whiteboard: [disclosure in April]

Hello Alessio,

Hope you are well too.

I have disclosed the bug, we were waiting on your confirmation for disclosure.

Thanks,
Frida

Thanks a lot Frida.
Kind Regards,
Alessio

You need to log in before you can comment on or make changes to this bug.