Automattic / knox

S3 Lib
MIT License
1.74k stars 285 forks source link

Incorrect sign in function signedUrl when filename contains special chars: !'()#*+? #334

Open victornikitin opened 3 years ago

victornikitin commented 3 years ago

Function signedUrl works incorrect with filenames containig special chars.

Problem: Filename for creating sign is converted with code: pathname = url.parse(filename).pathname

But filename for returning url is converted with code: return this.url(filename)

Function this.url includes conversion by internal function encodeSpecialCharacters, that converts special symbols: !'()#*+?. But url.parse does not convert these special chars. So results are different. Difference in url & sign cause S3 error SignatureDoesNotMatch.

Example: For Filename: file (1).png In sign is: file%20(1).png In url is: file%20%281%29.png

No workaround: I can't prepare filename by myself outside the knox. Because if I convert special chars in filename before knox, knox will double convert % char (% → %25) and sign will be incorect again. For this example: file%2520%25281%2529.png.

Please, help!

victornikitin commented 3 years ago

There is also a problem with non latin symbols (for example Russian).

Example: For Filename: визитка.png In sign is: визитка.png In url is: %D0%B2%D0%B8%D0%B7%D0%B8%D1%82%D0%BA%D0%B0.png

Again no workaround: If I call encodeURI before knox, sign will be ok, but returnin url will again have double converted % char (% → %25). For this example url become: %25D0%25B2%25D0%25B8%25D0%25B7%25D0%25B8%25D1%2582%25D0%25BA%25D0%25B0.png

victornikitin commented 3 years ago

Solution: Pathname for sign should be generated like: pathname = url.parse(encodeSpecialCharacters(filename)).pathname

As I have tested that helped for spechial chars & for non latin chars.