-
-
Notifications
You must be signed in to change notification settings - Fork 6.3k
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): Listen only to 127.0.0.1 by default #2977
fix(server): Listen only to 127.0.0.1 by default #2977
Conversation
Copying my comment from the prev PR for reference:
@eirslett We should add an equivalent paragraph to the docs. And this PR doesn't implement support for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (non-blocking): The only thing I see here is why do we have so huge duplicate code between server and preview? Can this be shared or e.g. re-called from the server impl?
Also it seems there are some failing tests 🤔 At least on windows 🤔 @patak-js Do you have windows? Can you reproduce this on your machine? |
@Shinigami92 I can reproduce this on my machine, but I don't understand how this is related to this PR. Head is green. |
Yes, we should refactor it, my suggestion is that since this is a security fix, we could merge it (after code review) and do the other improvements in a separate PR. The code duplication should definitely be refactored, and supporting My suspicion is that Windows tries to use the public IP in the tests, but by default the server now only listens to 127.0.0.1, which might be the reason why the tests fail? |
@eirslett you should consider to create a PR/branch on top of |
FWIW, Luke mentioned he only made that the default due to a few complaints about having to type more to expose. You certainly could make the argument that forcing users to be more explicit when exposing could be of benefit. Just something to consider. |
Ok, I agree with @rschristian. We can have |
The failing example in windows is working well when launching the dev server, but not in the jest tests. This may be an issue with |
Agree to keep the
Where the |
There we go:
🤞 Let's hope that the tests pass... |
It is still failing in Windows, but it should be because of our tests and not because of the feature itself. @eirslett maybe we can force to use the |
Some findings about the failing tests:
I don't understand why using Other details:
|
I think the host will then be
I don't think it matters - the most valuable piece of information is the public IP address, which you can then pass on to coworkers, or your mobile phone, or whatever should access your dev server remotely. |
If const hostname = options.host || '127.0.0.1' Note: Looks like if the system supports IPv6, passing undefined defaults to
Users may still want to use localhost and give the public IP to others at the same time, and this is how Vite works until this moment. Using |
I pushed a new change now, which makes the logic even more explicit. |
Hey @eirslett, I just had a quick look over your PR Some thoughts I had are:
IPv6 support (if wanted) could be outsourced to another PR 🤔 |
It's not really checking that, it's just setting the default value to 127.0.0.1.
I'm sure it possible, but maybe that's a separate feature?
Absolutely, there's not really anything in the way now for passing an IPv6 address as the |
75f68bb
to
33a4792
Compare
The security fix for listening only on 127.0.0.1 by default seems like it broke tests on Windows. Try using 0.0.0.0 for tests, and see if that fixes the tests.
packages/vite/src/node/preview.ts
Outdated
let hostname: string | ||
if (options.host === undefined) { | ||
// Use a secure default | ||
hostname = '127.0.0.1' | ||
} else if (options.host === true) { | ||
// The user probably passed --host in the CLI, without arguments | ||
hostname = '0.0.0.0' | ||
} else { | ||
hostname = options.host as string | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is reused in both files, let's extract it to a function:
const getHostname(hostnameOption: string | boolean | undefined): string {
if (typeof hostnameOption === 'string') {
return hostnameOption
}
// `--host` without parameters
if (hostnameOption === true) {
return '0.0.0.0'
}
// secure loopback-only default
return '127.0.0.1'
}
if (hostname === '127.0.0.1') { | ||
const url = `${protocol}://localhost:${chalk.bold(port)}${base}` | ||
logger.info(` > Local: ${chalk.cyan(url)}`) | ||
logger.info(` > Network: ${chalk.dim('use `--host` to expose')}`) | ||
} else { | ||
const interfaces = os.networkInterfaces() | ||
Object.keys(interfaces).forEach((key) => | ||
(interfaces[key] || []) | ||
.filter((details) => details.family === 'IPv4') | ||
.map((detail) => { | ||
return { | ||
type: detail.address.includes('127.0.0.1') | ||
? 'Local: ' | ||
: 'Network: ', | ||
host: detail.address | ||
} | ||
}) | ||
.forEach(({ type, host }) => { | ||
const url = `${protocol}://${host}:${chalk.bold(port)}${base}` | ||
logger.info(` > ${type} ${chalk.cyan(url)}`) | ||
}) | ||
) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be extracted too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, but I think it is better if we do these refactorings in a future PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍🏼 Okay to leave this one out, but it would be good to extract the added code (previous comment)
Looks like all the tests pass now! I'm not 100 % sure about making |
@eirslett let's do this change, and we can then use |
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
} else { | ||
hostname = options.host as string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: Is this also the case if options.host
is set to false
?
Cause I see that host
is of type string | boolean | undefined
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean, yes, the code in there should probably be refactored, prettified, extracted, nitpicked and all, but this is first and foremost a security patch, and it's already been 29 days since I opened the first PR. I'm getting a little bit tired of all the bike shedding, sorry. All I wanted to do was to make Vite more secure. |
Thanks for the PR @eirslett. For later reference, this was not merged before because tests were not passing til yesterday. |
If you use |
@evromalarkey Could you open an issue or maybe directly a PR for that? |
Issue here #3355 |
Co-authored-by: Nihal Gonsalves <nihal@nihalgonsalves.com> Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
Co-authored-by: antfu <hi@antfu.me>
This pull request supersedes #2865, after discussion that one should rely on the
--host
parameter to determine public/private network interface setup.