Nextcloud - [CVE-2025-58751] Low — HTTP directory-traversal disclosure of package.json

Just FYI,

this affects the latest nextcloud:

GET /../package.json

2 Likes

Are you sure that Nextcloud is affected, I couldn’t find it. I checked this page and also this one

1 Like

Dear @mrmarkuz

I’m pretty sure it’s affected, you can access it by entering the address of your server:

https://host/../package.json

Thanks,

1 Like

Ah ok, this way someone can check which packages, dependencies etc. are installed.

But I can’t find a relation between package.json and the CVE, do you have a link to get some information?

Content of https://host/../package.json
name	"nextcloud"
version	"1.0.0"
description	"Nextcloud Server"
author	"Nextcloud GmbH and Nextcloud contributors"
private	true
directories	
lib	"lib"
test	"tests"
scripts	
build	"webpack --node-env production --progress"
postbuild	"build/npm-post-build.sh"
dev	"webpack --node-env development --progress"
watch	"webpack --node-env development --progress --watch"
lint	'eslint $(for appdir in $(ls apps); do if ! $(git check-ignore -q $appdir); then printf "apps/$appdir "; fi; done) core --no-error-on-unmatched-pattern'
lint:fix	'eslint $(for appdir in $(ls apps); do if ! $(git check-ignore -q $appdir); then printf "apps/$appdir "; fi; done) core --no-error-on-unmatched-pattern --fix'
stylelint	"stylelint '{apps,core}/**/*.{scss,vue}'"
stylelint:fix	"stylelint --fix '{apps,core}/**/*.{scss,vue}'"
test	"vitest run"
test:watch	"vitest watch"
test:coverage	"vitest run --coverage"
test:update-snapshots	"vitest run --update"
test:jsunit	"karma start tests/karma.config.js --single-run"
sass	'sass --style compressed --load-path core/css core/css/ $(for cssdir in $(find apps -mindepth 2 -maxdepth 2 -name "css"); do if ! $(git check-ignore -q $cssdir); then printf "$cssdir "; fi; done)'
sass:watch	'sass --watch --load-path core/css core/css/ $(for cssdir in $(find apps -mindepth 2 -maxdepth 2 -name "css"); do if ! $(git check-ignore -q $cssdir); then printf "$cssdir "; fi; done)'
sass:icons	"babel-node core/src/icons.js"
cypress	"npm run cypress:component && npm run cypress:e2e"
cypress:component	"cypress run --component"
cypress:e2e	"cypress run --e2e"
cypress:gui	"cypress open"
cypress:version	"cypress version"
repository	
type	"git"
url	"https://github.com/nextcloud/server.git"
keywords	
0	"nextcloud"
license	"AGPL-3.0-or-later"
dependencies	
@chenfengyuan/vue-qrcode	"^1.0.2"
@mdi/js	"^7.4.47"
@mdi/svg	"^7.4.47"
@nextcloud/auth	"^2.5.1"
@nextcloud/axios	"^2.5.1"
@nextcloud/browser-storage	"^0.4.0"
@nextcloud/browserslist-config	"^3.0.1"
@nextcloud/calendar-availability-vue	"^2.2.6"
@nextcloud/capabilities	"^1.2.0"
@nextcloud/dialogs	"^6.3.1"
@nextcloud/event-bus	"^3.3.2"
@nextcloud/files	"^3.10.2"
@nextcloud/initial-state	"^2.2.0"
@nextcloud/l10n	"^3.3.0"
@nextcloud/logger	"^3.0.2"
@nextcloud/moment	"^1.3.4"
@nextcloud/password-confirmation	"^5.3.1"
@nextcloud/paths	"^2.2.1"
@nextcloud/router	"^3.0.1"
@nextcloud/sharing	"^0.2.4"
@nextcloud/upload	"^1.10.0"
@nextcloud/vue	"^8.27.0"
@simplewebauthn/browser	"^12.0.0"
@vue/web-component-wrapper	"^1.3.0"
@vueuse/components	"^11.3.0"
@vueuse/core	"^11.0.1"
@vueuse/integrations	"^11.3.0"
backbone	"^1.6.1"
blueimp-md5	"^2.19.0"
blurhash	"^2.0.5"
browserslist-useragent-regexp	"^4.1.1"
camelcase	"^8.0.0"
cancelable-promise	"^4.3.1"
clipboard	"^2.0.11"
color	"^4.2.3"
core-js	"^3.43.0"
davclient.js	"github:owncloud/davclient.js.git#0.2.2"
debounce	"^2.1.0"
dompurify	"^3.2.6"
escape-html	"^1.0.3"
focus-trap	"^7.6.5"
handlebars	"^4.7.7"
is-svg	"^5.1.0"
jquery	"~3.7"
jquery-ui	"1.13.3"
jquery-ui-dist	"^1.13.3"
libphonenumber-js	"^1.12.9"
lodash	"^4.17.21"
marked	"^15.0.12"
moment	"^2.30.1"
moment-timezone	"^0.6.0"
nextcloud-vue-collections	"^0.13.0"
p-limit	"^6.2.0"
p-queue	"^7.4.1"
path	"^0.12.7"
pinia	"^2.3.1"
query-string	"^9.2.1"
regenerator-runtime	"^0.14.1"
select2	"3.5.1"
snap.js	"^2.0.9"
strengthify	"github:nextcloud/strengthify#0.5.9"
throttle-debounce	"^5.0.2"
underscore	"1.13.7"
url-search-params-polyfill	"^8.1.1"
v-click-outside	"^3.2.0"
v-tooltip	"^2.1.3"
vue	"^2.7.16"
vue-click-outside	"^1.1.0"
vue-cropperjs	"^4.2.0"
vue-frag	"^1.4.2"
vue-infinite-loading	"^2.4.5"
vue-localstorage	"^0.6.2"
vue-material-design-icons	"^5.3.1"
vue-router	"^3.6.5"
vuedraggable	"^2.24.3"
vuex	"^3.6.2"
vuex-router-sync	"^5.0.0"
webdav	"^5.8.0"
devDependencies	
@babel/node	"^7.27.1"
@babel/plugin-transform-private-methods	"^7.27.1"
@babel/preset-typescript	"^7.27.1"
@cypress/vue2	"^2.1.1"
@cypress/webpack-preprocessor	"^6.0.4"
@nextcloud/babel-config	"^1.2.0"
@nextcloud/cypress	"^1.0.0-beta.15"
@nextcloud/eslint-config	"^8.4.2"
@nextcloud/stylelint-config	"^3.1.0"
@nextcloud/typings	"^1.9.1"
@nextcloud/webpack-vue-config	"^6.2.0"
@pinia/testing	"^0.1.7"
@simplewebauthn/types	"^12.0.0"
@testing-library/cypress	"^10.0.3"
@testing-library/jest-dom	"^6.6.3"
@testing-library/user-event	"^14.6.1"
@testing-library/vue	"^5.8.3"
@types/dockerode	"^3.3.41"
@types/wait-on	"^5.3.4"
@vitejs/plugin-vue2	"^2.3.1"
@vitest/coverage-v8	"^2.1.9"
@vue/test-utils	"^1.3.5"
@vue/tsconfig	"^0.5.1"
@zip.js/zip.js	"^2.7.62"
babel-loader	"^9.2.1"
babel-loader-exclude-node-modules-except	"^1.2.1"
babel-plugin-module-resolver	"^5.0.2"
colord	"^2.9.3"
css-loader	"^7.1.2"
cypress	"^13.17.0"
cypress-axe	"^1.6.0"
cypress-delete-downloads-folder	"^0.0.6"
cypress-if	"^1.13.2"
cypress-split	"^1.24.18"
cypress-wait-until	"^3.0.2"
dockerode	"^4.0.7"
eslint-plugin-cypress	"^3.6.0"
eslint-plugin-es	"^4.1.0"
exports-loader	"^5.0.0"
file-loader	"^6.2.0"
handlebars-loader	"^1.7.3"
jasmine-core	"~2.99.1"
jasmine-sinon	"^0.4.0"
jsdoc	"^4.0.4"
karma	"^6.4.4"
karma-chrome-launcher	"^3.2.0"
karma-coverage	"2.2.1"
karma-jasmine	"^1.1.2"
karma-jasmine-sinon	"^1.0.4"
karma-spec-reporter	"^0.0.36"
karma-viewport	"^1.0.9"
mime	"^4.0.7"
msw	"^2.10.2"
puppeteer	"^24.10.2"
raw-loader	"^4.0.2"
regextras	"^0.8.0"
sass	"^1.89.2"
sass-loader	"^16.0.5"
sinon	"<= 5.0.7"
style-loader	"^4.0.0"
stylelint	"^16.21.0"
stylelint-use-logical	"^2.1.2"
tar	"^7.4.3"
ts-loader	"^9.5.2"
ts-node	"^10.9.1"
tslib	"^2.8.1"
typescript	"^5.8.3"
vitest	"^2.0.5"
vue-loader	"^15.9.8"
vue-template-compiler	"^2.7.16"
wait-on	"^8.0.3"
webpack	"^5.99.9"
webpack-cli	"^5.0.2"
webpack-merge	"^6.0.1"
workbox-webpack-plugin	"^7.3.0"
browserslist	
0	"extends @nextcloud/browserslist-config"
engines	
node	"^20.0.0"
npm	"^10.0.0"
overrides	
colors	"1.4.0"

EDIT:

I think I found some info:

Summary / Description

CVE-2025-58751 is a directory traversal vulnerability that allows an attacker to access files outside the intended document root, particularly the package.json file. By sending a crafted HTTP request with path traversal (../), the attacker can potentially retrieve sensitive project metadata stored in package.json. This file may contain information such as dependencies, versions, and, in some cases, potentially sensitive data such as API keys or internal URLs.

Affected Resource

  • Exposed URL: ../package.json

  • The vulnerability occurs when the server fails to properly sanitize file paths, allowing unauthorized access to files outside the intended directory structure.

Impact

While rated low severity, the potential impacts of this vulnerability include:

  • Information Disclosure: Attackers could gain valuable information about the application’s dependencies, versions, and configurations. This can assist in crafting targeted attacks, such as exploiting known vulnerabilities in outdated packages.

  • Reconnaissance: By learning about the application stack, attackers could identify areas of potential weakness or determine if specific exploits are viable based on the disclosed dependencies.

  • Exposure of Secrets (if misconfigured): If sensitive information such as API keys, tokens, or internal URLs are accidentally stored in package.json or similar files, this could escalate the severity of the issue.

Safe — Non-actionable — Steps to reproduce (high level)

The following steps are for authorized testing only.

  1. Send an HTTP GET request to the vulnerable endpoint with a path traversal sequence targeting package.json:

    • Example: GET /../package.json HTTP/1.1
  2. Observe the HTTP response:

    • If the server returns a successful response (HTTP status 200) with the content of package.json, this confirms the vulnerability.

    • If the server returns 403, 404, or another error, the path traversal attempt was successfully blocked.

  3. Review the content of the exposed package.json file:

    • Look for potentially sensitive information, such as dependencies, internal URLs, or any misconfigured secrets.
  4. Ensure that no other sensitive files are exposed (e.g., .env, .git/*, etc.).

Recommendations & Remediation

To mitigate and fix this vulnerability, follow these best practices:

  1. Fix Path Handling (Primary Fix):

    • Properly canonicalize and validate file paths before allowing access to files. Ensure that user input is sanitized and that ../ (directory traversal) sequences are rejected.

    • Use secure methods for resolving paths in your application. In Node.js, for example, use path.resolve() to ensure paths are always resolved relative to a defined base directory.

  2. Block Access to Sensitive Files:

    • Explicitly deny access to sensitive configuration files such as package.json, .env, .git/*, npm-shrinkwrap.json, etc., from being publicly accessible.

    • Example for nginx:

      location ~* /(package\.json|\.env|\.git) {
          return 403;
      }
      
      
    • Example for Apache (using .htaccess):

      <FilesMatch "^(package\.json|\.env)$">
          Require all denied
      </FilesMatch>
      
      
  3. Restrict Access to Sensitive Configuration Files:

    • Ensure that package.json and similar files are not served through publicly accessible endpoints unless absolutely necessary. Instead, consider storing such files in directories outside the web root or restricting access with authentication.
  4. Sanitize and Validate User Input:

    • Sanitize and validate all user inputs, particularly for paths. Ensure that path traversal patterns (../) are not allowed and that users cannot influence the file path.

    • If your application serves files based on user input, ensure that input validation checks are comprehensive and reject potentially dangerous requests.

  5. Monitor for Suspicious Access:

    • Set up logging and monitoring for attempts to access sensitive files, especially when directory traversal is involved. Alerts can be triggered for unusual requests targeting files such as package.json.

    • Review logs regularly for any access attempts to files that should not be exposed.

  6. Secrets Management:

    • Review package.json and other files for accidentally committed sensitive data such as API keys, tokens, or credentials. Move such secrets to secure storage like environment variables, or use a secrets management system.

    • If any secrets are found in package.json, rotate them immediately and update your application accordingly.

  7. Security Testing:

    • Regularly perform security scans and penetration testing to identify and fix any potential vulnerabilities, including directory traversal or unintentional file disclosures.

Suggested Timeline & Priorities

  • Immediate (within 24-48 hours): Add rules to block access to package.json and other sensitive files. Begin logging and monitoring suspicious file access attempts.

  • Short term (within 1 week): Implement proper file path validation and canonicalization in the application to prevent path traversal.

  • Long term (within 1 month): Conduct a thorough review of file handling throughout the application, particularly around static file access, and implement best practices for securing configuration files.

Notes

  • Although this issue is low in severity, it is still critical to reduce the exposure of internal application details that could be used for targeted attacks. Even low-impact vulnerabilities can be used to facilitate higher-severity attacks.

  • If you find other sensitive files exposed (e.g., .env or .git), these should be treated as higher priority and immediately remediated.

2 Likes

Path traversal isn’t allowed. The package.json is located in the web root like composer.json.
You get to the same package.json no matter if you use one of the following.

  • /package.json
  • /../package.json
  • /../../package.json

It looks like it’s normal in Nextcloud that those json files are located in the web root, see also Can Access composer.json and package.json Anonymously - ℹ️ Support - Nextcloud community

As there’s not really sensitive information in those json files and there’s no access to files outside the web root the only thing we could think about is to block “.json” but I’m not sure if this would have some bad impact.