Improve path component validation
Detect when a specific path component tries to escape the path that came before it -- so that a user-provided value can't use '..' to escape the directories laid out by the build system. Change-Id: I02d52d9baadb7152448a34f4e8b573fe3c032b12
This commit is contained in:
@@ -620,21 +620,24 @@ func PathForModuleInstall(ctx AndroidModuleContext, paths ...string) OutputPath
|
|||||||
}
|
}
|
||||||
|
|
||||||
// validateSafePath validates a path that we trust (may contain ninja variables).
|
// validateSafePath validates a path that we trust (may contain ninja variables).
|
||||||
// Ensures that it does not attempt to leave the containing directory.
|
// Ensures that each path component does not attempt to leave its component.
|
||||||
func validateSafePath(ctx PathContext, paths ...string) string {
|
func validateSafePath(ctx PathContext, paths ...string) string {
|
||||||
|
for _, path := range paths {
|
||||||
|
path := filepath.Clean(path)
|
||||||
|
if path == ".." || strings.HasPrefix(path, "../") || strings.HasPrefix(path, "/") {
|
||||||
|
reportPathError(ctx, "Path is outside directory: %s", path)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
// TODO: filepath.Join isn't necessarily correct with embedded ninja
|
// TODO: filepath.Join isn't necessarily correct with embedded ninja
|
||||||
// variables. '..' may remove the entire ninja variable, even if it
|
// variables. '..' may remove the entire ninja variable, even if it
|
||||||
// will be expanded to multiple nested directories.
|
// will be expanded to multiple nested directories.
|
||||||
p := filepath.Join(paths...)
|
return filepath.Join(paths...)
|
||||||
if p == ".." || strings.HasPrefix(p, "../") || strings.HasPrefix(p, "/") {
|
|
||||||
reportPathError(ctx, "Path is outside directory: %s", p)
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return p
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// validatePath validates that a path does not include ninja variables, and does
|
// validatePath validates that a path does not include ninja variables, and that
|
||||||
// not attempt to leave the containing directory.
|
// each path component does not attempt to leave its component. Returns a joined
|
||||||
|
// version of each path component.
|
||||||
func validatePath(ctx PathContext, paths ...string) string {
|
func validatePath(ctx PathContext, paths ...string) string {
|
||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
if strings.Contains(path, "$") {
|
if strings.Contains(path, "$") {
|
||||||
|
@@ -69,6 +69,21 @@ var commonValidatePathTestCases = []strsTestCase{
|
|||||||
out: "",
|
out: "",
|
||||||
err: []error{errors.New("Path is outside directory: /a")},
|
err: []error{errors.New("Path is outside directory: /a")},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
in: []string{"a", "../b"},
|
||||||
|
out: "",
|
||||||
|
err: []error{errors.New("Path is outside directory: ../b")},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
in: []string{"a", "b/../../c"},
|
||||||
|
out: "",
|
||||||
|
err: []error{errors.New("Path is outside directory: ../c")},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
in: []string{"a", "./.."},
|
||||||
|
out: "",
|
||||||
|
err: []error{errors.New("Path is outside directory: ..")},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var validateSafePathTestCases = append(commonValidatePathTestCases, []strsTestCase{
|
var validateSafePathTestCases = append(commonValidatePathTestCases, []strsTestCase{
|
||||||
|
Reference in New Issue
Block a user