Skip to content

security: block SSRF to AWS IMDS via missing 169.254.0.0/16 in CanvasHttp blocked_ip_ranges#2636

Open
girishgupta211 wants to merge 2 commits into
instructure:masterfrom
girishgupta211:fix/ssrf-aws-imds-url-upload
Open

security: block SSRF to AWS IMDS via missing 169.254.0.0/16 in CanvasHttp blocked_ip_ranges#2636
girishgupta211 wants to merge 2 commits into
instructure:masterfrom
girishgupta211:fix/ssrf-aws-imds-url-upload

Conversation

@girishgupta211

Copy link
Copy Markdown

Summary

The url parameter on POST /api/v1/users/self/files allows authenticated users to trigger server-side HTTP requests. CanvasHttp.blocked_ip_ranges was missing 169.254.0.0/16 (RFC 3927 link-local), allowing requests to reach the AWS Instance Metadata Service (169.254.169.254) and retrieve IAM credentials.

Affected file: gems/canvas_http/lib/canvas_http.rb

Root cause: blocked_ip_ranges did not include the link-local CIDR block:
```ruby

Before (vulnerable)

@blocked_ip_ranges || [
"127.0.0.1/8",
"10.0.0.0/8",
"172.16.0.0/12",
"192.168.0.0/16",
"fd00::/8"
]

After (fixed)

@blocked_ip_ranges || [
"127.0.0.1/8",
"10.0.0.0/8",
"172.16.0.0/12",
"192.168.0.0/16",
"169.254.0.0/16",
"fd00::/8"
]
```

Impact

Any authenticated user could POST {"url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/<role>"} and retrieve live AWS AccessKeyId, SecretAccessKey, and Token from the EC2 instance running Canvas.

Test plan

  • POST /api/v1/users/self/files with url: "http://169.254.169.254/..." now returns an error instead of fetching metadata
  • Normal file uploads (browser → S3) are unaffected
  • URL-based uploads pointing to public URLs continue to work
  • Existing private IP blocks (10.x, 172.16.x, 192.168.x) still blocked

🤖 Generated with Claude Code

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

The link-local CIDR block (RFC 3927) was missing from blocked_ip_ranges,
allowing authenticated users to exploit the url parameter on
POST /api/v1/users/self/files to reach the AWS Instance Metadata Service
(169.254.169.254) and retrieve IAM credentials via SSRF.
Covers: AWS IMDS (169.254.169.254), link-local range, 10.x/172.16.x/192.168.x,
DNS rebinding (mixed public+private IPs), public S3 passthrough, and
validate_url check_host behaviour for all SSRF scenarios.
@girishgupta211
girishgupta211 force-pushed the fix/ssrf-aws-imds-url-upload branch from 38c0092 to 62be318 Compare May 28, 2026 12:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants