dongqin6926 2016-01-27 05:09
浏览 60

上传从浏览器(客户端)接收的文件的最安全方法是什么?

I am writing a web app using Golang, and I am writing the file upload part now, but I don't know what is the most secure way to do it.

Can anyone give me some information? Thanks.

Edit: I mean how to prevent users upload their file to the position other than the position I want. User may modify the filename to cause it to be uploaded to a specific directory. Are there any way to prevent it?

And I want to ask if the hacking technique like web shell workable to the web app written in Golang? I think is not, but I want to check if my thinking is right.

  • 写回答

1条回答 默认 最新

  • doucongqian6644 2016-01-27 06:41
    关注

    Your server receives a file (e.g. via a form post), and your server code is responsible to save it to a folder of the server's choice.

    The client has no control over where the server will save it. The client may arbitrarily recommend a folder e.g. with another form field (or a subfolder relative to some agreed or arbitrary root), but the client is not in a position to enforce anything.

    One thing you should be aware of that if you acquire the posted file name at server side, you should not use it as is, because the client may send a file name which contains folder separators (e.g. '/' and it may contain sequences to denote parent folders (e.g. "../..").

    What you should do (most secure) is to generate a name at the server side. Or if you want to use the name recommended by the client, only use the last part of the sent file name (in case it contains folder names too). Also if you use the name sent by the client, you should check if file already exists to prevent independent clients to overwrite each other's files. Or best would be to use a folder name unique to the client, that way there is no chance to overwrite each other's files.

    You may use the path package to check/manipulate file names and paths. For example path.Base() returns only the last part (the file name) of a path. And you may use path.Join() to concatenate folders and file name.

    For example if a client uploads a file via a form post, you may handle it at server side like this:

    func fileHandler(w http.ResponseWriter, r *http.Request) {
        f, fh, err := r.FormFile("file")
        if err != nil {
            // File not submitted? Handle error 
            http.Error(w, "You must upload a file", http.StatusBadRequest)
            return
        }
    
        // Save it:
        // Here I use username as a unique client identifier
        saveName := path.Join("path/to/uploaded/files/", username, path.Base(fh.Filename))
        savef, err := os.Create(saveName)
        if err != nil {
            // Failed to create file on server, handle err
            http.Error(w, "Failed to save file", http.StatusInternalServerError)
            return
        }
        defer savef.Close()
    
        io.Copy(savef, f)
        fmt.Fprintln(w, "File saved successfully.")
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥20 求个正点原子stm32f407开发版的贪吃蛇游戏
  • ¥15 正弦信号发生器串并联电路电阻无法保持同步怎么办
  • ¥15 划分vlan后,链路不通了?
  • ¥20 求各位懂行的人,注册表能不能看到usb使用得具体信息,干了什么,传输了什么数据
  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 Centos / PETGEM
  • ¥15 划分vlan后不通了
  • ¥20 用雷电模拟器安装百达屋apk一直闪退
  • ¥15 算能科技20240506咨询(拒绝大模型回答)
  • ¥15 自适应 AR 模型 参数估计Matlab程序