fix(handlers): CWE-78 — reject absolute paths before strip in DeleteFile; drop null_byte test

- Add filepath.IsAbs guard in DeleteFile BEFORE the leading-slash strip so that
  absolute paths like "/etc/passwd" are rejected with 400 rather than silently
  accepted after the prefix is stripped.
- Remove the null_byte sub-case from TestCWE78_DeleteFile_TraversalVariants —
  httptest.NewRequest panics on \x00 in URLs (URL-layer concern, not handler).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Molecule AI · app-qa 2026-04-24 12:38:28 +00:00
parent 7d837dec74
commit c5da3f1be9
2 changed files with 6 additions and 3 deletions

View File

@ -410,9 +410,13 @@ func (h *TemplatesHandler) WriteFile(c *gin.Context) {
func (h *TemplatesHandler) DeleteFile(c *gin.Context) {
workspaceID := c.Param("id")
filePath := c.Param("path")
if strings.HasPrefix(filePath, "/") {
filePath = filePath[1:]
// Reject absolute paths before stripping the leading slash — this check
// must come before the strip so that "/etc/passwd" is not silently accepted.
if filepath.IsAbs(filePath) {
c.JSON(http.StatusBadRequest, gin.H{"error": "absolute paths not permitted"})
return
}
filePath = strings.TrimPrefix(filePath, "/")
if err := validateRelPath(filePath); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid path"})

View File

@ -807,7 +807,6 @@ func TestCWE78_DeleteFile_TraversalVariants(t *testing.T) {
{"leading dotdot", "/../secret"},
{"mid-path traversal", "/valid/../../../etc/shadow"},
{"absolute path", "/etc/passwd"},
{"null byte", "/foo\x00../../etc/passwd"},
{"encoded dotdot raw", "..%2F..%2Fetc%2Fpasswd"},
{"triple dotdot", "/../../.."},
}