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

security: gh security recs #3368

Merged
merged 13 commits into from
Apr 2, 2024
Merged

security: gh security recs #3368

merged 13 commits into from
Apr 2, 2024

Conversation

hay-kot
Copy link
Collaborator

@hay-kot hay-kot commented Mar 24, 2024

What type of PR is this?

(REQUIRED)

  • security
  • bug

What this PR does / why we need it:

Addresses several security concerns raised by external audit/review

  1. All user HTTP requests now use a custom Transport class that applies a timeout and blocks known internal address spaces
  2. Note that you can't simple whitelist specific IP's, you must resolve the domain name first and then check the address space of the resolved IP. This prevents attackers from creating a DNS entry that resolves to a local address space and using that url to attack a Mealie instance.

Also, note that these are mitigations, they are not 100% fixes.

Which issue(s) this PR fixes:

Special notes for your reviewer:

I've tested locally and all the automated testing should pass. If possible, I would like another reviewer to pull down these changes and attempt to

  1. Scrape a few recipes from different domains
  2. Use the Scrape Image functionality to pull external images into Mealie from a few different domains.

Testing

See Above

@hay-kot hay-kot marked this pull request as ready for review March 25, 2024 15:56
@boc-the-git boc-the-git self-assigned this Mar 26, 2024
Copy link
Collaborator

@boc-the-git boc-the-git left a comment

Choose a reason for hiding this comment

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

The code changes all look good.
In testing the happy path, everything went well (i.e. I can still import recipes and images from legitimate internet sites.

In testing the negative path (trying to access things on my internal network), things came unstuck.

This first series of images is when accessing my Vikunja instance via the URL/reverse proxy (note I installed ping in the dev container to confirm what it's resolving to):
image
image
image

Then for a further test, I popped the IP/port in directly, avoiding the reverse proxy and any DNS resolution:
image

@hay-kot I'm interested in whether you can replicate this scenario.

I dug a bit deeper, and wanted to get some evidence of what was happening, which this code change and error message shows.. effectively the IP is None, rather than 192.168.x.y as I'd expect.
image

@p0lycarpio
Copy link
Contributor

Along the same lines as the ALLOW_SIGNUP variable which was set to False, I suggest setting all groups to private by default when they are created. This is an additional security measure and also when using Mealie for the first time the user would be redirected to the login/welcome page instead of the empty group.
What is your opinion ?

The change would be made in the group_preferences.py schema. I don't know the impacts though.

@boc-the-git
Copy link
Collaborator

@p0lycarpio do you want to raise a feature request for that (or discuss it on Discord)?
We wouldn't likely tackle that under this PR.

That's more a privacy issue than a security issue, if you take my meaning.
I don't have strong feelings on it one way or the other; other people might.

@hay-kot
Copy link
Collaborator Author

hay-kot commented Apr 1, 2024

@boc-the-git should be good now. Thanks to some folks on discord it's 99% less bad too!

netloc = request.url.netloc.decode()
if ":" in netloc: # Either an IP, or a hostname:port combo
netloc_parts = netloc.split(":")
if len(netloc_parts) > 1: # netloc of username:password@hostname:port not supported
Copy link
Collaborator

Choose a reason for hiding this comment

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

The check here doesn't align with the comment.. should this be checking for ... > 2?
I won't stop this delaying a merge, but will circle back to it, via Discord.

Copy link
Collaborator

Choose a reason for hiding this comment

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

... > 1 will always be true, except in some weird scenario where : was the first or last character of netloc (and tbh I'm not certain what happens in that scenario)

Copy link
Contributor

Choose a reason for hiding this comment

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

It was a typo.

mealie/pkgs/safehttp/transport.py Outdated Show resolved Hide resolved
mealie/pkgs/safehttp/transport.py Show resolved Hide resolved
@@ -46,8 +46,6 @@ async def handle_async_request(self, request):
netloc = request.url.netloc.decode()
if ":" in netloc: # Either an IP, or a hostname:port combo
netloc_parts = netloc.split(":")
if len(netloc_parts) > 1: # netloc of username:password@hostname:port not supported
Copy link
Collaborator

Choose a reason for hiding this comment

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

@hay-kot see this log.. showing that even when user:pass is included in the url, it was being stripped out before getting to this netloc variable. Thus, the check on parts is irrelevant here.

image

@boc-the-git
Copy link
Collaborator

@hay-kot this has my blessing, but note I had to make a fix. Please review, and merge/release as desired.

@hay-kot hay-kot merged commit 2a3463b into mealie-next Apr 2, 2024
10 checks passed
@hay-kot hay-kot deleted the security/gh-security-recs branch April 2, 2024 15:04
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.

None yet

4 participants