You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(s3): region-aware scanning + full S3 URL input (fixes enum-only on non-us-east-1)
Passing a bucket + region (e.g. ap-south-1) only enumerated and never probed
permissions: the probe and list-object URLs only built the global host
(bucket.s3.amazonaws.com, which 301-redirects for buckets outside us-east-1) and
the legacy dash host (bucket.s3-region.amazonaws.com). Modern regions are served
at the DOT host bucket.s3.<region>.amazonaws.com, so every list/read/write/delete
probe read false and the scan degraded to enumeration only.
- ParseBucketInput: accept a full S3 URL in the bucket field — virtual-hosted
dot/dash, path-style, dualstack, with/without scheme/port — and extract the
bucket name + region. Wired into the API handler (clean scan title) and handleScan.
- bucketListURLs: emit modern dot-style regional endpoints (+ legacy dash + path
style) so probing reaches buckets in any region. Used by handleScan and the
domain enum+scan path.
- detectBucketRegion: read x-amz-bucket-region (returned even on unauth 301/403),
so an empty region auto-resolves from the bucket itself — the launcher's
"leave empty to auto-detect" hint is now real. probeBucketPermissions self-heals
the region when the caller passes none.
- probeBucketPermissions: try the dot-style regional host first (before legacy dash).
- launcher UI: bucket placeholder + region help mention full-URL / auto-detect.
- cleanRegion: treat accelerate/website/dualstack host keywords as non-regions.
- tests: TestParseBucketInput covers 22 forms incl. dot/dash/path/dualstack/
website/accelerate/govcloud and the reported real-world URL.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
dns_takeover: {path: 'dns-takeover',modes: ['domain','domain_list'],placeholders: {domain: 'example.com',domain_list: 'one domain per line'}},
22
22
dns_cf1016: {path: 'dns-cf1016',modes: ['domain','subdomain','domain_list','subdomain_list'],placeholders: {domain: 'example.com',subdomain: 'api.example.com',domain_list: 'one domain per line',subdomain_list: 'one subdomain per line'}},
23
-
s3: {path: 's3',modes: ['bucket','bucket_list','domain','domain_list'],placeholders: {bucket: 'bucket-name',bucket_list: 'one bucket per line',domain: 'example.com',domain_list: 'one domain per line'}},
23
+
s3: {path: 's3',modes: ['bucket','bucket_list','domain','domain_list'],placeholders: {bucket: 'bucket-name or bucket.s3.ap-south-1.amazonaws.com',bucket_list: 'one bucket name or s3 URL per line',domain: 'example.com',domain_list: 'one domain per line'}},
24
24
github: {path: 'github',modes: ['repo','repo_list'],placeholders: {repo: 'owner/repository or github.com/owner/repo',repo_list: 'one owner/repo per line'}},
25
25
github_org: {path: 'github_org',modes: ['domain','domain_list'],placeholders: {domain: 'org-name or github.com/org',domain_list: 'one org per line'}},
26
26
zerodays: {path: 'zerodays',modes: ['domain','domain_list'],placeholders: {domain: 'example.com',domain_list: 'one domain per line'}},
{key: 'region',label: 'Region (optional)',type: 'text',advanced: false,help: 'AWS region for the bucket, e.g. us-east-1. Leave empty to auto-detect.'},
63
+
{key: 'region',label: 'Region (optional)',type: 'text',advanced: false,help: 'AWS region, e.g. ap-south-1. Leave empty to auto-detect (parsed from the URL if you paste a full s3 URL, else read from the bucket itself).'},
returnfmt.Errorf("bucket name is required for scan action")
456
451
}
457
452
453
+
// Accept a full S3 URL (bucket.s3.region.amazonaws.com, path-style, with or without
454
+
// scheme) as well as a plain bucket name — extract the bucket and any embedded region.
455
+
ifb, r:=ParseBucketInput(opts.Bucket); b!="" {
456
+
opts.Bucket=b
457
+
ifopts.Region=="" {
458
+
opts.Region=r
459
+
}
460
+
}
461
+
// Auto-detect the region when still unknown. Required for buckets outside us-east-1
462
+
// (e.g. ap-south-1) whose virtual-hosted endpoints differ from the global host; also
463
+
// fulfils the launcher's "leave empty to auto-detect" hint.
464
+
ifopts.Region=="" {
465
+
ifr:=detectBucketRegion(opts.Bucket); r!="" {
466
+
opts.Region=r
467
+
logger.GetLogger().Infof("[INFO] S3 scan: auto-detected region %s for bucket %s", r, opts.Bucket)
468
+
} else {
469
+
logger.GetLogger().Infof("[INFO] S3 scan: could not auto-detect region for %s (bucket may not exist); falling back to multi-region probing", opts.Bucket)
0 commit comments