Skip to content

Commit 1e985f4

Browse files
committed
target: validate app names in target URIs and skip invalid targets
Ensure the app name declared in target metadata matches the app name embedded in each app URI when loading plain and TUF repositories. Changes: validate URI parsing for each app entry and log detailed errors verify target app name matches URI app name use the configured target app name when building App entries skip the entire target if any app entry is invalid continue loading other targets from the same targets file This prevents loading misconfigured targets and avoids relying on incorrect app names derived from malformed or mismatched URIs. Signed-off-by: Mike Sul <mike.sul@foundries.io>
1 parent 051d386 commit 1e985f4

2 files changed

Lines changed: 76 additions & 19 deletions

File tree

pkg/target/plain_repo.go

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -104,22 +104,51 @@ func (r *plainRepo) loadTargets(targetsData []byte) error {
104104
continue
105105
}
106106
var apps []App
107-
for _, appField := range targetValue.Custom.Apps {
107+
isValidTarget := true
108+
for appName, appField := range targetValue.Custom.Apps {
108109
appRef, err := compose.ParseAppRef(appField.URI)
109110
if err != nil {
110-
slog.Debug("target with invalid app URI is found", "target custom", targetValue.Custom)
111-
continue
111+
slog.Error(
112+
"failed to parse app URI in target",
113+
"target", targetName,
114+
"app", appName,
115+
"uri", appField.URI,
116+
"error", err,
117+
)
118+
isValidTarget = false
119+
// This is an invalid target, continue processing other targets instead of
120+
// returning an error since the target file may contain multiple targets and some of them may be valid.
121+
break
122+
}
123+
// The app name embedded in the URI must match the app name declared
124+
// in the target configuration. A mismatch indicates a misconfigured
125+
// target. This validation is required because composectl derives the
126+
// app name from the URI passed through its CLI or API.
127+
if appRef.Name != appName {
128+
slog.Error(
129+
"app name mismatch between target and URI",
130+
"target", targetName,
131+
"target_app", appName,
132+
"uri_app", appRef.Name,
133+
"uri", appField.URI,
134+
)
135+
isValidTarget = false
136+
// This is an invalid target, continue processing other targets instead of
137+
// returning an error since the target file may contain multiple targets and some of them may be valid.
138+
break
112139
}
113140
apps = append(apps, App{
114-
Name: appRef.Name,
141+
Name: appName,
115142
URI: appField.URI,
116143
})
117144
}
118-
r.targets = append(r.targets, Target{
119-
ID: targetName,
120-
Version: version,
121-
Apps: apps,
122-
})
145+
if isValidTarget {
146+
r.targets = append(r.targets, Target{
147+
ID: targetName,
148+
Version: version,
149+
Apps: apps,
150+
})
151+
}
123152
}
124153
r.version = targetsFile.Signed.Version
125154
return nil

pkg/target/tuf_repo.go

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -93,23 +93,51 @@ func (r *tufRepo) loadTargets() error {
9393
}
9494

9595
var apps []App
96-
for _, appField := range targetDetails.Apps {
96+
isValidTarget := true
97+
for appName, appField := range targetDetails.Apps {
9798
appRef, err := compose.ParseAppRef(appField.URI)
9899
if err != nil {
99-
slog.Debug("target with invalid app URI is found", "target custom", targetDetails)
100-
continue
100+
slog.Error(
101+
"failed to parse app URI in target",
102+
"target", id,
103+
"app", appName,
104+
"uri", appField.URI,
105+
"error", err,
106+
)
107+
isValidTarget = false
108+
// This is an invalid target, continue processing other targets instead of
109+
// returning an error since the target file may contain multiple targets and some of them may be valid.
110+
break
111+
}
112+
// The app name embedded in the URI must match the app name declared
113+
// in the target configuration. A mismatch indicates a misconfigured
114+
// target. This validation is required because composectl derives the
115+
// app name from the URI passed through its CLI or API.
116+
if appRef.Name != appName {
117+
slog.Error(
118+
"app name mismatch between target and URI",
119+
"target", id,
120+
"target_app", appName,
121+
"uri_app", appRef.Name,
122+
"uri", appField.URI,
123+
)
124+
isValidTarget = false
125+
// This is an invalid target, continue processing other targets instead of
126+
// returning an error since the target file may contain multiple targets and some of them may be valid.
127+
break
101128
}
102129
apps = append(apps, App{
103-
Name: appRef.Name,
130+
Name: appName,
104131
URI: appField.URI,
105132
})
106133
}
107-
108-
r.targets = append(r.targets, Target{
109-
ID: id,
110-
Version: version,
111-
Apps: apps,
112-
})
134+
if isValidTarget {
135+
r.targets = append(r.targets, Target{
136+
ID: id,
137+
Version: version,
138+
Apps: apps,
139+
})
140+
}
113141
}
114142
return nil
115143
}

0 commit comments

Comments
 (0)