Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/s3/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
secretAccessKey: config.secretKey,
},
endpoint: config.endpoint,
forcePathStyle: !config.endpoint.includes('amazonaws.com'),

Check failure

Code scanning / CodeQL

Incomplete URL substring sanitization High

'
amazonaws.com
' can be anywhere in the URL, and arbitrary hosts may come before or after it.

Copilot Autofix

AI 6 days ago

In general, the problem is that the code checks whether the string "amazonaws.com" appears anywhere in config.endpoint, instead of reliably determining whether the endpoint really belongs to AWS. To fix this, we should parse the endpoint as a URL, extract its hostname, normalize it, and then compare it against a whitelist pattern, such as “is the hostname exactly amazonaws.com or ends with .amazonaws.com”. For plain hostnames without scheme, we can normalize by prepending https:// before parsing.

The best minimal fix here is to replace the .includes('amazonaws.com') call with a small helper that safely determines whether an endpoint is an AWS S3 endpoint. That helper can (1) accept the endpoint string, (2) ensure it has a scheme (prepend https:// if missing), (3) use the standard URL class to parse it, (4) extract hostname, and (5) return true only if the hostname is amazonaws.com or ends with .amazonaws.com. We then compute a boolean (e.g. isAwsEndpoint) and set forcePathStyle based on its negation as before, preserving behavior for genuine AWS endpoints but avoiding substring‑based misclassification for arbitrary URLs. This change can be implemented entirely inside packages/s3/src/index.ts without new external dependencies, using the built‑in URL global.

Concretely:

  • Add a small helper function (e.g. isAwsEndpoint) above createS3Service, within the same file.
  • In that helper, normalize and parse the endpoint string and perform host comparison as described.
  • In createS3Service, replace forcePathStyle: !config.endpoint.includes('amazonaws.com') with forcePathStyle: !isAwsEndpoint(config.endpoint).
Suggested changeset 1
packages/s3/src/index.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/packages/s3/src/index.ts b/packages/s3/src/index.ts
--- a/packages/s3/src/index.ts
+++ b/packages/s3/src/index.ts
@@ -58,6 +58,28 @@
   return path.replaceAll(/\/+/g, '/');
 };
 
+const isAwsEndpoint = (endpoint: string): boolean => {
+  if (!endpoint) {
+    return false;
+  }
+
+  let urlString = endpoint;
+  if (!/^[a-zA-Z][a-zA-Z0-9+\-.]*:/.test(urlString)) {
+    urlString = `https://${urlString}`;
+  }
+
+  try {
+    const url = new URL(urlString);
+    const hostname = url.hostname.toLowerCase();
+    return (
+      hostname === 'amazonaws.com' ||
+      hostname.endsWith('.amazonaws.com')
+    );
+  } catch {
+    return false;
+  }
+};
+
 export const createS3Service = (config: S3Config): S3Service => {
   const s3 = new S3Client({
     credentials: {
@@ -65,7 +87,7 @@
       secretAccessKey: config.secretKey,
     },
     endpoint: config.endpoint,
-    forcePathStyle: !config.endpoint.includes('amazonaws.com'),
+    forcePathStyle: !isAwsEndpoint(config.endpoint),
     region: config.region,
   });
 
EOF
@@ -58,6 +58,28 @@
return path.replaceAll(/\/+/g, '/');
};

const isAwsEndpoint = (endpoint: string): boolean => {
if (!endpoint) {
return false;
}

let urlString = endpoint;
if (!/^[a-zA-Z][a-zA-Z0-9+\-.]*:/.test(urlString)) {
urlString = `https://${urlString}`;
}

try {
const url = new URL(urlString);
const hostname = url.hostname.toLowerCase();
return (
hostname === 'amazonaws.com' ||
hostname.endsWith('.amazonaws.com')
);
} catch {
return false;
}
};

export const createS3Service = (config: S3Config): S3Service => {
const s3 = new S3Client({
credentials: {
@@ -65,7 +87,7 @@
secretAccessKey: config.secretKey,
},
endpoint: config.endpoint,
forcePathStyle: !config.endpoint.includes('amazonaws.com'),
forcePathStyle: !isAwsEndpoint(config.endpoint),
region: config.region,
});

Copilot is powered by AI and may make mistakes. Always verify output.
region: config.region,
});

Expand Down
Loading
Loading