Go语言是否对Web请求中的URL进行了清理?

huangapple go评论103阅读模式
英文:

Does Go sanitize URLs for web requests?

问题

我正在实现一个简单的Go语言Web服务器。由于我没有Web开发经验,这对我来说是一个严肃的问题。

假设我正在使用修改过的loadPage函数来提供网页,代码来自这里

func loadPage(title string) []byte {
    filename := title 
    body, _ := ioutil.ReadFile(filename)
    return body
}

func handler(w http.ResponseWriter, req *http.Request) {
    content := loadPage(req.URL.Path[1:])
    fmt.Fprintf(w, "%s", content)
}

从技术上讲,这使我能够以以下形式发送请求:

http://example.com/../../etc/passwd

而代码会愉快地提供/etc/passwd文件,但实际上并没有。这是否意味着Go的http包或http协议本身对../有某种保护,还是我做错了什么,导致存在安全漏洞?

英文:

I was implementing a simple web server in Go. As I have no experience in web development, this striked as a serious question for me.

Let's say I'm serving web pages with a modified loadPage function from here

func loadPage(title string) []byte {
    filename := title 
    body, _ := ioutil.ReadFile(filename)
    return body
}
 
func handler(w http.ResponseWriter, req *http.Request) {
    content := loadPage(req.URL.Path[1:])
    fmt.Fprintf(w, "%s", content)
}

Technically this allows me to write a request in a form of

 http://example.com/../../etc/passwd

and the code would happily serve the /etc/passwd file, but it does not. Does this mean that there is some sort of protection against ../ in the Go http package or http protocol itself, or am I just doing something wrong and it is a security hole?

答案1

得分: 10

net/http在其HTTP请求多路复用器ServeMux中执行此操作:

> ServeMux还负责对URL请求路径进行清理,将包含.或..元素的任何请求重定向到一个等效的不包含.-和..-的URL。

相关的函数是私有函数cleanPath(p string) string,它调用了path.Clean

1415		np := path.Clean(p)

path.Clean执行了适当的删除操作:

 97			case path[r] == '.' && path[r+1] == '.' && (r+2 == n || path[r+2] == '/'):
 98				// ..元素:删除到最后一个/
 99				r += 2
100				switch {
101				case out.w > dotdot:
102					// 可以回溯
103					out.w--
104					for out.w > dotdot && out.index(out.w) != '/' {
105						out.w--
106					}

如果路径没有根路径,还有一个额外的情况,但是上面的cleanPath函数确保路径已经是根路径,如果路径中没有斜杠,则在要清理的路径前面添加一个斜杠。

英文:

net/http does this in its HTTP request multiplexer, ServeMux:

> ServeMux also takes care of sanitizing the URL request path, redirecting any request containing . or .. elements to an equivalent .- and ..-free URL.

The relevant function is the private func cleanPath(p string) string, which calls path.Clean:

1415		np := path.Clean(p)

path.Clean does the appropriate removals:

 97			case path[r] == '.' && path[r+1] == '.' && (r+2 == n || path[r+2] == '/'):
 98				// .. element: remove to last /
 99				r += 2
100				switch {
101				case out.w > dotdot:
102					// can backtrack
103					out.w--
104					for out.w > dotdot && out.index(out.w) != '/' {
105						out.w--
106					}

There's an additional case if the path isn't rooted, but cleanPath above ensures it is so, by prepending a forward-slash to the path to be cleaned if there isn't one already.

huangapple
  • 本文由 发表于 2014年4月25日 14:09:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/23285364.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定