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

fix(server): Security fix: only listen to private network address by default #2865

Closed

Conversation

eirslett
Copy link
Contributor

@eirslett eirslett commented Apr 5, 2021

See also #2820 which makes this problem critically worse.

Up until now, Vite has been listening on all public IP addresses
by default, which could be a potential security vulnerability.

This fixes the default behavior, so Vite only listens on 127.0.0.1.

You can get the old behavior back (listen to all IPs) by running
with the --listen-public CLI flag, or setting

export default defineConfig({
  server: {
    listenPublic: true
  }
  // ... more config here
})

in the Vite config file.

This is how the two alternatives look like in the terminal: You can see that it writes "(disabled)" next to the public IP.

Skjermbilde 2021-04-06 kl  00 18 31

@furudean
Copy link

furudean commented Apr 5, 2021

How about we just render the message stating its disabled instead of showing the address? It can't be accessed after all. This avoids some unnecessary information shown to the user.

Something like:

local:    http://localhost:3000
network:  (disabled)

Additionally we could hint toward how to open the gates to the network:

Use --host to expose server to other devices on this network

@antfu
Copy link
Member

antfu commented Apr 6, 2021

Instead of the "listenPublic" options, maybe it's more straightforward to let users use host.

@antfu antfu added p4-important Violate documented behavior or significantly improves performance (priority) security labels Apr 6, 2021
@eirslett
Copy link
Contributor Author

eirslett commented Apr 6, 2021

Instead of the "listenPublic" options, maybe it's more straightforward to let users use host.

Yes, that's more straightforward, at least a bit easier from an implementation perspective inside Vite. And after all, the host option is already there today. However, considering the user-friendliness/developer experience, aren't people more likely to understand the meaning of public/private IP vs. how configuring the host parameter will affect the end result?

But even though using host could be more confusing for some (that's what I would imagine, at least), it can be compensated for with @c-bandy 's suggestion of providing hints in the console output.

I'm fine with both versions. WDYT?

@liuweiGL
Copy link
Contributor

liuweiGL commented Apr 6, 2021

I recommend using the listen property:

server: {
  listen: ip, // 127.0.0.1 or 0.0.0.0 or 192.168.35.1/24
}

@patak-dev
Copy link
Member

Thanks for pushing for this change @eirslett. IMO, we shouldn't show the Network line at all. If we want to hint that there is a config option to enable this, maybe we can add a line about that Use --public-ip to enable public network access (at least for a while in case someone was using this feature, but maybe it is enough if this is properly documented)

packages/vite/src/node/cli.ts Outdated Show resolved Hide resolved
packages/vite/src/node/server/index.ts Outdated Show resolved Hide resolved
@Shinigami92
Copy link
Member

Some tests are failing on AppVeyor 🤔
We may to find out why and possibly fix them before I can set my approval

@eirslett
Copy link
Contributor Author

eirslett commented Apr 6, 2021

Some tests are failing on AppVeyor 🤔
We may to find out why and possibly fix them before I can set my approval

I suspect that the test is trying to connect to localhost, but to the public IP interface instead of the private one...?
If the difference between AppVeyor and CircleCI is Windows vs Unix, then somebody with a Windows machine should probably test the change manually?

@eirslett
Copy link
Contributor Author

ping is there anybody with a Windows setup who can test locally that this change does what it's supposed to? I think the AppVeyor build fails because of the OS, but I'm not sure.

@Shinigami92
Copy link
Member

We may rebase this PR when #2622 was merged into main
Then there is a os:windows runner

With that we can then see if it's a windows problem or not

@Shinigami92
Copy link
Member

@eirslett You can do that now! #2622 is merged 🙂

eirslett and others added 4 commits April 12, 2021 16:25
…default

See also vitejs#2820 which makes this problem critically worse.

Up until now, Vite has been listening on all public IP addresses
by default, which could be a potential security vulnerability.

This fixes the default behavior, so Vite only listens on 127.0.0.1.

You can get the old behavior back (listen to all IPs) by running
with the --listen-public CLI flag, or setting

```
export default defineConfig({
  server: {
    listenPublic: true
  }
  // ... more config here
})
```

in the Vite config file.
Co-authored-by: Shinigami <chrissi92@hotmail.de>
Co-authored-by: Shinigami <chrissi92@hotmail.de>
@eirslett eirslett force-pushed the listen-only-private-ip-by-default branch from 470f4f2 to 3fa2971 Compare April 12, 2021 14:25
@eirslett
Copy link
Contributor Author

Looks like it's failing all over the place... on my MacOS locally, the tests pass. 😩

@@ -555,7 +562,10 @@ async function startServer(

httpServer.on('error', onError)

httpServer.listen(port, options.host, () => {
const listenHostname = listenPublic
Copy link
Contributor

Choose a reason for hiding this comment

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

would this mean you'd have to specify listenPublic: true if you want to set a custom hostname?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Correct - you would have to explicitly set both.

Copy link
Contributor

@dominikg dominikg Apr 12, 2021

Choose a reason for hiding this comment

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

hmm, not sure i like that. If i'm actively setting host it should work without having to set another option too. Imho defaulting host to 127.0.0.1 should suffice. Users can still do --host 0.0.0.0 to get the old behavior back. (they shouldn't).

Copy link
Contributor

Choose a reason for hiding this comment

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

not to mention that listenPublic may be a misnomer. We don't know the network setup on the machine the devserver is running on. The only safe assumption is that 127.0.0.1 isn't "public".

Copy link
Member

@patak-dev patak-dev Apr 12, 2021

Choose a reason for hiding this comment

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

I also think that if a user specifies a --host, it is already opting in.

As @c-bandy was proposing, we should add a message in the console to let the user know this option

Use --host to expose the server to other devices on this network

I think we should implement the same scheme as sirv: https://github.com/lukeed/sirv/tree/master/packages/sirv-cli#network-access

For security reasons, sirv-cli does not expose your server to the network by default. This means that your machine, and only your machine, will be able to access the localhost server.
If, however, your coworker wants to access the server from their computer, or you want to preview your work on a mobile device, you must use the --host flag. Only then will your server be accessible to other devices on the same network.
Using --host without a value is equivalent to --host 0.0.0.0, which is makes it discoverable publicly. You may customize this by passing a different value – but you probably don't need to!

@antfu what do you think? I like the --host option without parameters scheme here for the old behavior. And we wouldn't need an extra option

@eirslett
Copy link
Contributor Author

I created a new PR that implements this, but uses only the --host parameter: #2977
Looks like most people wanted that solution, so I'll close this PR for now.

@eirslett eirslett closed this Apr 13, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
p4-important Violate documented behavior or significantly improves performance (priority) security
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants