Skip to content

Commit 08d3d28

Browse files
cfsmp3claude
andauthored
security: sanitize user input in temp directory names (#411)
Replace direct use of email in temp directory names with a SHA256 hash to prevent directory traversal attacks. - Add utils/sanitize.go with SafeTempDirPrefix() function - Use 8-character hash of email instead of raw email - Update all tw/*.go files to use SafeTempDirPrefix This prevents potential path traversal if user-controlled email contains special characters like path separators. Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 48d7505 commit 08d3d28

9 files changed

Lines changed: 27 additions & 8 deletions

File tree

backend/utils/sanitize.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package utils
2+
3+
import (
4+
"crypto/sha256"
5+
"encoding/hex"
6+
)
7+
8+
// SafeTempDirPrefix creates a safe prefix for temporary directory names.
9+
// Instead of using user-provided values directly (which could contain path
10+
// separators or special characters), we use a hash of the value.
11+
// This prevents directory traversal attacks while still providing
12+
// unique prefixes per user.
13+
func SafeTempDirPrefix(prefix, userIdentifier string) string {
14+
// Create a short hash of the user identifier
15+
hash := sha256.Sum256([]byte(userIdentifier))
16+
// Use first 8 characters of hex-encoded hash (32 bits of entropy)
17+
shortHash := hex.EncodeToString(hash[:])[:8]
18+
return prefix + shortHash
19+
}

backend/utils/tw/add_task.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ func AddTaskToTaskwarrior(req models.AddTaskRequestBody, dueDate string) error {
1414
return fmt.Errorf("error deleting Taskwarrior data: %v", err)
1515
}
1616

17-
tempDir, err := os.MkdirTemp("", "taskwarrior-"+req.Email)
17+
tempDir, err := os.MkdirTemp("", utils.SafeTempDirPrefix("taskwarrior-", req.Email))
1818
if err != nil {
1919
return fmt.Errorf("failed to create temporary directory: %v", err)
2020
}

backend/utils/tw/complete_task.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ func CompleteTaskInTaskwarrior(email, encryptionSecret, uuid, taskuuid string) e
1010
if err := utils.ExecCommand("rm", "-rf", "/root/.task"); err != nil {
1111
return fmt.Errorf("error deleting Taskwarrior data: %v", err)
1212
}
13-
tempDir, err := os.MkdirTemp("", "taskwarrior-"+email)
13+
tempDir, err := os.MkdirTemp("", utils.SafeTempDirPrefix("taskwarrior-", email))
1414
if err != nil {
1515
return fmt.Errorf("failed to create temporary directory: %v", err)
1616
}

backend/utils/tw/complete_tasks.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ func CompleteTasksInTaskwarrior(email, encryptionSecret, uuid string, taskUUIDs
1313
return nil, fmt.Errorf("error deleting Taskwarrior data: %v", err)
1414
}
1515

16-
tempDir, err := os.MkdirTemp("", "taskwarrior-"+email)
16+
tempDir, err := os.MkdirTemp("", utils.SafeTempDirPrefix("taskwarrior-", email))
1717

1818
if err != nil {
1919
return nil, fmt.Errorf("failed to create temporary directory: %v", err)

backend/utils/tw/delete_task.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ func DeleteTaskInTaskwarrior(email, encryptionSecret, uuid, taskuuid string) err
1010
if err := utils.ExecCommand("rm", "-rf", "/root/.task"); err != nil {
1111
return fmt.Errorf("error deleting Taskwarrior data: %v", err)
1212
}
13-
tempDir, err := os.MkdirTemp("", "taskwarrior-"+email)
13+
tempDir, err := os.MkdirTemp("", utils.SafeTempDirPrefix("taskwarrior-", email))
1414
if err != nil {
1515
return fmt.Errorf("failed to create temporary directory: %v", err)
1616
}

backend/utils/tw/delete_tasks.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ func DeleteTasksInTaskwarrior(email, encryptionSecret, uuid string, taskUUIDs []
1313
return nil, fmt.Errorf("error deleting Taskwarrior data: %v", err)
1414
}
1515

16-
tempDir, err := os.MkdirTemp("", "taskwarrior-"+email)
16+
tempDir, err := os.MkdirTemp("", utils.SafeTempDirPrefix("taskwarrior-", email))
1717

1818
if err != nil {
1919
return nil, fmt.Errorf("failed to create temporary directory: %v", err)

backend/utils/tw/edit_task.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ func EditTaskInTaskwarrior(uuid, description, email, encryptionSecret, taskID st
1313
if err := utils.ExecCommand("rm", "-rf", "/root/.task"); err != nil {
1414
return fmt.Errorf("error deleting Taskwarrior data: %v", err)
1515
}
16-
tempDir, err := os.MkdirTemp("", "taskwarrior-"+email)
16+
tempDir, err := os.MkdirTemp("", utils.SafeTempDirPrefix("taskwarrior-", email))
1717
if err != nil {
1818
return fmt.Errorf("failed to create temporary directory: %v", err)
1919
}

backend/utils/tw/fetch_tasks.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ func FetchTasksFromTaskwarrior(email, encryptionSecret, origin, UUID string) ([]
1414
return nil, fmt.Errorf("error deleting Taskwarrior data: %v", err)
1515
}
1616

17-
tempDir, err := os.MkdirTemp("", "taskwarrior-"+email)
17+
tempDir, err := os.MkdirTemp("", utils.SafeTempDirPrefix("taskwarrior-", email))
1818
if err != nil {
1919
return nil, fmt.Errorf("failed to create temporary directory: %v", err)
2020
}

backend/utils/tw/modify_task.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ func ModifyTaskInTaskwarrior(uuid, description, project, priority, status, due,
1111
if err := utils.ExecCommand("rm", "-rf", "/root/.task"); err != nil {
1212
return fmt.Errorf("error deleting Taskwarrior data: %v", err)
1313
}
14-
tempDir, err := os.MkdirTemp("", "taskwarrior-"+email)
14+
tempDir, err := os.MkdirTemp("", utils.SafeTempDirPrefix("taskwarrior-", email))
1515
if err != nil {
1616
return fmt.Errorf("failed to create temporary directory: %v", err)
1717
}

0 commit comments

Comments
 (0)