Skip to content

Commit 35a1ffe

Browse files
committed
doc: more clarity in security warning
1 parent bf776f6 commit 35a1ffe

3 files changed

Lines changed: 31 additions & 9 deletions

File tree

README.md

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,38 @@ implementation. (Note that most of these are disabled if
3232
is set, or the extraction is run as root.
3333
- File and directory modes in the archive are ignored, unless
3434
the `chmod: true` option is set.
35-
36-
**However**, care must still be taken when dealing with data from
37-
unknown sources, especially when extracting files, with this or
38-
any library, no matter how hardened it may be.
35+
- A path-reservation system is used to ensure that even when
36+
multiple entries are being extracted in parallel, subsequent
37+
entries with the same filename will not interfere with one
38+
another (for example, exchanging a file with a symbolic link
39+
while it is being written to).
40+
- Unicode characters in path names are fully normalized, to
41+
prevent evading these protections with unicode equivalences.
42+
43+
It is frankly unlikely that any tar implementation in JavaScript
44+
is going to be as secure as this one, unless a similar amount of
45+
work is put into it, putting it to the test over many years of
46+
intensive use and scrutiny. You can vibe-code a tar extractor in
47+
an afternoon, but you'll regret it.
48+
49+
> [!WARNING]
50+
>
51+
> **However**, all that being said, _care must still be taken_
52+
> when dealing with data from unknown sources, especially when
53+
> extracting files, with this or any library, no matter how
54+
> hardened it may be. It is _your_ responsibility to use this
55+
> library safely.
3956
4057
1. **NEVER** extract tarball data into a folder that could be
4158
potentially controlled by an unknown actor. A clever attacker
4259
can swap out the target of an extracted file with a symbolic
4360
link to some location of their choosing, resulting in writing
4461
files outside the target folder. There is no reasonable way to
4562
harden against this category of attack, and security reports
46-
about it will be closed. TOCTOU exposure is unavoidable when
47-
creating files based on entries in an archive file.
63+
about it will be closed.
64+
[TOCTOU](https://cwe.mitre.org/data/definitions/367.html)
65+
exposure is unavoidable when creating files based on entries
66+
in an archive file.
4867
2. If you are unpacking tarballs that may come from an unknown
4968
source, it is **highly recommended** that you use a filter
5069
function that rejects all hardlinks and symbolic links. Link

src/unpack.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ export class Unpack extends Parser {
303303
// tar paths, not a filesystem.
304304
const entryDir = path.posix.dirname(entry.path)
305305
const resolved = path.posix.normalize(
306-
path.posix.join(entryDir, parts.join('/'))
306+
path.posix.join(entryDir, parts.join('/')),
307307
)
308308
// If the resolved path escapes (starts with ..), reject it
309309
if (resolved.startsWith('../') || resolved === '..') {

test/ghsa-8qq5-rm4j-mr97.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@ const absoluteWithDotDot = '/../a/target'
1414
const secretLinkpath = resolve(t.testdirName, 'secret.txt')
1515

1616
t.formatSnapshot = (o: unknown): unknown =>
17-
typeof o === 'string' ? o.replace(
18-
/^ENOENT: no such file or directory, link .*? -> .*?$/, 'ENOENT: no such file or directory, link')
17+
typeof o === 'string' ?
18+
o.replace(
19+
/^ENOENT: no such file or directory, link .*? -> .*?$/,
20+
'ENOENT: no such file or directory, link',
21+
)
1922
: Array.isArray(o) ? o.map(o => t.formatSnapshot?.(o))
2023
: o
2124

0 commit comments

Comments
 (0)