Reject credential and other unsupported keys in `files_external:option`
Nobody has claimed this yet.
- Dominant language
- PHP
- Stars
- 36.9k
- Forks
- 5.2k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 713
Description
⚠️ This issue respects the following points: ⚠️
- This is a bug, not a question or a configuration/webserver/proxy issue.
- This issue is not already reported on Github OR Nextcloud Community Forum (I've searched it).
- Nextcloud Server is up to date. See Maintenance and Release Schedule for supported versions.
- I agree to follow Nextcloud's Code of Conduct.
Bug description
When configuring SMB external storage via occ, using:
php occ files_external:option <mount_id> password ''
stores a password field as a mount option. It can then be exposed in plaintext via:
php occ files_external:list --output=json
as options.password.
This is problematic for two reasons:
- It’s a potential secret-leak footgun (password in plaintext options output).
- It does not reliably set the SMB authentication credential where the SMB backend expects it (the correct credential setter is php occ files_external:config <mount_id> password '').
I’m proposing guardrails/warnings (or rejection) when attempting to set option keys like password via files_external:option, and updating docs/examples to steer admins to files_external:config for credential setting.
Steps to reproduce
- On a Nextcloud Server instance with the External storage support app enabled, create an SMB external storage mount (any valid SMB host/share/user is fine) and note the returned mount id
<mount_id>. - Run the following command to “set the password” via
option:
php occ files_external:option <mount_id> password 'example-password'
3. List mounts in JSON:
php occ files_external:list --output=json
- Observe that the JSON for that mount includes a plaintext
options.passwordfield. - Now set the password via the correct command:
php occ files_external:config <mount_id> password 'example-password'
php occ files_external:list --output=json
- Observe that
configuration.passwordis treated as a credential (redacted in output), andoptions.passwordshould not be used for credentials.
Expected behavior
I expected files_external:option <mount_id> password ... to either:
• be rejected (because password is a credential, not a mount option), or
• at minimum emit a clear warning that credentials must be set via files_external:config, and that storing a password as an option may expose it in output.
I also expected files_external:list --output=json to never include a plaintext password under options.* for any mount.
Nextcloud Server version
32
Operating system
Debian/Ubuntu
PHP engine version
PHP 8.3
Web server
Nginx
Database engine version
MariaDB
Is this bug present after an update or on a fresh install?
Updated from a MINOR version (ex. 32.0.1 to 32.0.2)
Are you using the Nextcloud Server Encryption module?
Encryption is Disabled
What user-backends are you using?
- Default user-backend (database)
- LDAP/ Active Directory
- SSO - SAML
- Other
Configuration report
{
"system": {
"passwordsalt": "***REMOVED SENSITIVE VALUE***",
"secret": "***REMOVED SENSITIVE VALUE***",
"trusted_domains": [
"localhost",
"wm3v.com",
"nextcloud",
"192.168.39.200"
],
"datadirectory": "***REMOVED SENSITIVE VALUE***",
"overwrite.cli.url": "https:\/\/wm3v.com\/nextcloud",
"dbtype": "mysql",
"version": "32.0.4.1",
"dbname": "***REMOVED SENSITIVE VALUE***",
"dbhost": "***REMOVED SENSITIVE VALUE***",
"dbport": "",
"dbtableprefix": "oc_",
"dbuser": "***REMOVED SENSITIVE VALUE***",
"dbpassword": "***REMOVED SENSITIVE VALUE***",
"installed": true,
"instanceid": "***REMOVED SENSITIVE VALUE***",
"ldapIgnoreNamingRules": false,
"ldapProviderFactory": "\\OCA\\User_LDAP\\LDAPProviderFactory",
"updatechecker": false,
"memcache.local": "\\OC\\Memcache\\APCu",
"integrity.check.disabled": true,
"filelocking.enabled": true,
"memcache.locking": "\\OC\\Memcache\\Redis",
"redis": {
"host": "***REMOVED SENSITIVE VALUE***",
"port": "6379",
"timeout": "0.0",
"password": "***REMOVED SENSITIVE VALUE***"
},
"logout_url": "https:\/\/wm3v.com\/yunohost\/sso\/?action=logout&r=aHR0cHM6Ly93bTN2LmNvbS9uZXh0Y2xvdWQ=",
"updater.release.channel": "stable",
"maintenance": false,
"theme": "",
"config_is_read_only": false,
"loglevel": 2,
"logtimezone": "America\/Denver",
"default_phone_region": "US",
"mail_smtpmode": "smtp",
"mail_sendmailmode": "smtp",
"mail_from_address": "***REMOVED SENSITIVE VALUE***",
"mail_domain": "***REMOVED SENSITIVE VALUE***",
"mail_smtpauthtype": "LOGIN",
"mail_smtphost": "***REMOVED SENSITIVE VALUE***",
"mail_smtpport": "25",
"mail_smtpauth": 1,
"mail_smtpname": "***REMOVED SENSITIVE VALUE***",
"mail_smtppassword": "***REMOVED SENSITIVE VALUE***",
"mail_smtpsecure": "ssl",
"hashing_default_password": true,
"mysql.utf8mb4": true,
"app_install_overwrite": {
"0": "spreed",
"1": "sharerenamer",
"2": "files_reader",
"3": "radio",
"4": "occweb",
"6": "files_frommail",
"7": "richdocuments",
"8": "duplicatefinder",
"9": "ransomware_protection",
"10": "inventory",
"11": "hedgenext"
},
"localstorage.allowsymlinks": true,
"simpleSignUpLink.shown": false,
"mail_smtpstreamoptions": {
"ssl": {
"allow_self_signed": true,
"verify_peer": false,
"verify_peer_name": false
}
},
"logfile": "\/var\/log\/nextcloud\/nextcloud.log",
"maintenance_window_start": 1,
"quota_include_external_storage": false,
"trusted_proxies": "***REMOVED SENSITIVE VALUE***",
"trashbin_retention_obligation": "auto, 30",
"versions_retention_obligation": "auto, 30",
"forbidden_filename_basenames": [
"con",
"prn",
"aux",
"nul",
"com0",
"com1",
"com2",
"com3",
"com4",
"com5",
"com6",
"com7",
"com8",
"com9",
"com\u00b9",
"com\u00b2",
"com\u00b3",
"lpt0",
"lpt1",
"lpt2",
"lpt3",
"lpt4",
"lpt5",
"lpt6",
"lpt7",
"lpt8",
"lpt9",
"lpt\u00b9",
"lpt\u00b2",
"lpt\u00b3"
],
"forbidden_filename_characters": [
"<",
">",
":",
"\"",
"|",
"?",
"*",
"\\",
"\/"
],
"forbidden_filename_extensions": [
" ",
".",
".filepart",
".part"
]
}
}
List of activated Apps
Enabled:
- activity: 5.0.0-dev.0
- admin_audit: 1.22.0
- audioplayer: 3.7.0
- camerarawpreviews: 0.8.8
- circles: 32.0.0
- cloud_federation_api: 1.16.0
- comments: 1.22.0
- contactsinteraction: 1.13.1
- dav: 1.34.2
- epubviewer: 1.9.2
- federatedfilesharing: 1.22.0
- files: 2.4.0
- files_3dmodelviewer: 0.0.16
- files_external: 1.24.0
- files_fulltextsearch: 32.0.2
- files_pdfviewer: 5.0.0-dev.0
- files_sharing: 1.24.1
- files_trashbin: 1.22.0
- files_versions: 1.25.0
- forms: 5.2.3
- fulltextsearch: 32.0.0
- impersonate: 3.0.1
- keeweb: 0.6.22
- logreader: 5.0.0-dev.0
- lookup_server_connector: 1.20.0
- nextcloud_announcements: 4.0.0-dev.0
- notes: 4.12.4
- notifications: 5.0.0-dev.0
- notify_push: 1.3.0
- oauth2: 1.20.0
- password_policy: 4.0.0-dev.0
- passwords: 2026.2.20
- photos: 5.0.0-dev.1
- privacy: 4.0.0-dev.0
- profile: 1.1.0
- provisioning_api: 1.22.0
- secrets: 2.1.6
- serverinfo: 4.0.0-dev.0
- settings: 1.15.1
- spreed: 22.0.9
- support: 4.0.0-dev.0
- text: 6.0.1
- theming: 2.7.0
- thesearchpage: 2.0.5
- twofactor_backupcodes: 1.21.0
- user_ldap: 1.23.0
- user_status: 1.12.0
- user_usage_report: 3.0.0
- viewer: 5.0.0-dev.0
- weather_status: 1.12.0
- webhook_listeners: 1.3.0
- workflowengine: 2.14.0
Disabled:
- app_api: 32.0.0 (installed 5.0.2)
- assistant: 2.12.0 (installed 2.12.0)
- bruteforcesettings: 5.0.0-dev.0 (installed 2.9.0)
- cadviewer: 10.10.7 (installed 10.10.7)
- context_chat: 5.2.0 (installed 5.2.0)
- dashboard: 7.12.0 (installed 7.2.0)
- dicomviewer: 2.3.1 (installed 2.3.1)
- encryption: 2.20.0
- federation: 1.22.0 (installed 1.9.0)
- files_downloadlimit: 5.0.0-dev.0 (installed 2.0.0)
- files_linkeditor: 1.1.23 (installed 1.1.23)
- files_photospheres: 1.32.0 (installed 1.32.0)
- files_reader: 1.5.3 (installed 1.5.3)
- files_reminders: 1.5.0 (installed 1.2.0)
- files_rightclick: 1.6.0 (installed 1.6.0)
- firstrunwizard: 5.0.0-dev.0 (installed 2.8.0)
- integration_openai: 3.10.0 (installed 3.10.0)
- inventory: 0.1.3 (installed 0.1.3)
- keeporsweep: 0.3.0 (installed 0.3.0)
- occweb: 0.2.3 (installed 0.2.3)
- ransomware_protection: 1.14.0 (installed 1.14.0)
- recommendations: 5.0.0-dev.0 (installed 0.7.0)
- related_resources: 3.0.0-dev.0 (installed 1.4.0)
- richdocuments: 9.0.2 (installed 9.0.2)
- richdocumentscode: 25.4.702 (installed 25.4.702)
- sharebymail: 1.22.0 (installed 1.8.0)
- sms_relentless: 1.4.4 (installed 1.4.4)
- survey_client: 4.0.0-dev.0 (installed 1.17.0)
- suspicious_login: 10.0.0-dev.0
- systemtags: 1.22.0 (installed 1.19.0)
- twofactor_nextcloud_notification: 6.0.0-dev.0
- twofactor_totp: 14.0.0
- updatenotification: 1.22.0 (installed 1.21.0)
- wordfind: 1.4.2 (installed 1.4.2)
- workflow_media_converter: 1.15.1 (installed 1.15.1)
Nextcloud Signing status
Integrity checker has been disabled. Integrity cannot be verified.
Nextcloud Logs
N/A — this report is based on deterministic occ output (files_external:list --output=json) showing options.password after running files_external:option … password …. No specific Nextcloud log entry was required to reproduce.
Additional info
Running on Nextcloud Hub 25 (32.0.4) (YunoHost package 32.0.4~ynh1), PHP-FPM 8.3, MariaDB, nginx, Debian 12. External storage app files_external version 1.24.0. LDAP backend enabled (user_ldap).
Supporting write-up with more context (including YunoHost-specific SMB outage mode):
Related issues found while searching (likely different root causes; listed for context):
• https://github.com/nextcloud/server/issues/58027
• https://github.com/nextcloud/server/issues/30751
• https://github.com/nextcloud/server/issues/29461
• https://github.com/nextcloud/server/issues/3299
• https://github.com/nextcloud/server/issues/57596
• https://github.com/nextcloud/server/issues/36773
Disclosure: I used AI tools (Claude Sonnet 4.6 and OpenClaw / OpenAI Codex gpt‑5.2) to help structure/edit this report; technical claims are based on occ output and observed behavior.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by locating the implementations of the files_external:option, files_external:config, and files_external:list commands in the files_external app, then compare how option and credential values are stored and serialized. Reproduce the commands from the issue and add coverage for unsupported keys such as password; done means credentials are rejected or clearly warned about and are not exposed under options in JSON output.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php
- Domain
- backend, cli, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100