haveibeenpwned
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseHave I Been Pwned API Skill
Have I Been Pwned API 技能
Expert assistance for integrating the Have I Been Pwned (HIBP) API v3 to check for compromised accounts, passwords, and data breaches. This skill provides comprehensive guidance for building security tools, breach notification systems, and password validation features.
为集成 Have I Been Pwned (HIBP) API v3 以检查泄露账户、密码和数据泄露事件提供专业协助。本技能为构建安全工具、泄露通知系统和密码验证功能提供全面指导。
When to Use This Skill
何时使用本技能
This skill should be triggered when:
- Checking if emails/accounts appear in data breaches - "check if this email was pwned"
- Validating password security - "check if password is in breach database"
- Building breach notification systems - "notify users about compromised accounts"
- Implementing password validation - "prevent users from choosing pwned passwords"
- Querying stealer logs - "check if credentials were stolen by malware"
- Integrating HIBP into authentication flows - "add breach checking to login"
- Monitoring domains for compromised emails - "track breaches affecting our domain"
- Working with the HIBP API - any questions about authentication, rate limits, or endpoints
在以下场景下应触发本技能:
- 检查电子邮件/账户是否出现在数据泄露事件中 - "检查这个邮箱是否被泄露"
- 验证密码安全性 - "检查密码是否在泄露数据库中"
- 构建泄露通知系统 - "通知用户其账户已泄露"
- 实现密码验证 - "阻止用户选择已泄露的密码"
- 查询窃取日志 - "检查凭证是否被恶意软件窃取"
- 将 HIBP 集成到认证流程中 - "在登录环节添加泄露检查"
- 监控域名下的泄露邮箱 - "跟踪影响我们域名的泄露事件"
- 使用 HIBP API - 任何关于认证、速率限制或端点的问题
Quick Reference
快速参考
1. Basic Account Breach Check
1. 基础账户泄露检查
python
import requests
def check_account_breaches(email, api_key):
"""Check if an account appears in any breaches"""
headers = {
'hibp-api-key': api_key,
'user-agent': 'MyApp/1.0'
}
url = f'https://haveibeenpwned.com/api/v3/breachedaccount/{email}'
response = requests.get(url, headers=headers)
if response.status_code == 200:
return response.json() # List of breach objects
elif response.status_code == 404:
return [] # Account not found in breaches
else:
response.raise_for_status()python
import requests
def check_account_breaches(email, api_key):
"""Check if an account appears in any breaches"""
headers = {
'hibp-api-key': api_key,
'user-agent': 'MyApp/1.0'
}
url = f'https://haveibeenpwned.com/api/v3/breachedaccount/{email}'
response = requests.get(url, headers=headers)
if response.status_code == 200:
return response.json() # List of breach objects
elif response.status_code == 404:
return [] # Account not found in breaches
else:
response.raise_for_status()Usage
Usage
breaches = check_account_breaches('user@example.com', 'your-api-key')
print(f"Found in {len(breaches)} breaches")
undefinedbreaches = check_account_breaches('user@example.com', 'your-api-key')
print(f"Found in {len(breaches)} breaches")
undefined2. Password Breach Check (k-Anonymity)
2. 密码泄露检查(k-Anonymity 模型)
python
import hashlib
import requests
def check_password_pwned(password):
"""Check if password appears in breaches using k-anonymity"""
# Hash password with SHA-1
sha1_hash = hashlib.sha1(password.encode('utf-8')).hexdigest().upper()
prefix = sha1_hash[:5]
suffix = sha1_hash[5:]
# Query API with first 5 characters only
url = f'https://api.pwnedpasswords.com/range/{prefix}'
response = requests.get(url)
# Parse response for matching suffix
hashes = (line.split(':') for line in response.text.splitlines())
for hash_suffix, count in hashes:
if hash_suffix == suffix:
return int(count) # Times password appears in breaches
return 0 # Password not foundpython
import hashlib
import requests
def check_password_pwned(password):
"""Check if password appears in breaches using k-anonymity"""
# Hash password with SHA-1
sha1_hash = hashlib.sha1(password.encode('utf-8')).hexdigest().upper()
prefix = sha1_hash[:5]
suffix = sha1_hash[5:]
# Query API with first 5 characters only
url = f'https://api.pwnedpasswords.com/range/{prefix}'
response = requests.get(url)
# Parse response for matching suffix
hashes = (line.split(':') for line in response.text.splitlines())
for hash_suffix, count in hashes:
if hash_suffix == suffix:
return int(count) # Times password appears in breaches
return 0 # Password not foundUsage
Usage
count = check_password_pwned('password123')
if count > 0:
print(f"⚠️ Password found {count} times in breaches!")
undefinedcount = check_password_pwned('password123')
if count > 0:
print(f"⚠️ Password found {count} times in breaches!")
undefined3. Get All Breaches in System
3. 获取系统中所有泄露事件
python
import requests
def get_all_breaches(domain=None):
"""Retrieve all breaches, optionally filtered by domain"""
url = 'https://haveibeenpwned.com/api/v3/breaches'
params = {'domain': domain} if domain else {}
headers = {'user-agent': 'MyApp/1.0'}
response = requests.get(url, headers=headers, params=params)
return response.json()python
import requests
def get_all_breaches(domain=None):
"""Retrieve all breaches, optionally filtered by domain"""
url = 'https://haveibeenpwned.com/api/v3/breaches'
params = {'domain': domain} if domain else {}
headers = {'user-agent': 'MyApp/1.0'}
response = requests.get(url, headers=headers, params=params)
return response.json()Usage - no authentication required
Usage - no authentication required
breaches = get_all_breaches()
print(f"Total breaches: {len(breaches)}")
breaches = get_all_breaches()
print(f"Total breaches: {len(breaches)}")
Filter by domain
Filter by domain
adobe_breaches = get_all_breaches(domain='adobe.com')
undefinedadobe_breaches = get_all_breaches(domain='adobe.com')
undefined4. Monitor for New Breaches
4. 监控新泄露事件
python
import requests
import time
def monitor_latest_breach(check_interval=3600):
"""Poll for new breaches every hour"""
last_breach_name = None
while True:
url = 'https://haveibeenpwned.com/api/v3/latestbreach'
headers = {'user-agent': 'MyApp/1.0'}
response = requests.get(url, headers=headers)
if response.status_code == 200:
breach = response.json()
if breach['Name'] != last_breach_name:
print(f"🆕 New breach: {breach['Title']}")
print(f" Accounts affected: {breach['PwnCount']:,}")
last_breach_name = breach['Name']
time.sleep(check_interval)python
import requests
import time
def monitor_latest_breach(check_interval=3600):
"""Poll for new breaches every hour"""
last_breach_name = None
while True:
url = 'https://haveibeenpwned.com/api/v3/latestbreach'
headers = {'user-agent': 'MyApp/1.0'}
response = requests.get(url, headers=headers)
if response.status_code == 200:
breach = response.json()
if breach['Name'] != last_breach_name:
print(f"🆕 New breach: {breach['Title']}")
print(f" Accounts affected: {breach['PwnCount']:,}")
last_breach_name = breach['Name']
time.sleep(check_interval)5. Domain-Wide Breach Search
5. 域名范围泄露搜索
python
import requests
def search_domain_breaches(domain, api_key):
"""Search for all breached emails in a verified domain"""
headers = {
'hibp-api-key': api_key,
'user-agent': 'MyApp/1.0'
}
url = f'https://haveibeenpwned.com/api/v3/breacheddomain/{domain}'
response = requests.get(url, headers=headers)
if response.status_code == 200:
results = response.json()
# Returns: {"alias1": ["Adobe"], "alias2": ["Adobe", "Gawker"]}
total_affected = len(results)
print(f"Found {total_affected} compromised accounts")
return results
else:
response.raise_for_status()python
import requests
def search_domain_breaches(domain, api_key):
"""Search for all breached emails in a verified domain"""
headers = {
'hibp-api-key': api_key,
'user-agent': 'MyApp/1.0'
}
url = f'https://haveibeenpwned.com/api/v3/breacheddomain/{domain}'
response = requests.get(url, headers=headers)
if response.status_code == 200:
results = response.json()
# Returns: {"alias1": ["Adobe"], "alias2": ["Adobe", "Gawker"]}
total_affected = len(results)
print(f"Found {total_affected} compromised accounts")
return results
else:
response.raise_for_status()6. Check Pastes for Account
6. 检查账户相关的粘贴内容
python
import requests
def check_pastes(email, api_key):
"""Check if email appears in any pastes"""
headers = {
'hibp-api-key': api_key,
'user-agent': 'MyApp/1.0'
}
url = f'https://haveibeenpwned.com/api/v3/pasteaccount/{email}'
response = requests.get(url, headers=headers)
if response.status_code == 200:
pastes = response.json()
for paste in pastes:
print(f"{paste['Source']}: {paste['Title']}")
print(f" Date: {paste['Date']}")
print(f" Emails found: {paste['EmailCount']}")
return pastes
elif response.status_code == 404:
return [] # No pastes foundpython
import requests
def check_pastes(email, api_key):
"""Check if email appears in any pastes"""
headers = {
'hibp-api-key': api_key,
'user-agent': 'MyApp/1.0'
}
url = f'https://haveibeenpwned.com/api/v3/pasteaccount/{email}'
response = requests.get(url, headers=headers)
if response.status_code == 200:
pastes = response.json()
for paste in pastes:
print(f"{paste['Source']}: {paste['Title']}")
print(f" Date: {paste['Date']}")
print(f" Emails found: {paste['EmailCount']}")
return pastes
elif response.status_code == 404:
return [] # No pastes found7. Enhanced Password Check with Padding
7. 带填充的增强型密码检查
python
import hashlib
import requests
def check_password_secure(password):
"""Check password with padding to prevent inference attacks"""
sha1_hash = hashlib.sha1(password.encode('utf-8')).hexdigest().upper()
prefix = sha1_hash[:5]
suffix = sha1_hash[5:]
headers = {'Add-Padding': 'true'}
url = f'https://api.pwnedpasswords.com/range/{prefix}'
response = requests.get(url, headers=headers)
# Parse response, ignore padded entries (count=0)
for line in response.text.splitlines():
hash_suffix, count = line.split(':')
if hash_suffix == suffix and int(count) > 0:
return int(count)
return 0python
import hashlib
import requests
def check_password_secure(password):
"""Check password with padding to prevent inference attacks"""
sha1_hash = hashlib.sha1(password.encode('utf-8')).hexdigest().upper()
prefix = sha1_hash[:5]
suffix = sha1_hash[5:]
headers = {'Add-Padding': 'true'}
url = f'https://api.pwnedpasswords.com/range/{prefix}'
response = requests.get(url, headers=headers)
# Parse response, ignore padded entries (count=0)
for line in response.text.splitlines():
hash_suffix, count = line.split(':')
if hash_suffix == suffix and int(count) > 0:
return int(count)
return 08. Handle Rate Limiting
8. 处理速率限制
python
import requests
import time
def api_call_with_retry(url, headers, max_retries=3):
"""Make API call with automatic retry on rate limit"""
for attempt in range(max_retries):
response = requests.get(url, headers=headers)
if response.status_code == 429:
# Rate limited - wait and retry
retry_after = int(response.headers.get('retry-after', 2))
print(f"Rate limited, waiting {retry_after}s...")
time.sleep(retry_after)
continue
return response
raise Exception("Max retries exceeded")python
import requests
import time
def api_call_with_retry(url, headers, max_retries=3):
"""Make API call with automatic retry on rate limit"""
for attempt in range(max_retries):
response = requests.get(url, headers=headers)
if response.status_code == 429:
# Rate limited - wait and retry
retry_after = int(response.headers.get('retry-after', 2))
print(f"Rate limited, waiting {retry_after}s...")
time.sleep(retry_after)
continue
return response
raise Exception("Max retries exceeded")9. Check Subscription Status
9. 检查订阅状态
python
import requests
def get_subscription_info(api_key):
"""Retrieve API subscription details and limits"""
headers = {
'hibp-api-key': api_key,
'user-agent': 'MyApp/1.0'
}
url = 'https://haveibeenpwned.com/api/v3/subscription/status'
response = requests.get(url, headers=headers)
if response.status_code == 200:
info = response.json()
print(f"Plan: {info['SubscriptionName']}")
print(f"Rate limit: {info['Rpm']} requests/minute")
print(f"Valid until: {info['SubscribedUntil']}")
return infopython
import requests
def get_subscription_info(api_key):
"""Retrieve API subscription details and limits"""
headers = {
'hibp-api-key': api_key,
'user-agent': 'MyApp/1.0'
}
url = 'https://haveibeenpwned.com/api/v3/subscription/status'
response = requests.get(url, headers=headers)
if response.status_code == 200:
info = response.json()
print(f"Plan: {info['SubscriptionName']}")
print(f"Rate limit: {info['Rpm']} requests/minute")
print(f"Valid until: {info['SubscribedUntil']}")
return info10. Stealer Logs Search
10. 窃取日志搜索
python
import requests
def check_stealer_logs(email, api_key):
"""Check if credentials appear in info stealer malware logs"""
headers = {
'hibp-api-key': api_key,
'user-agent': 'MyApp/1.0'
}
url = f'https://haveibeenpwned.com/api/v3/stealerlogsbyemail/{email}'
response = requests.get(url, headers=headers)
if response.status_code == 200:
domains = response.json() # List of website domains
print(f"Credentials found for {len(domains)} websites")
return domains
elif response.status_code == 404:
return [] # Not found in stealer logspython
import requests
def check_stealer_logs(email, api_key):
"""Check if credentials appear in info stealer malware logs"""
headers = {
'hibp-api-key': api_key,
'user-agent': 'MyApp/1.0'
}
url = f'https://haveibeenpwned.com/api/v3/stealerlogsbyemail/{email}'
response = requests.get(url, headers=headers)
if response.status_code == 200:
domains = response.json() # List of website domains
print(f"Credentials found for {len(domains)} websites")
return domains
elif response.status_code == 404:
return [] # Not found in stealer logsRequires Pwned 5+ subscription
Requires Pwned 5+ subscription
undefinedundefinedKey Concepts
核心概念
Authentication
认证
- API Key Format: 32-character hexadecimal string
- Header:
hibp-api-key: {your-key} - User-Agent Required: Must set valid user-agent header (returns 403 if missing)
- Test Key: for integration testing
00000000000000000000000000000000
- API Key 格式:32位十六进制字符串
- 请求头:
hibp-api-key: {your-key} - 必须设置 User-Agent:必须设置有效的User-Agent请求头(缺失时返回403)
- 测试密钥:用于集成测试
00000000000000000000000000000000
k-Anonymity Model
k-Anonymity 模型
The Pwned Passwords API uses k-anonymity to protect user privacy:
- Client hashes password locally with SHA-1
- Sends only first 5 characters of hash to API
- API returns ~800 matching hash suffixes
- Client checks locally if full hash matches
This ensures the actual password never leaves your system.
Pwned Passwords API 使用 k-Anonymity 模型保护用户隐私:
- 客户端在本地使用SHA-1对密码进行哈希
- 仅将哈希值的前5个字符发送至API
- API返回约800个匹配的哈希后缀
- 客户端在本地检查完整哈希是否匹配
这确保实际密码永远不会离开你的系统。
Rate Limiting
速率限制
- Varies by subscription tier: Pwned 5 = 1,000 requests/minute
- HTTP 429 response when exceeded with header
retry-after - Pwned Passwords API: No rate limit
- Best practice: Implement exponential backoff on 429 responses
- 因订阅层级而异:Pwned 5 层级为1000次请求/分钟
- 超出限制时返回HTTP 429响应,并附带请求头
retry-after - Pwned Passwords API:无速率限制
- 最佳实践:在收到429响应时实现指数退避重试
Breach Model Attributes
泄露模型属性
Key fields in breach objects:
- Name: Unique identifier (e.g., "Adobe")
- Title: Human-readable name
- BreachDate: When breach occurred (ISO 8601)
- PwnCount: Total compromised accounts
- DataClasses: Types of data exposed (emails, passwords, etc.)
- IsVerified: Breach authenticity confirmed
- IsSensitive: Excluded from public searches
泄露对象中的关键字段:
- Name:唯一标识符(例如 "Adobe")
- Title:人类可读名称
- BreachDate:泄露事件发生日期(ISO 8601格式)
- PwnCount:受影响的账户总数
- DataClasses:泄露的数据类型(电子邮件、密码等)
- IsVerified:泄露事件真实性已确认
- IsSensitive:排除在公开搜索之外
Response Codes
响应码
| Code | Meaning |
|---|---|
| 200 | Success - data found |
| 404 | Not found (account not in breaches) |
| 401 | Unauthorized (invalid API key) |
| 403 | Forbidden (missing user-agent) |
| 429 | Rate limit exceeded |
| 代码 | 含义 |
|---|---|
| 200 | 请求成功 - 找到数据 |
| 404 | 未找到(账户未出现在泄露事件中) |
| 401 | 未授权(无效API密钥) |
| 403 | 禁止访问(缺失User-Agent) |
| 429 | 超出速率限制 |
Reference Files
参考文件
This skill includes comprehensive API documentation in :
references/- other.md - Complete HIBP API v3 reference with all endpoints, authentication, and usage examples
The reference file contains:
- All API endpoints - Breaches, pastes, passwords, stealer logs
- Request/response formats - Headers, parameters, JSON structures
- Authentication details - API key setup and usage
- Rate limiting information - Subscription tiers and retry strategies
- Test accounts - Pre-configured test data for integration
- Code examples - Real-world implementation patterns
Use to read the reference file when you need detailed information about specific endpoints or advanced features.
view本技能在目录中包含全面的API文档:
references/- other.md - 完整的HIBP API v3参考,包含所有端点、认证和使用示例
参考文件包含:
- 所有API端点 - 泄露事件、粘贴内容、密码、窃取日志
- 请求/响应格式 - 请求头、参数、JSON结构
- 认证详情 - API密钥的设置与使用
- 速率限制信息 - 订阅层级和重试策略
- 测试账户 - 预配置的测试数据用于集成
- 代码示例 - 真实场景的实现模式
当你需要了解特定端点或高级功能的详细信息时,使用命令查看参考文件。
viewWorking with This Skill
使用本技能的指南
For Beginners
面向初学者
Start by understanding the core concepts:
- Password checking - Use Pwned Passwords API (no authentication required)
- Account breaches - Requires API key from haveibeenpwned.com
- k-Anonymity - Learn how password hashing protects privacy
Begin with Quick Reference examples #1 (breach check) and #2 (password check).
从理解核心概念开始:
- 密码检查 - 使用Pwned Passwords API(无需认证)
- 账户泄露检查 - 需要从haveibeenpwned.com获取API密钥
- k-Anonymity - 了解密码哈希如何保护隐私
从快速参考中的示例#1(泄露检查)和#2(密码检查)开始。
For Integration Projects
面向集成项目
Focus on:
- Authentication setup - Get API key and configure headers
- Rate limiting - Implement retry logic (example #8)
- Error handling - Handle 404, 401, 429 responses properly
- User experience - Provide clear messaging about breach exposure
Review Quick Reference examples #5 (domain search) and #9 (subscription info).
重点关注:
- 认证设置 - 获取API密钥并配置请求头
- 速率限制 - 实现重试逻辑(示例#8)
- 错误处理 - 正确处理404、401、429响应
- 用户体验 - 提供清晰的泄露暴露提示信息
查看快速参考中的示例#5(域名搜索)和#9(订阅信息)。
For Production Systems
面向生产系统
Consider:
- Caching - Store breach results to reduce API calls
- Background processing - Check breaches asynchronously
- Monitoring - Track new breaches with latest breach endpoint (example #4)
- Privacy - Never log passwords, use k-anonymity model
- Compliance - Follow attribution requirements (CC BY 4.0)
考虑以下事项:
- 缓存 - 存储泄露结果以减少API调用
- 后台处理 - 异步检查泄露事件
- 监控 - 使用最新泄露端点跟踪新泄露事件(示例#4)
- 隐私保护 - 绝不记录密码,使用k-Anonymity模型
- 合规性 - 遵循归属要求(CC BY 4.0)
For Security Tools
面向安全工具
Advanced patterns:
- Stealer logs - Check malware-stolen credentials (example #10)
- Domain monitoring - Track all compromised accounts in your organization
- Paste monitoring - Alert on email exposure in public pastes (example #6)
- Padding - Use response padding to prevent inference attacks (example #7)
高级模式:
- 窃取日志 - 检查被恶意软件窃取的凭证(示例#10)
- 域名监控 - 跟踪组织内所有受影响的账户
- 粘贴内容监控 - 当邮箱在公开粘贴内容中暴露时发出警报(示例#6)
- 填充机制 - 使用响应填充防止推理攻击(示例#7)
Common Patterns
常见模式
Pattern 1: Sign-up Password Validation
模式1:注册密码验证
python
undefinedpython
undefinedPrevent users from choosing compromised passwords
阻止用户选择已泄露的密码
def validate_signup_password(password):
count = check_password_pwned(password)
if count > 0:
return False, f"This password appears in {count} data breaches"
return True, "Password is secure"
undefineddef validate_signup_password(password):
count = check_password_pwned(password)
if count > 0:
return False, f"This password appears in {count} data breaches"
return True, "Password is secure"
undefinedPattern 2: Breach Notification System
模式2:泄露通知系统
python
undefinedpython
undefinedNotify users when their account appears in new breach
当用户账户出现在新泄露事件中时通知用户
def notify_affected_users():
latest = get_latest_breach()
affected_users = query_users_in_breach(latest['Name'])
for user in affected_users:
send_notification(user, latest)
undefineddef notify_affected_users():
latest = get_latest_breach()
affected_users = query_users_in_breach(latest['Name'])
for user in affected_users:
send_notification(user, latest)
undefinedPattern 3: Compliance Check
模式3:合规性检查
python
undefinedpython
undefinedVerify all domain accounts for compliance reporting
验证域名下所有账户以用于合规报告
def domain_security_audit(domain, api_key):
breached = search_domain_breaches(domain, api_key)
report = {
'total_accounts': len(breached),
'affected_accounts': breached,
'timestamp': datetime.now()
}
return report
undefineddef domain_security_audit(domain, api_key):
breached = search_domain_breaches(domain, api_key)
report = {
'total_accounts': len(breached),
'affected_accounts': breached,
'timestamp': datetime.now()
}
return report
undefinedAPI Endpoints Summary
API端点汇总
Authenticated Endpoints (Require API Key)
需要认证的端点(需API密钥)
- - Check account breaches
GET /breachedaccount/{account} - - Check pastes
GET /pasteaccount/{account} - - Domain-wide search
GET /breacheddomain/{domain} - - List verified domains
GET /subscribeddomains - - Check subscription
GET /subscription/status - - Stealer logs by email
GET /stealerlogsbyemail/{email} - - Stealer logs by site
GET /stealerlogsbywebsitedomain/{domain} - - Stealer logs by email domain
GET /stealerlogsbyemaildomain/{domain}
- - 检查账户泄露情况
GET /breachedaccount/{account} - - 检查粘贴内容
GET /pasteaccount/{account} - - 域名范围搜索
GET /breacheddomain/{domain} - - 列出已验证的域名
GET /subscribeddomains - - 检查订阅状态
GET /subscription/status - - 按邮箱查询窃取日志
GET /stealerlogsbyemail/{email} - - 按网站域名查询窃取日志
GET /stealerlogsbywebsitedomain/{domain} - - 按邮箱域名查询窃取日志
GET /stealerlogsbyemaildomain/{domain}
Public Endpoints (No Authentication)
公开端点(无需认证)
- - All breaches in system
GET /breaches - - Single breach details
GET /breach/{name} - - Most recent breach
GET /latestbreach - - List of data types
GET /dataclasses - - Password check
GET https://api.pwnedpasswords.com/range/{prefix}
- - 系统中所有泄露事件
GET /breaches - - 单个泄露事件详情
GET /breach/{name} - - 最新泄露事件
GET /latestbreach - - 数据类型列表
GET /dataclasses - - 密码检查
GET https://api.pwnedpasswords.com/range/{prefix}
Testing
测试
Test Accounts
测试账户
Use these on domain :
hibp-integration-tests.com- - Has breaches and pastes
account-exists@ - - Three different breaches
multiple-breaches@ - - Only spam-flagged breach
spam-list-only@ - - In stealer logs
stealer-log@ - - No results (opted out)
opt-out@
使用域名下的以下账户:
hibp-integration-tests.com- - 存在泄露记录和粘贴内容
account-exists@ - - 涉及三次不同的泄露事件
multiple-breaches@ - - 仅存在于垃圾邮件列表泄露中
spam-list-only@ - - 出现在窃取日志中
stealer-log@ - - 无结果(已选择退出)
opt-out@
Test API Key
测试API密钥
Use for integration testing.
00000000000000000000000000000000使用进行集成测试。
00000000000000000000000000000000Best Practices
最佳实践
- Always set User-Agent - Required header, returns 403 without it
- Use HTTPS only - API requires TLS 1.2+
- Implement retry logic - Handle 429 rate limits gracefully
- Cache breach data - Reduce API calls for frequently checked accounts
- Never log passwords - Use k-anonymity model, hash locally
- Provide attribution - Link to haveibeenpwned.com (CC BY 4.0 license)
- Handle 404 gracefully - "Not found" is good news for users
- Use padding for passwords - Add header
Add-Padding: true
- 始终设置User-Agent - 必填请求头,缺失时返回403
- 仅使用HTTPS - API要求TLS 1.2+
- 实现重试逻辑 - 优雅处理429速率限制
- 缓存泄露数据 - 减少频繁检查账户的API调用
- 绝不记录密码 - 使用k-Anonymity模型,在本地进行哈希
- 提供归属链接 - 链接至haveibeenpwned.com(CC BY 4.0许可证)
- 优雅处理404响应 - "未找到"对用户来说是好消息
- 为密码检查使用填充 - 添加请求头
Add-Padding: true
Resources
资源
Official Links
官方链接
- API Documentation: https://haveibeenpwned.com/API/v3
- Get API Key: https://haveibeenpwned.com/API/Key
- Dashboard: https://haveibeenpwned.com/DomainSearch
Community Tools
社区工具
- PwnedPasswordsDownloader (GitHub) - Download full password database
- Integration libraries available for Python, JavaScript, Go, C#, and more
- PwnedPasswordsDownloader(GitHub) - 下载完整密码数据库
- 提供Python、JavaScript、Go、C#等多种语言的集成库
Acceptable Use
可接受的使用场景
Permitted:
- Security tools and breach notifications
- Password validation in authentication systems
- Compliance and security audits
- Educational and research purposes
Prohibited:
- Targeting or harming breach victims
- Denial-of-service attacks
- Circumventing security measures
- Misrepresenting data source
- Automating undocumented APIs
Violations may result in API key revocation or IP blocking.
允许的场景:
- 安全工具和泄露通知
- 认证系统中的密码验证
- 合规性和安全审计
- 教育和研究用途
禁止的场景:
- 针对或伤害泄露事件受害者
- 拒绝服务攻击
- 规避安全措施
- 歪曲数据源
- 自动化未公开的API
违规可能导致API密钥被吊销或IP被封禁。
Notes
注意事项
- Breach data licensed under Creative Commons Attribution 4.0
- Pwned Passwords has no licensing requirements
- CORS only supported for unauthenticated endpoints
- Never expose API keys in client-side code
- Service tracks 917+ breaches as of API documentation date
- 泄露数据采用知识共享署名4.0许可证
- Pwned Passwords无许可证要求
- 仅未认证端点支持CORS
- 绝不在客户端代码中暴露API密钥
- 截至API文档发布时,服务已跟踪917+起泄露事件