Shodan has a lesser-known free API endpoint called InternetDB. No API key. No rate limits. One call per IP — returns open ports, hostnames, vulnerabilities, and tags.
It's the fastest way to get Shodan-quality data for free.
The Endpoint
\
https://internetdb.shodan.io/{ip}
\\
That's it. No authentication. No signup.
Quick Example
\`python
import requests
def check_ip(ip):
"""Get Shodan InternetDB data for any IP."""
r = requests.get(f"https://internetdb.shodan.io/{ip}", timeout=10)
if r.status_code == 200:
data = r.json()
print(f"IP: {data.get('ip', ip)}")
print(f"Ports: {data.get('ports', [])}")
print(f"Hostnames: {data.get('hostnames', [])}")
print(f"CPEs: {data.get('cpes', [])[:5]}")
print(f"Vulns: {data.get('vulns', [])[:5]}")
print(f"Tags: {data.get('tags', [])}")
return data
elif r.status_code == 404:
print(f"{ip}: Not found in InternetDB")
return None
Check Cloudflare
check_ip("1.1.1.1")
print()
Check Google DNS
check_ip("8.8.8.8")
`\
Output
\
IP: 1.1.1.1
Ports: [53, 80, 443, 2082, 2083, 2086, 2087, 8443, 8880]
Hostnames: ['one.one.one.one']
CPEs: ['cpe:/a:cloudflare:cloudflare']
Vulns: []
Tags: ['cdn', 'cloud']
\\
Bulk Scanner
Scan an entire subnet in seconds:
\`python
import ipaddress
import concurrent.futures
def scan_subnet(subnet, max_workers=10):
"""Scan an entire subnet using InternetDB."""
network = ipaddress.ip_network(subnet)
results = []
def check(ip):
try:
r = requests.get(f"https://internetdb.shodan.io/{ip}", timeout=5)
if r.status_code == 200:
return r.json()
except:
pass
return None
with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
futures = {executor.submit(check, str(ip)): str(ip) for ip in network.hosts()}
for future in concurrent.futures.as_completed(futures):
result = future.result()
if result and result.get("ports"):
ip = futures[future]
ports = result["ports"]
vulns = result.get("vulns", [])
status = "🔴 VULNS" if vulns else "🟡 Open ports"
print(f"{status} {ip}: ports={ports}")
if vulns:
print(f" CVEs: {', '.join(vulns[:3])}")
results.append(result)
print(f"\nTotal: {len(results)} hosts with open ports out of {network.num_addresses}")
return results
Scan a /28 (16 IPs) — only scan networks you own!
scan_subnet("192.168.1.0/28")
`\
Vulnerability Alert System
\`python
def vuln_check(ips):
"""Check a list of IPs for known vulnerabilities."""
vulnerable = []
for ip in ips:
try:
r = requests.get(f"https://internetdb.shodan.io/{ip}", timeout=5)
if r.status_code == 200:
data = r.json()
vulns = data.get("vulns", [])
if vulns:
vulnerable.append({
"ip": ip,
"vulns": vulns,
"ports": data.get("ports", []),
"hostnames": data.get("hostnames", [])
})
except:
pass
if vulnerable:
print(f"⚠ {len(vulnerable)} IPs have known vulnerabilities:")
for v in vulnerable:
print(f"\n {v['ip']} ({', '.join(v['hostnames'][:2])})")
print(f" Ports: {v['ports']}")
print(f" CVEs: {', '.join(v['vulns'][:5])}")
else:
print("✓ No known vulnerabilities found")
Check your own servers
vuln_check(["1.1.1.1", "8.8.8.8"])
`\
InternetDB vs Regular Shodan API
| Feature | InternetDB | Shodan API |
|---|---|---|
| API key | Not needed | Required |
| Rate limit | None published | 1 req/sec |
| Data per IP | Ports, vulns, tags, CPEs | Full banners, screenshots |
| Search | No (IP only) | Full query language |
| Price | Free | Free tier + $59 paid |
| Best for | Quick IP lookups | Deep research |
InternetDB is Shodan's fast lookup — perfect when you just need to quickly check an IP without full banner data.
What You Can Build
- Asset inventory — map all your public-facing services
- Vulnerability scanner — check your IPs for known CVEs
- DNS enrichment — add port/vuln data to DNS records
- CI/CD security gate — verify your deployed services aren't exposed
- Incident response — quickly profile attacker IPs
Zero setup. Zero cost. Just curl https://internetdb.shodan.io/IP\.
More free security APIs on my GitHub.
Top comments (0)