{"record":{"id":"a89556bbf2ad9078","repo":"affaan-m/ECC","slug":"unsafe-nasiko-archive-nonzero-tar-padding","errorCode":null,"errorMessage":"Unsafe Nasiko archive: nonzero tar padding.","messagePattern":"Unsafe Nasiko archive: nonzero tar padding\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/nasiko-release.js","lineNumber":123,"sourceCode":"        || !tar.subarray(offset + 512, terminatorEnd).every(byte => byte === 0)\n        || !tar.subarray(terminatorEnd).every(byte => byte === 0)\n      ) {\n        throw new Error('Unsafe Nasiko archive: incomplete terminator or nonzero trailing data.');\n      }\n      terminated = true;\n      break;\n    }\n    const name = readTarString(header, 0, 100);\n    const prefix = readTarString(header, 345, 155);\n    const type = String.fromCharCode(header[156] || 48);\n    const size = readTarOctal(header, 124, 12);\n    const start = offset + 512;\n    const end = start + size;\n    const paddedEnd = start + Math.ceil(size / 512) * 512;\n    if (!Number.isSafeInteger(end) || paddedEnd > tar.length) throw new Error('Nasiko archive is truncated.');\n    const payload = tar.subarray(start, end);\n    if (!tar.subarray(end, paddedEnd).every(byte => byte === 0)) {\n      throw new Error('Unsafe Nasiko archive: nonzero tar padding.');\n    }\n    const isBinary = !prefix && name === expectedName && (type === '0' || type === '\\0');\n    const isAppleDouble = !prefix && name === `._${expectedName}` && type === '0' && size <= 1024 * 1024;\n    const isPaxMetadata = !prefix && name === `PaxHeader/${expectedName}` && type === 'x' && size <= 64 * 1024\n      && !/(?:^|\\n)(?:path|linkpath)=/i.test(payload.toString('utf8'));\n    if (isBinary && !binary && size > 0 && size <= MAX_BINARY_BYTES) binary = Buffer.from(payload);\n    else if (!isAppleDouble && !isPaxMetadata) throw new Error('Unsafe Nasiko archive: expected exactly one bounded regular binary file.');\n    offset = paddedEnd;\n  }\n  if (!terminated) throw new Error('Unsafe Nasiko archive: missing complete tar terminator.');\n  if (!binary) throw new Error('Unsafe Nasiko archive: expected exactly one bounded regular binary file.');\n  return binary;\n}\n\nfunction fetchBytes(url, options = {}) {\n  const parsed = new URL(url);\n  if (parsed.origin !== REGISTRY_ORIGIN || parsed.protocol !== 'https:') return Promise.reject(new Error('Nasiko download origin is not allowed.'));\n  const maxBytes = options.maxBytes || MAX_ARCHIVE_BYTES;","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/nasiko-release.js#L105-L141","documentation":"Tar pads every file entry to a 512-byte boundary. extractQualifiedTarGzip requires that all padding bytes between the end of an entry's payload and its padded boundary be zero. Nonzero padding indicates a malformed or tampered archive, so it throws this error instead of processing it.","triggerScenarios":"Calling extractQualifiedTarGzip with an archive where any byte in the padding region between payload end and the next 512-byte boundary is nonzero.","commonSituations":"Hand-crafted or maliciously modified tarballs; archives produced by nonconforming packers that put hidden data in padding; bit-rot or corruption in a cached download.","solutions":["Obtain the archive from the official registry again rather than a modified copy.","Verify the archive checksum against the published digest.","Repack the source file with standard tar so padding is zero-filled.","If this happens on every download, inspect any proxy/CDN that may be altering bytes."],"exampleFix":"// before\nconst tar = fs.readFileSync(untrustedPath);\nconst bin = extractQualifiedTarGzip(tar);\n// after\nconst tar = fs.readFileSync(untrustedPath);\nif (sha256(tar) !== PUBLISHED_DIGEST) throw new Error('Refusing unverified archive.');\nconst bin = extractQualifiedTarGzip(tar);","handlingStrategy":"validation","validationCode":"const digest = crypto.createHash('sha256').update(archiveBuffer).digest('hex'); if (digest !== publishedDigest) throw new Error('Archive digest mismatch.');","typeGuard":null,"tryCatchPattern":"try { return extractQualifiedTarGzip(tar); } catch (err) { if (err.message.includes('nonzero tar padding')) throw new Error('Archive failed integrity validation; refusing to install.'); throw err; }","preventionTips":["Only install artifacts whose sha256 matches the registry manifest","Obtain tarballs only from the official registry origin","Reject archives produced or modified by nonstandard packers","Treat any padding modification as a potential supply-chain tampering signal"],"tags":["archive","tar","validation","security"],"backgroundTag":"checksum-mismatch","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}