fix: harden evidence URI validation
This commit is contained in:
@@ -276,6 +276,7 @@ function isSafeEvidencePattern(value: string): boolean {
|
||||
}
|
||||
|
||||
function parsePublicHttpUri(value: string): URL | undefined {
|
||||
if (value.trim() !== value || /[\u0000-\u001f\u007f\\]/u.test(value)) return undefined;
|
||||
try {
|
||||
const parsed = new URL(value);
|
||||
if (
|
||||
@@ -297,14 +298,20 @@ function canonicalPublicHttpUri(value: string): string | undefined {
|
||||
}
|
||||
|
||||
function isSafeS3Uri(value: string): boolean {
|
||||
if (value.trim() !== value || /[\u0000-\u001f\u007f\\]/u.test(value)) return false;
|
||||
try {
|
||||
const parsed = new URL(value);
|
||||
const bucket = parsed.hostname;
|
||||
const validBucket = /^(?=.{3,63}$)(?!-)(?!.*\.\.)(?!.*\.-)(?!.*-\.)[a-z0-9](?:[a-z0-9.-]*[a-z0-9])?$/.test(bucket)
|
||||
&& !/^\d{1,3}(?:\.\d{1,3}){3}$/.test(bucket);
|
||||
return parsed.protocol === "s3:"
|
||||
&& parsed.hostname.length > 0
|
||||
&& validBucket
|
||||
&& parsed.port === ""
|
||||
&& parsed.username === ""
|
||||
&& parsed.password === ""
|
||||
&& parsed.search === ""
|
||||
&& parsed.hash === "";
|
||||
&& parsed.hash === ""
|
||||
&& parsed.href === value;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
@@ -380,7 +387,8 @@ const s3EvidenceSourceSchema = z.object({
|
||||
message: "custom S3 endpoints must be explicitly trusted",
|
||||
});
|
||||
}
|
||||
if (source.endpoint_url.startsWith("http:") && !source.allow_insecure_endpoint) {
|
||||
const endpoint = parsePublicHttpUri(source.endpoint_url);
|
||||
if (endpoint?.protocol === "http:" && !source.allow_insecure_endpoint) {
|
||||
context.addIssue({
|
||||
code: "custom", path: ["allow_insecure_endpoint"],
|
||||
message: "HTTP S3 endpoints require an explicit insecure opt-in",
|
||||
|
||||
Reference in New Issue
Block a user