aboutsummaryrefslogtreecommitdiffstats
path: root/internal/notify/service.go
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-09-15 18:01:49 +0200
committerDanilo M. <danix@danix.xyz>2026-09-15 18:01:49 +0200
commit7a6b1c1ada3ba6ca2ca4ed70cf51f2f5f30d7b1e (patch)
tree6b0e0ffd76f0de162093a56d1799847a8b81ade5 /internal/notify/service.go
parent3b8a0e0f4a5c28394ac578e8559bf57ae82d3fd2 (diff)
downloadnotifyd-7a6b1c1ada3ba6ca2ca4ed70cf51f2f5f30d7b1e.tar.gz
notifyd-7a6b1c1ada3ba6ca2ca4ed70cf51f2f5f30d7b1e.zip
fix(notify): cover expiry cleanup and harden the image-removal guard
Split the dismiss test so expiry is exercised on its own: Expire removes the image without deleting the inert entry, and nothing asserted it. removeImage now requires filepath.Dir(filepath.Clean(path)) to equal the image directory, so a path carrying .. cannot reach a sibling daemon file such as queue.json. The previous prefix test accepted it. Not exploitable until Task 4 populates Popup.Image from a client hint, which is exactly why the guard is fixed now.
Diffstat (limited to 'internal/notify/service.go')
-rw-r--r--internal/notify/service.go7
1 files changed, 4 insertions, 3 deletions
diff --git a/internal/notify/service.go b/internal/notify/service.go
index d46293f..2442127 100644
--- a/internal/notify/service.go
+++ b/internal/notify/service.go
@@ -14,7 +14,7 @@ package notify
import (
"log"
"os"
- "strings"
+ "path/filepath"
"sync"
"time"
@@ -52,12 +52,13 @@ func NewService(conn *dbus.Conn, dir string) *Service {
}
// removeImage unlinks only what the daemon wrote, so a client's own image-path
-// is never touched.
+// is never touched. A cleaned path must sit directly inside the image
+// directory, which also refuses a `..` traversal to a sibling daemon file.
func (s *Service) removeImage(path string) {
if path == "" {
return
}
- if !strings.HasPrefix(path, ImagesDir(s.dir)+string(os.PathSeparator)) {
+ if filepath.Dir(filepath.Clean(path)) != ImagesDir(s.dir) {
return
}
os.Remove(path)