ocis icon indicating copy to clipboard operation
ocis copied to clipboard

PATCH request for TUS upload with wrong checksum gives incorrect response

Open swoichha opened this issue 4 years ago • 3 comments

Describe the bug

According to the TUS checksum extension description in https://tus.io/protocols/resumable-upload.html#checksum when a PATCH request is send with an Upload-Checksum header depending on the result the server may respond with one of the following status code: 1.400 Bad Request if the checksum algorithm is not supported by the server 2. 460 Checksum Mismatch if the checksums mismatch 3. 204 No Content if the checksums match and the processing of the data succeeded But when we send PATCH request with wrong checksum then instead of 460 Checksum Mismatch we get 204 No Content

Steps to reproduce

Steps to reproduce the behavior:

  1. Create a base64 encoding of a file name
  • echo -n "textFile.txt" | base64 (example dGV4dEZpbGUudHh0)
  1. As user Einstein send a POST request to create resource which will give a resource location url.
 curl -k -X POST -u einstein:relativity   https://localhost:9200/remote.php/dav/files/Einstein/  -H 'Tus-Resumable: 1.0.0' -H 'Upload-Length: 5' -H 'Upload-Metadata: filename dGV4dEZpbGUudHh0' -v
  1. User Einstein send PATCH request to upload data to the location url along with a wrong checkum For example: correct sha1sum for '12345' is 8cb2237d0679ca88db6464eac60da96345513964 but we are sending wrong value i.e. 01b307acba4f54f55aafc33bb06bbbf6ca803e9a:
curl -k -X PATCH <your TUS resource Location> -u einstein:relativity -H 'Content-Type: application/offset+octet-stream' -H 'Tus-Resumable: 1.0.0' -H 'Upload-Offset: 0' -H'Upload-Checksum:sha1 01b307acba4f54f55aafc33bb06bbbf6ca803e9a' -d '12345' -v

Expected behavior

HTTP/1.1 460 Checksum Mismatch
Tus-Resumable: 1.0.0
Upload-Offset: 5

Actual behavior

HTTP/1.1 204 No content
Tus-Resumable: 1.0.0
Upload-Offset: 5

While doing PROPFIND it can be seen that the file textFile.txt has been created and it gives the correct checksum and ignores the incorrect checksum send during PATCH request.

curl -X PROPFIND -u einstein:relativity https://localhost:9200/remote.php/webdav -k | xmllint --format -
    % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1676  100  1676    0     0  27032      0 --:--:-- --:--:-- --:--:-- 27032
<?xml version="1.0" encoding="utf-8"?>
<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:oc="http://owncloud.org/ns">
  <d:response>
    <d:href>/remote.php/webdav/</d:href>
    <d:propstat>
      <d:prop>
        <oc:id>MTI4NGQyMzgtYWE5Mi00MmNlLWJkYzQtMGIwMDAwMDA5MTU3OjA2OTRjZjY4LWYxOGUtNDY1ZC1hMzlkLTEzNWFkM2RkMjg3ZA==</oc:id>
        <oc:fileid>MTI4NGQyMzgtYWE5Mi00MmNlLWJkYzQtMGIwMDAwMDA5MTU3OjA2OTRjZjY4LWYxOGUtNDY1ZC1hMzlkLTEzNWFkM2RkMjg3ZA==</oc:fileid>
        <d:getetag>"7bdfa13e5b7a5a4cdd27fb7550617b10"</d:getetag>
        <oc:permissions>DNVCKR</oc:permissions>
        <d:resourcetype>
          <d:collection/>
        </d:resourcetype>
        <oc:size>5</oc:size>
        <d:getlastmodified>Thu, 04 Mar 2021 06:38:01 GMT</d:getlastmodified>
        <oc:favorite>0</oc:favorite>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
  <d:response>
    <d:href>/remote.php/webdav/textFile.txt</d:href>
    <d:propstat>
      <d:prop>
        <oc:id>MTI4NGQyMzgtYWE5Mi00MmNlLWJkYzQtMGIwMDAwMDA5MTU3Ojg2NzI2NzA5LTNlOTQtNDcxZS04YTAyLTAzOTdlMzdjYzdhYw==</oc:id>
        <oc:fileid>MTI4NGQyMzgtYWE5Mi00MmNlLWJkYzQtMGIwMDAwMDA5MTU3Ojg2NzI2NzA5LTNlOTQtNDcxZS04YTAyLTAzOTdlMzdjYzdhYw==</oc:fileid>
        <d:getetag>"a5cf632982d978b971264c7edddb2738"</d:getetag>
        <oc:permissions>DNVWR</oc:permissions>
        <d:resourcetype/>
        <d:getcontentlength>5</d:getcontentlength>
        <d:getcontenttype>text/plain; charset=utf-8</d:getcontenttype>
        <d:getlastmodified>Thu, 04 Mar 2021 06:38:01 GMT</d:getlastmodified>
        <oc:checksums>
          <oc:checksum>SHA1:8cb2237d0679ca88db6464eac60da96345513964 MD5:827ccb0eea8a706c4c34a16891f84e7b ADLER32:02f80100</oc:checksum>
        </oc:checksums>
        <oc:favorite>0</oc:favorite>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
</d:multistatus>

swoichha avatar Mar 03 '21 08:03 swoichha

tested on ocis 6.0.0 still relevant

ScharfViktor avatar Jun 26 '24 10:06 ScharfViktor

@micbar @butonic @aduffeck There are few points for discussion:

  • Why do we stick to the v1 of tus/tusd packge if v2 was already realised a long time back?
  • It looks like the checksum extensions to tusd have been available since V2, How to enable checksum? https://github.com/cs3org/reva/blob/f4b705be700c9c374d5ab84cc9d5dfa58aa2be46/pkg/storage/utils/decomposedfs/upload/upload.go#L68

2403905 avatar Jul 11 '24 08:07 2403905

Yes, we need to switch to v2 version if we want this fixed. See accurate description of the problem here: https://github.com/cs3org/reva/blob/edge/pkg/storage/utils/decomposedfs/upload/upload.go#L68-L71 (tusd v1 simply doesn't support it...)

kobergj avatar Jul 30 '24 09:07 kobergj

How do we continue here? Do we update to version 2? What is the downside?

dragotin avatar Aug 09 '24 13:08 dragotin

v2 has landed on master. I'll try making progress here next week :+1:

kobergj avatar Aug 09 '24 14:08 kobergj

Tried to add support for chunk based checksum checking here https://github.com/cs3org/reva/pull/4807 but we hit several walls.

A) Mixed checksum format during test. The format in which the checksum headers are sent differs within test. Tests not specifying a checksum use the tus-php package which base64 encodes the checksum. Test that specify a checksum do not base64 encode. The tus spec states that the header should be base64 encoded.

B) Breaking bug in tus-php package The tus-php contains a breaking bug. It always sends the checksum for the complete file instead of the checksum for one chunk. https://github.com/ankitpokhrel/tus-php/issues/422 This means the tests are sending wrong requests when making multiple requests.

We could get pass A by adjusting all tests. But B is breaking as we cannot control it. We have two options: fix it upstream (if possible) or switch to different tus package for php tests.

kobergj avatar Aug 14 '24 14:08 kobergj

There does not seem to be another up to date php tus client library: https://tus.io/implementations

butonic avatar Aug 14 '24 14:08 butonic