compressing 2.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -169,7 +169,7 @@ const urllib = require('urllib');
169
169
  const targetDir = require('os').tmpdir();
170
170
  const compressing = require('compressing');
171
171
 
172
- urllib.request('http://registry.npmjs.org/pedding/-/pedding-1.1.0.tgz', {
172
+ urllib.request('http://registry.npmjs.org/compressing/-/compressing-2.0.0.tgz', {
173
173
  streaming: true,
174
174
  followRedirect: true,
175
175
  })
package/lib/utils.js CHANGED
@@ -4,6 +4,22 @@ const fs = require('fs');
4
4
  const path = require('path');
5
5
  const { pipeline: pump } = require('stream');
6
6
 
7
+ /**
8
+ * Check if childPath is within parentPath (prevents path traversal attacks)
9
+ * @param {string} childPath - The path to check
10
+ * @param {string} parentPath - The parent directory path
11
+ * @returns {boolean} - True if childPath is within parentPath
12
+ */
13
+ function isPathWithinParent(childPath, parentPath) {
14
+ const normalizedChild = path.resolve(childPath);
15
+ const normalizedParent = path.resolve(parentPath);
16
+ const parentWithSep = normalizedParent.endsWith(path.sep)
17
+ ? normalizedParent
18
+ : normalizedParent + path.sep;
19
+ return normalizedChild === normalizedParent ||
20
+ normalizedChild.startsWith(parentWithSep);
21
+ }
22
+
7
23
  // file/fileBuffer/stream
8
24
  exports.sourceType = source => {
9
25
  if (!source) return undefined;
@@ -92,6 +108,9 @@ exports.makeUncompressFn = StreamClass => {
92
108
  fs.mkdir(destDir, { recursive: true }, err => {
93
109
  if (err) return reject(err);
94
110
 
111
+ // Resolve destDir to absolute path for security validation
112
+ const resolvedDestDir = path.resolve(destDir);
113
+
95
114
  let entryCount = 0;
96
115
  let successCount = 0;
97
116
  let isFinish = false;
@@ -108,7 +127,15 @@ exports.makeUncompressFn = StreamClass => {
108
127
  .on('error', reject)
109
128
  .on('entry', (header, stream, next) => {
110
129
  stream.on('end', next);
111
- const destFilePath = path.join(destDir, header.name);
130
+ const destFilePath = path.join(resolvedDestDir, header.name);
131
+ const resolvedDestPath = path.resolve(destFilePath);
132
+
133
+ // Security: Validate that the entry path doesn't escape the destination directory
134
+ if (!isPathWithinParent(resolvedDestPath, resolvedDestDir)) {
135
+ console.warn(`[compressing] Skipping entry with path traversal: "${header.name}" -> "${resolvedDestPath}"`);
136
+ stream.resume();
137
+ return;
138
+ }
112
139
 
113
140
  if (header.type === 'file') {
114
141
  const dir = path.dirname(destFilePath);
@@ -125,6 +152,14 @@ exports.makeUncompressFn = StreamClass => {
125
152
  } else if (header.type === 'symlink') {
126
153
  const dir = path.dirname(destFilePath);
127
154
  const target = path.resolve(dir, header.linkname);
155
+
156
+ // Security: Validate that the symlink target doesn't escape the destination directory
157
+ if (!isPathWithinParent(target, resolvedDestDir)) {
158
+ console.warn(`[compressing] Skipping symlink "${header.name}": target "${target}" escapes extraction directory`);
159
+ stream.resume();
160
+ return;
161
+ }
162
+
128
163
  entryCount++;
129
164
 
130
165
  fs.mkdir(dir, { recursive: true }, err => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "compressing",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Everything you need for compressing and uncompressing",
5
5
  "main": "index.js",
6
6
  "scripts": {