Fix http path bug (#16117)
* Fix http path bug * Add missed request * add tests Co-authored-by: 6543 <6543@obermui.de>
This commit is contained in:
		
							parent
							
								
									1bfb0a24d8
								
							
						
					
					
						commit
						da057996d5
					
				
					 3 changed files with 131 additions and 0 deletions
				
			
		
							
								
								
									
										69
									
								
								integrations/git_smart_http_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								integrations/git_smart_http_test.go
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,69 @@ | ||||||
|  | // Copyright 2021 The Gitea Authors. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a MIT-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | package integrations | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"io/ioutil" | ||||||
|  | 	"net/http" | ||||||
|  | 	"net/url" | ||||||
|  | 	"testing" | ||||||
|  | 
 | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func TestGitSmartHTTP(t *testing.T) { | ||||||
|  | 	onGiteaRun(t, testGitSmartHTTP) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func testGitSmartHTTP(t *testing.T, u *url.URL) { | ||||||
|  | 	var kases = []struct { | ||||||
|  | 		p    string | ||||||
|  | 		code int | ||||||
|  | 	}{ | ||||||
|  | 		{ | ||||||
|  | 			p:    "user2/repo1/info/refs", | ||||||
|  | 			code: 200, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			p:    "user2/repo1/HEAD", | ||||||
|  | 			code: 200, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			p:    "user2/repo1/objects/info/alternates", | ||||||
|  | 			code: 404, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			p:    "user2/repo1/objects/info/http-alternates", | ||||||
|  | 			code: 404, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			p:    "user2/repo1/../../custom/conf/app.ini", | ||||||
|  | 			code: 404, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			p:    "user2/repo1/objects/info/../../../../custom/conf/app.ini", | ||||||
|  | 			code: 404, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			p:    `user2/repo1/objects/info/..\..\..\..\custom\conf\app.ini`, | ||||||
|  | 			code: 400, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for _, kase := range kases { | ||||||
|  | 		t.Run(kase.p, func(t *testing.T) { | ||||||
|  | 			p := u.String() + kase.p | ||||||
|  | 			req, err := http.NewRequest("GET", p, nil) | ||||||
|  | 			assert.NoError(t, err) | ||||||
|  | 			req.SetBasicAuth("user2", userPassword) | ||||||
|  | 			resp, err := http.DefaultClient.Do(req) | ||||||
|  | 			assert.NoError(t, err) | ||||||
|  | 			defer resp.Body.Close() | ||||||
|  | 			assert.EqualValues(t, kase.code, resp.StatusCode) | ||||||
|  | 			_, err = ioutil.ReadAll(resp.Body) | ||||||
|  | 			assert.NoError(t, err) | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -366,7 +366,26 @@ func (h *serviceHandler) setHeaderCacheForever() { | ||||||
| 	h.w.Header().Set("Cache-Control", "public, max-age=31536000") | 	h.w.Header().Set("Cache-Control", "public, max-age=31536000") | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func containsParentDirectorySeparator(v string) bool { | ||||||
|  | 	if !strings.Contains(v, "..") { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | 	for _, ent := range strings.FieldsFunc(v, isSlashRune) { | ||||||
|  | 		if ent == ".." { | ||||||
|  | 			return true | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func isSlashRune(r rune) bool { return r == '/' || r == '\\' } | ||||||
|  | 
 | ||||||
| func (h *serviceHandler) sendFile(contentType, file string) { | func (h *serviceHandler) sendFile(contentType, file string) { | ||||||
|  | 	if containsParentDirectorySeparator(file) { | ||||||
|  | 		log.Error("request file path contains invalid path: %v", file) | ||||||
|  | 		h.w.WriteHeader(http.StatusBadRequest) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
| 	reqFile := path.Join(h.dir, file) | 	reqFile := path.Join(h.dir, file) | ||||||
| 
 | 
 | ||||||
| 	fi, err := os.Stat(reqFile) | 	fi, err := os.Stat(reqFile) | ||||||
|  |  | ||||||
							
								
								
									
										43
									
								
								routers/web/repo/http_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								routers/web/repo/http_test.go
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,43 @@ | ||||||
|  | // Copyright 2021 The Gitea Authors. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a MIT-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | package repo | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"testing" | ||||||
|  | 
 | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func TestContainsParentDirectorySeparator(t *testing.T) { | ||||||
|  | 	tests := []struct { | ||||||
|  | 		v string | ||||||
|  | 		b bool | ||||||
|  | 	}{ | ||||||
|  | 		{ | ||||||
|  | 			v: `user2/repo1/info/refs`, | ||||||
|  | 			b: false, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			v: `user2/repo1/HEAD`, | ||||||
|  | 			b: false, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			v: `user2/repo1/some.../strange_file...mp3`, | ||||||
|  | 			b: false, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			v: `user2/repo1/../../custom/conf/app.ini`, | ||||||
|  | 			b: true, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			v: `user2/repo1/objects/info/..\..\..\..\custom\conf\app.ini`, | ||||||
|  | 			b: true, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for i := range tests { | ||||||
|  | 		assert.EqualValues(t, tests[i].b, containsParentDirectorySeparator(tests[i].v)) | ||||||
|  | 	} | ||||||
|  | } | ||||||
		Loading…
	
		Reference in a new issue