notes icon indicating copy to clipboard operation
notes copied to clipboard

Ignoring `readonly` attribute leads to `500` when origin is another instance

Open stefan-niedermann opened this issue 3 years ago • 1 comments

Steps to reproduce

  1. Create a folder with a text file on Nextcloud instance A
  2. Share this folder without write permissions to a user on Nextcloud instance B (via federated sharing)
  3. Move the folder in Nextcloud instance B into your /Notes folder
  4. Try editing and saving it on Nextcloud instance B

Expected behaviour

Http 403 should be returned

Actual behaviour

Http 500 will be returned

Screenshots

image

Server

Please complete the following information.

  • Notes app version: 4.3.1
  • Nextcloud version: 23.0.3
  • OS:
  • Web server:
  • PHP version: 8.1
  • Database: MySQL

Nextcloud configuration:

``` If you have access to your command line run e.g.: sudo -u www-data php occ config:list system from within your Nextcloud installation folder ```

Client

Please complete the following information.

  • Browser (incl. version): Firefox
  • OS: Debian

Log files

{
   "reqId":"YkIQE-M1vxwFYekKdJU9PgAAAB0",
   "level":3,
   "time":"2022-03-28T19:44:23+00:00",
   "remoteAddr":"2a01:c23:c1d5:a700:7801:4875:61b8:ec3b",
   "user":"userB",
   "app":"notes",
   "method":"PUT",
   "url":"/index.php/apps/notes/notes/227690",
   "message":"Controller failed with GuzzleHttp\\Exception\\ClientException",
   "userAgent":"Mozilla/5.0 (X11; Linux x86_64; rv:98.0) Gecko/20100101 Firefox/98.0",
   "version":"23.0.3.2",
   "exception":{
      "Exception":"GuzzleHttp\\Exception\\ClientException",
      "Message":"Client error: `PUT https://a.example.com/public.php/webdav/Shared%20note.md` resulted in a `403 Forbidden` response:\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<d:error xmlns:d=\"DAV:\" xmlns:s=\"http://sabredav.org/ns\">\n  <s:exception>Sabre\\DA (truncated...)\n",
      "Code":403,
      "Trace":[
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/3rdparty/guzzlehttp/guzzle/src/Middleware.php",
            "line":69,
            "function":"create",
            "class":"GuzzleHttp\\Exception\\RequestException",
            "type":"::"
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/3rdparty/guzzlehttp/promises/src/Promise.php",
            "line":204,
            "function":"GuzzleHttp\\{closure}",
            "class":"GuzzleHttp\\Middleware",
            "type":"::",
            "args":[
               "*** sensitive parameters replaced ***"
            ]
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/3rdparty/guzzlehttp/promises/src/Promise.php",
            "line":153,
            "function":"callHandler",
            "class":"GuzzleHttp\\Promise\\Promise",
            "type":"::"
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/3rdparty/guzzlehttp/promises/src/TaskQueue.php",
            "line":48,
            "function":"GuzzleHttp\\Promise\\{closure}",
            "class":"GuzzleHttp\\Promise\\Promise",
            "type":"::",
            "args":[
               "*** sensitive parameters replaced ***"
            ]
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/3rdparty/guzzlehttp/promises/src/Promise.php",
            "line":248,
            "function":"run",
            "class":"GuzzleHttp\\Promise\\TaskQueue",
            "type":"->"
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/3rdparty/guzzlehttp/promises/src/Promise.php",
            "line":224,
            "function":"invokeWaitFn",
            "class":"GuzzleHttp\\Promise\\Promise",
            "type":"->"
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/3rdparty/guzzlehttp/promises/src/Promise.php",
            "line":269,
            "function":"waitIfPending",
            "class":"GuzzleHttp\\Promise\\Promise",
            "type":"->"
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/3rdparty/guzzlehttp/promises/src/Promise.php",
            "line":226,
            "function":"invokeWaitList",
            "class":"GuzzleHttp\\Promise\\Promise",
            "type":"->"
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/3rdparty/guzzlehttp/promises/src/Promise.php",
            "line":62,
            "function":"waitIfPending",
            "class":"GuzzleHttp\\Promise\\Promise",
            "type":"->"
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/3rdparty/guzzlehttp/guzzle/src/Client.php",
            "line":187,
            "function":"wait",
            "class":"GuzzleHttp\\Promise\\Promise",
            "type":"->"
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/lib/private/Http/Client/Client.php",
            "line":329,
            "function":"request",
            "class":"GuzzleHttp\\Client",
            "type":"->"
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/lib/private/Files/Storage/DAV.php",
            "line":515,
            "function":"put",
            "class":"OC\\Http\\Client\\Client",
            "type":"->"
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/lib/private/Files/Storage/DAV.php",
            "line":422,
            "function":"uploadFile",
            "class":"OC\\Files\\Storage\\DAV",
            "type":"->"
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/lib/private/Files/Storage/DAV.php",
            "line":413,
            "function":"writeBack",
            "class":"OC\\Files\\Storage\\DAV",
            "type":"->"
         },
         {
            "function":"OC\\Files\\Storage\\{closure}",
            "class":"OC\\Files\\Storage\\DAV",
            "type":"->",
            "args":[
               "*** sensitive parameters replaced ***"
            ]
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/3rdparty/icewind/streams/src/CallbackWrapper.php",
            "line":119,
            "function":"call_user_func"
         },
         {
            "function":"stream_close",
            "class":"Icewind\\Streams\\CallbackWrapper",
            "type":"->"
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/lib/private/Files/Storage/Common.php",
            "line":209,
            "function":"fclose"
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/lib/private/Files/Storage/DAV.php",
            "line":494,
            "function":"file_put_contents",
            "class":"OC\\Files\\Storage\\Common",
            "type":"->"
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/lib/private/Files/Storage/Wrapper/Wrapper.php",
            "line":258,
            "function":"file_put_contents",
            "class":"OC\\Files\\Storage\\DAV",
            "type":"->"
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/lib/private/Files/Storage/Wrapper/Availability.php",
            "line":274,
            "function":"file_put_contents",
            "class":"OC\\Files\\Storage\\Wrapper\\Wrapper",
            "type":"->"
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/lib/private/Files/Storage/Wrapper/Wrapper.php",
            "line":258,
            "function":"file_put_contents",
            "class":"OC\\Files\\Storage\\Wrapper\\Availability",
            "type":"->"
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/lib/private/Files/View.php",
            "line":1169,
            "function":"file_put_contents",
            "class":"OC\\Files\\Storage\\Wrapper\\Wrapper",
            "type":"->"
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/lib/private/Files/View.php",
            "line":706,
            "function":"basicOperation",
            "class":"OC\\Files\\View",
            "type":"->"
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/lib/private/Files/Node/File.php",
            "line":71,
            "function":"file_put_contents",
            "class":"OC\\Files\\View",
            "type":"->"
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/apps/notes/lib/Service/Note.php",
            "line":171,
            "function":"putContent",
            "class":"OC\\Files\\Node\\File",
            "type":"->"
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/apps/notes/lib/Controller/NotesController.php",
            "line":226,
            "function":"setContent",
            "class":"OCA\\Notes\\Service\\Note",
            "type":"->"
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/apps/notes/lib/Service/Util.php",
            "line":28,
            "function":"OCA\\Notes\\Controller\\{closure}",
            "class":"OCA\\Notes\\Controller\\NotesController",
            "type":"->",
            "args":[
               "*** sensitive parameters replaced ***"
            ]
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/apps/notes/lib/Controller/Helper.php",
            "line":145,
            "function":"retryIfLocked",
            "class":"OCA\\Notes\\Service\\Util",
            "type":"::"
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/apps/notes/lib/Controller/NotesController.php",
            "line":228,
            "function":"handleErrorResponse",
            "class":"OCA\\Notes\\Controller\\Helper",
            "type":"->"
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/lib/private/AppFramework/Http/Dispatcher.php",
            "line":217,
            "function":"update",
            "class":"OCA\\Notes\\Controller\\NotesController",
            "type":"->",
            "args":[
               "*** sensitive parameters replaced ***"
            ]
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/lib/private/AppFramework/Http/Dispatcher.php",
            "line":126,
            "function":"executeController",
            "class":"OC\\AppFramework\\Http\\Dispatcher",
            "type":"->"
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/lib/private/AppFramework/App.php",
            "line":157,
            "function":"dispatch",
            "class":"OC\\AppFramework\\Http\\Dispatcher",
            "type":"->"
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/lib/private/Route/Router.php",
            "line":302,
            "function":"main",
            "class":"OC\\AppFramework\\App",
            "type":"::"
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/lib/base.php",
            "line":1006,
            "function":"match",
            "class":"OC\\Route\\Router",
            "type":"->"
         },
         {
            "file":"/var/www/vhosts/b.example.com/b.example.com/index.php",
            "line":36,
            "function":"handleRequest",
            "class":"OC",
            "type":"::"
         }
      ],
      "File":"/var/www/vhosts/b.example.com/b.example.com/3rdparty/guzzlehttp/guzzle/src/Exception/RequestException.php",
      "Line":113,
      "CustomMessage":"Controller failed with GuzzleHttp\\Exception\\ClientException"
   },
   "id":"6242101826d1c"
}

stefan-niedermann avatar Mar 28 '22 19:03 stefan-niedermann

That's an interesting use case, we don't have this in our CI tests, yet. At first sight, it looks like the Nextcloud framework says, that the file is writable - although it isn't. The Notes app calls OC\Files\Node\File.isUpdateable() for checking writability - which appears to not work in this case. Otherwise the Notes app would have opened the editor in read-only mode.

I would say that's a bug in Nextcloud server, but I'll try to reproduce this for further insights.

korelstar avatar Mar 30 '22 06:03 korelstar