Ignore unrecognized pax headers
diff --git a/lib/src/common.dart b/lib/src/common.dart
index a94de21..5acafed 100644
--- a/lib/src/common.dart
+++ b/lib/src/common.dart
@@ -25,6 +25,22 @@
const paxHeaderGname = 'gname';
const paxHeaderSize = 'size';
+/// These are the pax headers considered when reading tar files.
+///
+/// Other pax headers are dropped in the reader to avoid memory-based DOS
+/// attacks. We already limit the size of a headers file by default, but an
+/// attacker could provide many small global header files with bogus keys, which
+/// we'd all have to store.
+/// With this approach, we can ensure that the reader's buffer will have an
+/// upper bound of `(supportedPaxHeaders.length + 1) * maxHeaderSize`.
+const supportedPaxHeaders = {
+ paxHeaderLinkName,
+ paxHeaderPath,
+ paxHeaderUname,
+ paxHeaderGname,
+ paxHeaderSize,
+};
+
const defaultSpecialLength = blockSize * 2;
extension ToTyped on List<int> {
diff --git a/lib/src/reader.dart b/lib/src/reader.dart
index 12c4ccd..09ae3ca 100644
--- a/lib/src/reader.dart
+++ b/lib/src/reader.dart
@@ -350,6 +350,7 @@
keyBuffer.writeCharCode(currentChar);
currentChar = _buffer[++offset];
}
+ final key = keyBuffer.toString();
// Skip over the equals sign
offset++;
@@ -358,7 +359,11 @@
final lengthOfValue = length - 3 - keyBuffer.length - charsInLength;
final value =
utf8.decode(_buffer.sublist(offset, offset + lengthOfValue));
- map[keyBuffer.toString()] = value;
+ // Ignore unrecognized headers to avoid unbounded growth of the global
+ // header map.
+ if (supportedPaxHeaders.contains(key)) {
+ map[key] = value;
+ }
// Skip over value and trailing newline
offset += lengthOfValue + 1;