[SHARING] Credentials including URL are raising an Exception and corrupt the vault (data loss)
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 823
- Forks
- 117
- Avg merge
- 1d 21h
- Merged PRs (30d)
- 8
Description
Bug report
Trying to share login credentials including a url makes passman throwing an excepetion becauses of:
SQLSTATE[42000]: Syntax error or access violation: 1118 Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.
Steps to reproduce
Bug is reproducible in the online demo (did it twice)
- Create credentials with Label: test, Username: test, Password: test & URL: https://www.google.de
- Try to share it with any user
Expected behaviour
User wich got selected for sharing the credentials with, should be able to use the credentials.
Actual behaviour
- Vault gets corrupted if you dont delete the complete dataset instantly. If you try to reopen the vault its not gonna work.
- Selected User gets request for accepting the share but its not gonna work because data is corrupted.
Configuration
Operating system: Windows 10, Fedora 26 (Client)
Browser: FireFox 58, latest Chrome (tried multiple Browsers)
Extensions that might cause interference: none
Passman version: 2.1.5
Operating system: Debian 9 (Server)
Web server: Apache 2.4.25
Database: MariaDB Ver 15.1 Distrib 10.1.26-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2
PHP version: PHP 7.0.19-1
cloud server: Nextcloud
cloud version: 12.0.3
Browser log
Browser log
``` PATCH https://host/index.php/apps/passman/api/v2/credentials/GUID 500 (Internal Server Error) (anonymous) @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:103 n @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:99 (anonymous) @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:96 (anonymous) @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:131 $eval @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:145 $digest @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:142 (anonymous) @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:145 e @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:45 (anonymous) @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:48 setTimeout (async) k.defer @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:48 $evalAsync @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:145 (anonymous) @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:130 e @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:130 then @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:131 m @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:96 m.(anonymous function) @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:100 updateCredential @ credentialservice.js?v=90f886b7a637504e07a5ce000a974531-0:101 (anonymous) @ share.js?v=90f886b7a637504e07a5ce000a974531-0:369 C_Promise.call_then @ promise.js?v=90f886b7a637504e07a5ce000a974531-0:40 (anonymous) @ credentialservice.js?v=90f886b7a637504e07a5ce000a974531-0:352 C_Promise.call_then @ promise.js?v=90f886b7a637504e07a5ce000a974531-0:40 revision_workload @ credentialservice.js?v=90f886b7a637504e07a5ce000a974531-0:284 setTimeout (async) (anonymous) @ credentialservice.js?v=90f886b7a637504e07a5ce000a974531-0:307 (anonymous) @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:131 $eval @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:145 $digest @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:142 $apply @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:146 l @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:97 J @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:102 t.onload @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:103 XMLHttpRequest.send (async) (anonymous) @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:103 n @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:99 (anonymous) @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:96 (anonymous) @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:131 $eval @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:145 $digest @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:142 (anonymous) @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:145 e @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:45 (anonymous) @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:48 setTimeout (async) k.defer @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:48 $evalAsync @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:145 (anonymous) @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:130 e @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:130 then @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:131 m @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:96 m.(anonymous function) @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:99 getRevisions @ credentialservice.js?v=90f886b7a637504e07a5ce000a974531-0:171 promise_revisions_update @ credentialservice.js?v=90f886b7a637504e07a5ce000a974531-0:274 setTimeout (async) C_Promise @ promise.js?v=90f886b7a637504e07a5ce000a974531-0:49 (anonymous) @ credentialservice.js?v=90f886b7a637504e07a5ce000a974531-0:346 C_Promise.call_then @ promise.js?v=90f886b7a637504e07a5ce000a974531-0:40 (anonymous) @ credentialservice.js?v=90f886b7a637504e07a5ce000a974531-0:232 (anonymous) @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:131 $eval @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:145 $digest @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:142 $apply @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:146 l @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:97 J @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:102 t.onload @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:103 XMLHttpRequest.send (async) (anonymous) @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:103 n @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:99 (anonymous) @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:96 (anonymous) @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:131 $eval @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:145 $digest @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:142 $apply @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:146 l @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:97 J @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:102 t.onload @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:103 XMLHttpRequest.send (async) (anonymous) @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:103 n @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:99 (anonymous) @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:96 (anonymous) @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:131 $eval @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:145 $digest @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:142 (anonymous) @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:145 e @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:45 (anonymous) @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:48 setTimeout (async) k.defer @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:48 $evalAsync @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:145 (anonymous) @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:130 e @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:130 then @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:131 m @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:96 m.(anonymous function) @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:99 getCredential @ credentialservice.js?v=90f886b7a637504e07a5ce000a974531-0:111 promise_credential_update @ credentialservice.js?v=90f886b7a637504e07a5ce000a974531-0:213 setTimeout (async) C_Promise @ promise.js?v=90f886b7a637504e07a5ce000a974531-0:49 promise_workload @ credentialservice.js?v=90f886b7a637504e07a5ce000a974531-0:325 setTimeout (async) C_Promise @ promise.js?v=90f886b7a637504e07a5ce000a974531-0:49 reencryptCredential @ credentialservice.js?v=90f886b7a637504e07a5ce000a974531-0:358 (anonymous) @ share.js?v=90f886b7a637504e07a5ce000a974531-0:363 C_Promise.call_then @ promise.js?v=90f886b7a637504e07a5ce000a974531-0:40 (anonymous) @ shareservice.js?v=90f886b7a637504e07a5ce000a974531-0:241 generate @ crypto_wrap.js?v=90f886b7a637504e07a5ce000a974531-0:59 generate @ crypto_wrap.js?v=90f886b7a637504e07a5ce000a974531-0:64 generate @ crypto_wrap.js?v=90f886b7a637504e07a5ce000a974531-0:64 generate @ crypto_wrap.js?v=90f886b7a637504e07a5ce000a974531-0:64 generate @ crypto_wrap.js?v=90f886b7a637504e07a5ce000a974531-0:64 generate @ crypto_wrap.js?v=90f886b7a637504e07a5ce000a974531-0:64 (anonymous) @ shareservice.js?v=90f886b7a637504e07a5ce000a974531-0:239 setTimeout (async) C_Promise @ promise.js?v=90f886b7a637504e07a5ce000a974531-0:49 generateSharedKey @ shareservice.js?v=90f886b7a637504e07a5ce000a974531-0:236 $scope.applyShare @ share.js?v=90f886b7a637504e07a5ce000a974531-0:358 fn @ VM18867:4 b @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:126 e @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:276 $eval @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:145 $apply @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:146 (anonymous) @ angular.min.js?v=90f886b7a637504e07a5ce000a974531-0:276 dispatch @ core.js?v=90f886b7a637504e07a5ce000a974531-0:3 r.handle @ core.js?v=90f886b7a637504e07a5ce000a974531-0:3 ```Cloud log
Cloud log
Doctrine\DBAL\Exception\DriverException: An exception occurred while executing 'UPDATE `oc_passman_credentials` SET `guid` = ?,`vault_id` = ?,`user_id` = ?,`label` = ?,`description` = ?,`created` = ?,`changed` = ?,`tags` = ?,`email` = ?,`username` = ?,`password` = ?,`url` = ?,`icon` = ?,`expire_time` = ?,`files` = ?,`custom_fields` = ?,`otp` = ?,`hidden` = ?,`delete_time` = ?,`shared_key` = ? WHERE `id` = ?' with params [DATA REMOVED]: SQLSTATE[42000]: Syntax error or access violation: 1118 Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.
Maybe favicons should be stored in filesystem instead of database? Their size can vary very.
Thank you very much for making this very useful tool.
Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.
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 with the sharing flow named in share.js, credentialservice.js, shareservice.js, and crypto_wrap.js, then reproduce the URL-sharing steps while checking the cloud log. Inspect the oc_passman_credentials UPDATE and its database schema around the reported row-size error. Done means sharing credentials with a URL completes without an exception or vault corruption and the recipient can use them.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- angularjs, javascript, mariadb, php
- Domain
- api, backend, databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100