Input Validation & Sanitization
Implemented Controls
SSRF Prevention
lib/git_gud/outbound_url.ex — Comprehensive outbound URL validation
Blocks the following categories of URLs when making outbound HTTP requests:
- Loopback addresses:
127.0.0.0/8,::1,localhost - Link-local:
169.254.0.0/16 - Private ranges: RFC 1918 (
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16) - Cloud metadata:
169.254.169.254(AWS, GCP, Azure metadata endpoints) - IPv6 unique-local:
fc00::/7 - IPv6 multicast:
ff00::/8 - IPv6 reserved:
::/128,::1/128 - IPv4-mapped IPv6:
::ffff:0:0/96 - CGNAT:
100.64.0.0/10
DNS rebinding protection included — resolves hostnames and validates resolved IP addresses.
Size Limits
| Endpoint | Limit | File/Line |
|---|---|---|
| Pre-receive hooks | 1MB | PreReceiveController |
| Package uploads | 200MB | PackageRegistryController |
| Hook requests | 1MB body | HookController |
| Runner proto | 50MB | runner_controller.ex:700 |
| Artifact uploads | 1GB | actions_artifact_controller.ex:76 |
| Cache chunk upload | 200MB | actions_cache_controller.ex:91 |
Data Validation
- Ecto changesets — all schema writes use
validate_required,validate_inclusion,unique_constraint - SHA validation — pre-receive hooks validate 40-character hex SHA format
- Ref format parsing — git ref updates validated against expected format
- Token format validation — personal access tokens, runner tokens validated on use
HTML/Markdown Sanitization
lib/git_gud/markdown.ex— HTML sanitization before rendering user-generated content- Processes markdown input through sanitization pipeline
- Strips dangerous elements (scripts, event handlers, javascript: URIs)
- Uses
Flokiorex_html_saxfor DOM manipulation - Allows safe subset of HTML (bold, italic, links, code blocks, etc.)
Security Observations
Medium
Markdown sanitization rules need periodic review
- Sanitization configuration should be verified against latest OWASP XSS cheatsheet
- New XSS vectors discovered regularly — ensure sanitization is current
- Recommendation: add test cases for known XSS payloads (e.g.,
<svg/onload=alert(1)>,<iframe src=javascript:...>)
Size limits can cause memory exhaustion
actions_artifact_controller.ex:76—read_body/2withlength: 1_000_000_000(1 GB)- If multiple concurrent artifact uploads hit the limit, memory exhaustion is possible
- Recommendation: add per-user or per-repo concurrent upload limits
actions_cache_controller.ex:91— 200MB per chunk upload- Consider chunking or streaming for very large caches
No file type validation in storage controller
StorageControllerrelies on upstream validation for file types- No virus/malware scanning pipeline
- Recommendation: add content-type validation based on actual file content (magic bytes) not just headers
- Consider adding malware scanning (e.g., ClamAV integration) for uploaded artifacts
No rate limiting on login/register endpoints
- Only MFA attempts tracked via
TwoFactorAttempts - Login/register endpoints can be hammered for brute-force or credential stuffing
- Recommendation: add IP-based rate limiting (e.g., 10 requests/minute per IP for login)
- Recommendation: add CAPTCHA or proof-of-work after N failed attempts