unicode characters in image URL - 404

不打扰是莪最后的温柔 提交于 2021-01-28 02:25:14

问题


I am trying to open an image that has Latin characters in its name (113_Atlético Madrid).

I saved it by encoding its name with the PHP function rawurlencode(), so now its new name is 113_Atl%C3%A9tico%20Madrid. But when I am trying to open it by this URL for example mysite.com/images/113_Atl%C3%A9tico%20Madrid.png I got 404 error.

How I can fix this issue?

PHP code:

if(isset($_FILES['Team'])){
    $avatar = $_FILES['Team'];
    $model->avatar = "{$id}_".rawurlencode($model->name).".png";
    if(!is_file(getcwd()."/images/avatars/competitions/{$model->avatar}")){
        move_uploaded_file($avatar['tmp_name']['avatar'], getcwd()."/images/avatars/teams/{$model->avatar}");
    }
}

回答1:


%-encoding is for URLs. Filenames are not URLs. You use the form:

http://example.org/images/113_Atl%C3%A9tico%20Madrid.png

in the URL, and the web server will decode that to a filename something like:

/var/www/example-site/data/images/113_Atlético Madrid.png

You should use rawurlencode() when you're preparing the filename to go in a URL, but you shouldn't use it to prepare the filename for disc storage.

There is an additional problem here in that storing non-ASCII filenames on disc is something that is unreliable across platforms. Especially if you run on a Windows server, the PHP file APIs like move_uploaded_file() can very likely use an encoding that you didn't want, and you might end up with a filename like 113_Atlético Madrid.png.

There isn't necessarily an easy fix to this, but you could use any form of encoding, even %-encoding. So if you stuck with your current rawurlencode() for making filenames:

/var/www/example-site/data/images/113_Atl%C3%A9tico%20Madrid.png

that would be OK but you would then have to use double-rawurlencode to generate the matching URL:

http://example.org/images/113_Atl%25C3%25A9tico%2520Madrid.png

But in any case, it's very risky to include potentially-user-supplied arbitrary strings as part of a filename. You may be open to directory traversal attacks, where the name contains a string like /../../ to access the filesystem outside of the target directory. (And these attacks commonly escalate for execute-arbitrary-code attacks for PHP apps which are typically deployed with weak permissioning.) You would be much better off using an entirely synthetic name, as suggested (+1) by @MatthewBrown.

(Note this still isn't the end of security problems with allowing user file uploads, which it turns out is a very difficult feature to get right. There are still issues with content-sniffing and plugins that can allow image files to be re-interpreted as other types of file, resulting in cross-site scripting issues. To prevent all possibility of this it is best to only serve user-supplied files from a separate hostname, so that XSS against that host doesn't get you XSS against the main site.)




回答2:


If you do not need to preserve the name of the file (and often there are good reasons not to) then it might be best to simply rename the entirely. The current timestamp is a reasonable choice.

if(isset($_FILES['Team'])){
    $avatar = $_FILES['Team'];
    $date = new DateTime();
    $model->avatar = "{$id}_".$date->format('Y-m-d-H-i-sP').".png";
    if(!is_file(getcwd()."/images/avatars/competitions/{$model->avatar}")){
        move_uploaded_file($avatar['tmp_name']['avatar'], getcwd()."/images/avatars/teams/{$model->avatar}");
    }
}

After all, what the file was called before it was uploaded shouldn't be that important and much more importantly if two users have a picture called "me.png" there is much less chance of a conflict.

If you are married to the idea of encoding the file name then I can only point you to other answers:

  • How do I use filesystem functions in PHP, using UTF-8 strings?
  • PHP - FTP filename encoding issue
  • PHP - Upload utf-8 filename


来源:https://stackoverflow.com/questions/38978495/unicode-characters-in-image-url-404

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!