mirror of
https://codeberg.org/git-pages/git-pages.git
synced 2026-05-14 03:01:48 +00:00
Make project name validation more consistent and stricter.
Previously, you could issue e.g. a `GET /%2e%2e/%2e%2e` and it would get interpreted as a parent directory path segment in the handler. This didn't result in a path traversal vulnerability when passed to the S3 backend because of a `path.Clean()` call indirectly done by `makeWebRoot()`, but it's prudent to not take chances.
This commit is contained in:
@@ -65,10 +65,14 @@ func GetHost(r *http.Request) (string, error) {
|
||||
return host, nil
|
||||
}
|
||||
|
||||
func IsValidProjectName(name string) bool {
|
||||
return !strings.HasPrefix(name, ".") && !strings.Contains(name, "%")
|
||||
}
|
||||
|
||||
func GetProjectName(r *http.Request) (string, error) {
|
||||
// path must be either `/` or `/foo/` (`/foo` is accepted as an alias)
|
||||
path := strings.TrimPrefix(strings.TrimSuffix(r.URL.Path, "/"), "/")
|
||||
if path == ".index" || strings.HasPrefix(path, ".index/") {
|
||||
if !IsValidProjectName(path) {
|
||||
return "", AuthError{http.StatusBadRequest,
|
||||
fmt.Sprintf("directory name %q is reserved", ".index")}
|
||||
} else if strings.Contains(path, "/") {
|
||||
|
||||
24
src/pages.go
24
src/pages.go
@@ -132,18 +132,20 @@ func getPage(w http.ResponseWriter, r *http.Request) error {
|
||||
err = nil
|
||||
sitePath = strings.TrimPrefix(r.URL.Path, "/")
|
||||
if projectName, projectPath, hasProjectSlash := strings.Cut(sitePath, "/"); projectName != "" {
|
||||
var projectManifest *Manifest
|
||||
var projectMetadata ManifestMetadata
|
||||
projectManifest, projectMetadata, err = backend.GetManifest(
|
||||
r.Context(), makeWebRoot(host, projectName),
|
||||
GetManifestOptions{BypassCache: bypassCache},
|
||||
)
|
||||
if err == nil {
|
||||
if !hasProjectSlash {
|
||||
writeRedirect(w, http.StatusFound, r.URL.Path+"/")
|
||||
return nil
|
||||
if IsValidProjectName(projectName) {
|
||||
var projectManifest *Manifest
|
||||
var projectMetadata ManifestMetadata
|
||||
projectManifest, projectMetadata, err = backend.GetManifest(
|
||||
r.Context(), makeWebRoot(host, projectName),
|
||||
GetManifestOptions{BypassCache: bypassCache},
|
||||
)
|
||||
if err == nil {
|
||||
if !hasProjectSlash {
|
||||
writeRedirect(w, http.StatusFound, r.URL.Path+"/")
|
||||
return nil
|
||||
}
|
||||
sitePath, manifest, metadata = projectPath, projectManifest, projectMetadata
|
||||
}
|
||||
sitePath, manifest, metadata = projectPath, projectManifest, projectMetadata
|
||||
}
|
||||
}
|
||||
if manifest == nil && (err == nil || errors.Is(err, ErrObjectNotFound)) {
|
||||
|
||||
Reference in New Issue
Block a user