Critical severityNVD Advisory· Published Dec 5, 2022· Updated Apr 24, 2025
CVE-2022-41642
CVE-2022-41642
Description
OS command injection vulnerability in Nadesiko3 (PC Version) v3.3.61 and earlier allows a remote attacker to execute an arbitrary OS command when processing compression and decompression on the product.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
nadesiko3npm | < 3.3.69 | 3.3.69 |
Affected products
1- Range: v3.3.61 and earlier
Patches
3124871c064cfnode v12 でcnako3の圧縮解凍が実行できない問題を修正 #1325
2 files changed · +4 −5
src/plugin_node.mts+3 −3 modified@@ -27,11 +27,11 @@ export default { fn: function (sys: any) { sys.__quotePath = (fpath: string) => { if (process.platform === 'win32') { - fpath = fpath.replaceAll('"', '') - fpath = fpath.replaceAll('%', '"^%"') + fpath = fpath.replace(/\"/g, '') + fpath = fpath.replace(/\%/g, '"^%"') fpath = '"' + fpath + '"' } else { - fpath = fpath.replaceAll('\'', '\'\\\'\'') // '\'' + fpath = fpath.replace(/\'/, '\'\\\'\'') // '\'' fpath = '\'' + fpath + '\'' } return fpath
test/node/plugin_node_test.mjs+1 −2 modified@@ -80,7 +80,7 @@ describe('plugin_node_test', () => { cmp('「some data to hash」を「sha256」の「hex」でハッシュ値計算して表示。', '6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50') }) it('テンポラリフォルダ', () => { - cmd('F=「{テンポラリフォルダ}/test.txt」;「abc」をFに保存。Fを読んでトリムして表示。', 'abc') + cmp('F=「{テンポラリフォルダ}/test.txt」;「abc」をFに保存。Fを読んでトリムして表示。', 'abc') }) it('圧縮解凍', () => { let path7z = '7z' @@ -125,4 +125,3 @@ describe('plugin_node_test', () => { cmp(`${pathSrc2}FILEをファイル削除。ZIPをテンポラリフォルダに解凍。FILEを読む。トリム。それを表示。`, 'abc') }) }) -
56ccfb2f9ccefixed win32で圧縮解凍
2 files changed · +12 −8
src/plugin_node.mjs+6 −4 modified@@ -15,6 +15,9 @@ import readline from 'readline'; // ハッシュ関数で利用 import crypto from 'crypto'; import os from 'os'; +import url from 'url'; +const __filename = url.fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); export default { '初期化': { type: 'func', @@ -24,7 +27,7 @@ export default { sys.__quotePath = (fpath) => { if (process.platform === 'win32') { fpath = fpath.replaceAll('"', ''); - fpath = fpath.replaceAll('%', '%%'); + fpath = fpath.replaceAll('%', '"^%"'); fpath = '"' + fpath + '"'; } else { @@ -37,11 +40,10 @@ export default { let fpath = tool; if (process.platform === 'win32') { if (!fileExists(tool)) { - const nodeDir = path.dirname(process.argv[0]); - const root = path.resolve(path.join(nodeDir, '..')); + const root = path.resolve(path.join(__dirname, '..')); fpath = path.join(root, 'bin', tool + '.exe'); if (fileExists(fpath)) { - return sys.__quotePath(`${fpath}`); + return `${fpath}`; } return tool; }
src/plugin_node.mts+6 −4 modified@@ -15,6 +15,9 @@ import readline from 'readline' // ハッシュ関数で利用 import crypto from 'crypto' import os from 'os' +import url from 'url'; +const __filename = url.fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); export default { '初期化': { @@ -25,7 +28,7 @@ export default { sys.__quotePath = (fpath: string) => { if (process.platform === 'win32') { fpath = fpath.replaceAll('"', '') - fpath = fpath.replaceAll('%', '%%') + fpath = fpath.replaceAll('%', '"^%"') fpath = '"' + fpath + '"' } else { fpath = fpath.replaceAll('\'', '\'\\\'\'') // '\'' @@ -37,10 +40,9 @@ export default { let fpath = tool if (process.platform === 'win32') { if (!fileExists(tool)) { - const nodeDir = path.dirname(process.argv[0]) - const root = path.resolve(path.join(nodeDir, '..')) + const root = path.resolve(path.join(__dirname, '..')) fpath = path.join(root, 'bin', tool + '.exe') - if (fileExists(fpath)) { return sys.__quotePath(`${fpath}`) } + if (fileExists(fpath)) { return `${fpath}` } return tool } }
61a70792752a圧縮解凍時のOSインジェクションを修正
2 files changed · +58 −20
src/plugin_node.mjs+29 −9 modified@@ -21,6 +21,18 @@ export default { josi: [], pure: true, fn: function (sys) { + sys.__quotePath = (fpath) => { + if (process.platform === 'win32') { + fpath = fpath.replaceAll('"', ''); + fpath = fpath.replaceAll('%', '%%'); + fpath = '"' + fpath + '"'; + } + else { + fpath = fpath.replaceAll('\'', '\'\\\'\''); // '\'' + fpath = '\'' + fpath + '\''; + } + return fpath; + }; sys.__getBinPath = (tool) => { let fpath = tool; if (process.platform === 'win32') { @@ -29,7 +41,7 @@ export default { const root = path.resolve(path.join(nodeDir, '..')); fpath = path.join(root, 'bin', tool + '.exe'); if (fileExists(fpath)) { - return `"${fpath}"`; + return sys.__quotePath(`${fpath}`); } return tool; } @@ -517,8 +529,10 @@ export default { josi: [['を', 'から'], ['に', 'へ']], pure: true, fn: function (a, b, sys) { - const tpath = sys.__getBinPath(sys.__v0['圧縮解凍ツールパス']); - const cmd = `${tpath} x "${a}" -o"${b}" -y`; + const tpath = sys.__quotePath(sys.__getBinPath(sys.__v0['圧縮解凍ツールパス'])); + a = sys.__quotePath(a); + b = sys.__quotePath(b); + const cmd = `${tpath} x ${a} -o${b} -y`; execSync(cmd); return true; } @@ -528,8 +542,10 @@ export default { josi: [['で'], ['を', 'から'], ['に', 'へ']], pure: true, fn: function (callback, a, b, sys) { - const tpath = sys.__getBinPath(sys.__v0['圧縮解凍ツールパス']); - const cmd = `${tpath} x "${a}" -o"${b}" -y`; + const tpath = sys.__quotePath(sys.__getBinPath(sys.__v0['圧縮解凍ツールパス'])); + a = sys.__quotePath(a); + b = sys.__quotePath(b); + const cmd = `${tpath} x ${a} -o${b} -y`; exec(cmd, (err, stdout, stderr) => { if (err) { throw new Error('[エラー]『解凍時』' + err); @@ -544,8 +560,10 @@ export default { josi: [['を', 'から'], ['に', 'へ']], pure: true, fn: function (a, b, sys) { - const tpath = sys.__getBinPath(sys.__v0['圧縮解凍ツールパス']); - const cmd = `${tpath} a -r "${b}" "${a}" -y`; + const tpath = sys.__quotePath(sys.__getBinPath(sys.__v0['圧縮解凍ツールパス'])); + a = sys.__quotePath(a); + b = sys.__quotePath(b); + const cmd = `${tpath} a -r ${b} ${a} -y`; execSync(cmd); return true; } @@ -555,8 +573,10 @@ export default { josi: [['で'], ['を', 'から'], ['に', 'へ']], pure: true, fn: function (callback, a, b, sys) { - const tpath = sys.__getBinPath(sys.__v0['圧縮解凍ツールパス']); - const cmd = `${tpath} a -r "${b}" "${a}" -y`; + const tpath = sys.__quotePath(sys.__getBinPath(sys.__v0['圧縮解凍ツールパス'])); + a = sys.__quotePath(a); + b = sys.__quotePath(b); + const cmd = `${tpath} a -r ${b} ${a} -y`; exec(cmd, (err, stdout, stderr) => { if (err) { throw new Error('[エラー]『圧縮時』' + err);
src/plugin_node.mts+29 −11 modified@@ -22,18 +22,28 @@ export default { josi: [], pure: true, fn: function (sys: any) { - sys.__getBinPath = (tool: any) => { + sys.__quotePath = (fpath: string) => { + if (process.platform === 'win32') { + fpath = fpath.replaceAll('"', '') + fpath = fpath.replaceAll('%', '%%') + fpath = '"' + fpath + '"' + } else { + fpath = fpath.replaceAll('\'', '\'\\\'\'') // '\'' + fpath = '\'' + fpath + '\'' + } + return fpath + } + sys.__getBinPath = (tool: any) => { let fpath = tool if (process.platform === 'win32') { if (!fileExists(tool)) { const nodeDir = path.dirname(process.argv[0]) const root = path.resolve(path.join(nodeDir, '..')) fpath = path.join(root, 'bin', tool + '.exe') - if (fileExists(fpath)) { return `"${fpath}"` } + if (fileExists(fpath)) { return sys.__quotePath(`${fpath}`) } return tool } } - return fpath } sys.__getBokanPath = () => { @@ -470,8 +480,10 @@ export default { josi: [['を', 'から'], ['に', 'へ']], pure: true, fn: function (a: string, b: string, sys: any) { - const tpath = sys.__getBinPath(sys.__v0['圧縮解凍ツールパス']) - const cmd = `${tpath} x "${a}" -o"${b}" -y` + const tpath = sys.__quotePath(sys.__getBinPath(sys.__v0['圧縮解凍ツールパス'])) + a = sys.__quotePath(a) + b = sys.__quotePath(b) + const cmd = `${tpath} x ${a} -o${b} -y` execSync(cmd) return true } @@ -481,8 +493,10 @@ export default { josi: [['で'], ['を', 'から'], ['に', 'へ']], pure: true, fn: function (callback: any, a: string, b: string, sys: any) { - const tpath = sys.__getBinPath(sys.__v0['圧縮解凍ツールパス']) - const cmd = `${tpath} x "${a}" -o"${b}" -y` + const tpath = sys.__quotePath(sys.__getBinPath(sys.__v0['圧縮解凍ツールパス'])) + a = sys.__quotePath(a) + b = sys.__quotePath(b) + const cmd = `${tpath} x ${a} -o${b} -y` exec(cmd, (err, stdout, stderr) => { if (err) { throw new Error('[エラー]『解凍時』' + err) } callback(stdout) @@ -495,8 +509,10 @@ export default { josi: [['を', 'から'], ['に', 'へ']], pure: true, fn: function (a: string, b: string, sys: any) { - const tpath = sys.__getBinPath(sys.__v0['圧縮解凍ツールパス']) - const cmd = `${tpath} a -r "${b}" "${a}" -y` + const tpath = sys.__quotePath(sys.__getBinPath(sys.__v0['圧縮解凍ツールパス'])) + a = sys.__quotePath(a) + b = sys.__quotePath(b) + const cmd = `${tpath} a -r ${b} ${a} -y` execSync(cmd) return true } @@ -506,8 +522,10 @@ export default { josi: [['で'], ['を', 'から'], ['に', 'へ']], pure: true, fn: function (callback: any, a: string, b: string, sys: any) { - const tpath = sys.__getBinPath(sys.__v0['圧縮解凍ツールパス']) - const cmd = `${tpath} a -r "${b}" "${a}" -y` + const tpath = sys.__quotePath(sys.__getBinPath(sys.__v0['圧縮解凍ツールパス'])) + a = sys.__quotePath(a) + b = sys.__quotePath(b) + const cmd = `${tpath} a -r ${b} ${a} -y` exec(cmd, (err, stdout, stderr) => { if (err) { throw new Error('[エラー]『圧縮時』' + err) } callback(stdout)
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
10- github.com/advisories/GHSA-m8r5-7wf4-63mwghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2022-41642ghsaADVISORY
- github.com/kujirahand/nadesiko3/commit/124871c064cfc65cdcd83205637e84fc246c76dfghsaWEB
- github.com/kujirahand/nadesiko3/commit/56ccfb2f9cceaec83e6a9d3024c3ba8c54ebe1a4ghsaWEB
- github.com/kujirahand/nadesiko3/commit/61a70792752a75b7f71df214e98a236721ea3fa6ghsaWEB
- github.com/kujirahand/nadesiko3/issues/1325ghsaWEB
- github.com/kujirahand/nadesiko3/issues/1347ghsaWEB
- github.com/kujirahand/nadesiko3/releases/tag/3.3.62ghsaWEB
- github.com/kujirahand/nadesiko3/releases/tag/3.3.69ghsaWEB
- jvn.jp/en/jp/JVN56968681/index.htmlghsaWEB
News mentions
0No linked articles in our index yet.