-
-
Notifications
You must be signed in to change notification settings - Fork 291
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
[dev-server] CVE-2024-29415: "ip SSRF improper categorization in isPublic" #2747
Comments
I see from this comment that people seem to be switching to using the ip-address package instead. |
It looks like the feature used - guessing the current public ipv4 address of the server - is not available in ip-address. Some options I see:
Source code of ip.address: https://github.com/indutny/node-ip/blob/main/lib/ip.js#L383 I propose exporting a new function in core lib, which loops through addresses by nic, picking the first non loopack ipv4 address found. An enhancement would be allowing this value to be passed in to more places as a configuration object, to better handle cases where there are mutliple addresses that meet this criteria (if that is desired). |
Great points @dmihalcik! Another possibility could be the public-ip package. It seems to be very straightforward and accomplish the small need of this package. |
In our codebase we use only one method from given it's always a call to I think the defaults will be // currently used functon
// node_modules/ip/lib/ip.js
//
// ### function address (name, family)
// #### @name {string|'public'|'private'} **Optional** Name or security
// of the network interface.
// #### @family {ipv4|ipv6} **Optional** IP family of the address (defaults
// to ipv4).
//
// Returns the address for the network interface on the current system with
// the specified `name`:
// * String: First `family` address of the interface.
// If not found see `undefined`.
// * 'public': the first public ip address of family.
// * 'private': the first private ip address of family.
// * undefined: First address with `ipv4` or loopback address `127.0.0.1`.
//
ip.address = function (name, family) {
var interfaces = os.networkInterfaces();
//
// Default to `ipv4`
//
family = _normalizeFamily(family);
//
// If a specific network interface has been named,
// return the address.
//
if (name && name !== 'private' && name !== 'public') {
var res = interfaces[name].filter((details) => {
var itemFamily = _normalizeFamily(details.family);
return itemFamily === family;
});
if (res.length === 0) {
return undefined;
}
return res[0].address;
}
var all = Object.keys(interfaces).map((nic) => {
//
// Note: name will only be `public` or `private`
// when this is called.
//
var addresses = interfaces[nic].filter((details) => {
details.family = _normalizeFamily(details.family);
if (details.family !== family || ip.isLoopback(details.address)) {
return false;
} if (!name) {
return true;
}
return name === 'public' ? ip.isPrivate(details.address)
: ip.isPublic(details.address);
});
return addresses.length ? addresses[0].address : undefined;
}).filter(Boolean);
return !all.length ? ip.loopback(family) : all[0];
}; |
so looks like we need internal-ip from the same author as public-ip specifically import {internalIpV4} from 'internal-ip';
console.log(await internalIpV4());
//=> '10.0.0.79' but it's just my guess based on quick analyses of the libraries UPDATE this is confusing though return name === 'public' ? ip.isPrivate(details.address)
: ip.isPublic(details.address); |
did a test locally // index.mjs
import ip from "ip";
import { internalIpV4 } from "internal-ip";
import { publicIpv4 } from "public-ip";
console.log("ip.address()", ip.address());
console.log("await internalIpV4()", await internalIpV4());
console.log("await publicIpv4()", await publicIpv4());
|
Wait maybe I am missing something but |
no, it's not, updated the comment |
given the difference, I think we actually need this https://github.com/silverwind/default-gateway gonna test now UPDATE also not // index.mjs
import ip from "ip";
import { gateway4sync } from "default-gateway";
import { internalIpV4 } from "internal-ip";
import { publicIpv4 } from "public-ip";
console.log("ip.address()", ip.address());
console.log("gateway4sync().gateway", gateway4sync().gateway);
console.log("await internalIpV4()", await internalIpV4());
console.log("await publicIpv4()", await publicIpv4());
|
did a bit research on what's going on internally I can't find any working alternaitve though, feel free to suggest one otherwise I can look into making our own utility for that, which is basically a simplified version of the old PS: e.g. storybook just implemented a custom utility in their codebase https://github.com/storybookjs/storybook/pull/27529/files |
Any ETA on the fix? |
Found a working one, looks good https://www.npmjs.com/package/local-ip-url // index.mjs
import ip from "ip";
import localIpUrl from "local-ip-url";
import { gateway4sync } from "default-gateway";
import { internalIpV4 } from "internal-ip";
console.log("ip.address()", ip.address());
console.log("localIpUrl()", localIpUrl());
console.log("gateway4sync().gateway", gateway4sync().gateway);
console.log("await internalIpV4()", await internalIpV4());
|
Unfortunately I figured |
I'd like to thank you for the effort you've put in on this - I know you hit a bit of a pivot point but is there any ETA on the |
It's released. For exact versions of new packages you can check #2744 |
Thank you very much @bashmish for your efforts on this! |
This issue is just meant to raise the flag about the current vulnerability with the
ip
package that@web/dev-server
depends on. It seems that there currently is no fix for this fromip
.GHSA-2p57-rm9w-gvfp
The text was updated successfully, but these errors were encountered: