wget默认使用正确的文件名

使用wget下载文件的苦恼

最近在使用wget下载文件的时候,发现经过cgi下载的文件如果不自己制定文件名最终下载下来的文件名称会非常乱,比如实际文件名叫做filename.txt但是wget下载之后就变成了d.php?f=2010%2F12%2Ffilename.txt。看着下载的这一堆文件真是心乱如麻,这一堆文件这么多没个好看的名字也不是事儿啊,后续再下载也不能总是重命名啊。于是想着是不是写一个python工具自动把前面那种多余的字符去掉!!

解决方案

突然意识到,wget作为这么强大的工具应该会有选项支持吧!于是经过查找,找到了这个神奇的选项。加上之后表示非常好用,符合预期,其实中间也搜到了另外一个选项–trust-server-names,但是这个没有效果,仍然还是最初的文件名。之后又找到一个选项–content-disposition,使用这个现在之后文件是正常的文件名不再是带有cgi参数的名称了。我们来看一下文档里面对这个选项的解释,当指定了这个选项的时候wget会使用服务器指定的header当中Content-disposition: attachment; filename=file.txt来作为文件名。

1
2
3
4
5
6
7
8
9
10
11
12
--content-disposition
If this is set to on, experimental (not fully-functional) support for
"Content-Disposition" headers is enabled. This can currently result in extra round-trips
to the server for a "HEAD" request, and is known to suffer from a few bugs, which is why
it is not currently enabled by default.
This option is useful for some file-downloading CGI programs that use
"Content-Disposition" headers to describe what the name of a downloaded file should be.
When combined with --metalink-over-http and --trust-server-names, a Content-Type:
application/metalink4+xml file is named using the "Content-Disposition" filename field,
if available.

当使用wget指定了-S选项详细输出server端响应的时候我们是可以看到Content-disposition: attachment; filename=这个字段的,并且当指定了–content-disposition选项时确实会正确设置文件名。

继续挖坑

于是又有另外一个疑惑了,为什么这么好的选项不是默认打开的呢!文档里面也说了,这是个实验性的功能并且会有一些已知的bug,但是想了想没有想到于是简单搜了一下,还真有,在Stack Overflow上面有指明这个选项可能会有一些安全性的问题。跟随它给出的连接继续阅读发现在RFC 6266的Section 7和文档中RFC 2183中给出了说明,大致意思是说如果使用Header当中的Content-disposition字段进行文件名指定时,服务端面临的问题是下载者可能会通过指定恶意的文件名实施网络攻击,例如在下载文件当中指定文件名为/etc/passwd,或者在上传文件时将恶意的执行文件上传为~/bin/more,这些都是有可能的。所以在服务端那里如果真的必须要和客户端通过这个header进行交互的时候一定要做好路径判定,例如只使用basename,而不是用户传递的原始名称。

同时还找到一篇文章描述了当攻击者从服务端进行攻击时的案例,大体方式是通过网页注入的形式在应该渲染html页面的时候可能会导致用户将js代码下载,通过进行相应的重命名甚至会导致用户以为自己从信任的A网站下载了一个文件。

说实话,哪些搞安全的人,真的是太骚气了,🤣

转载请注明来源链接 http://just4fun.im/2018/11/11/wget-content-disposition/ 尊重知识,谢谢:)