A FastAPI-based service that calculates vendor security risk scores based on breach data from Hudson Rock Cavalier API and lookalike domain detection using dnstwist.
- Breach Data Analysis: Retrieves employee, user, and third-party breach information from Hudson Rock
- Password Strength Assessment: Analyzes password quality distribution (too weak, weak, medium, strong)
- Lookalike Domain Detection: Identifies typosquatting domains using dnstwist
- Risk Scoring: Calculates a 0-10 risk score based on multiple security factors
- Rate Limiting: Built-in rate limiter for Hudson Rock API (50 requests per 10 seconds)
- Docker Support: Fully containerized with Docker and Docker Compose
┌─────────────┐
│ Client │
└──────┬──────┘
│ POST /analyze
▼
┌─────────────────────┐
│ FastAPI Server │
│ (Port 80) │
└──────┬──────────────┘
│
├─► Hudson Rock API (breach data)
│
└─► dnstwist (lookalike domains)
- Docker
- Docker Compose
-
Clone or navigate to the project directory
cd Risker -
Build and start the service
docker-compose up --build
-
Run in background
docker-compose up -d
-
Stop the service
docker-compose down
-
View logs
docker-compose logs -f
POST /analyze
Analyzes a vendor domain and returns comprehensive risk assessment.
{
"domain": "example.com"
}Parameters:
domain(string, required): Domain name or URL to analyze (e.g., "example.com" or "https://example.com")
{
"capture": {
"domain": "example.com",
"breaches": {
"employees": 10,
"users": 250,
"third_parties": 5,
"total": 265
},
"passwords": {
"total": 350,
"weak_pct": 65.5,
"strong_pct": 34.5
},
"last_breach_utc": "2024-11-25T00:00:00+00:00",
"compromised_urls": 100,
"total_stealers": 33000,
"lookalikes": {
"registered": 15,
"with_mx": 3
}
},
"risk": {
"domain": "example.com",
"risk_score": 7.85,
"breaches": {
"employees": 10,
"users": 250,
"third_parties": 5,
"total": 265
},
"weak_password_pct": 65.5,
"days_since_breach": 21,
"compromised_urls": 100,
"lookalikes_with_mx": 3
}
}Capture Data:
domain: Analyzed domain namebreaches: Count of breached accounts by typepasswords: Password strength distribution and percentageslast_breach_utc: Most recent breach timestampcompromised_urls: Number of compromised URLs/subdomainstotal_stealers: Total stealer malware instances foundlookalikes.registered: Number of registered typosquatting domainslookalikes.with_mx: Lookalike domains with MX records (email capability)
Risk Data:
risk_score: Overall risk score (0-10, higher = riskier)weak_password_pct: Percentage of weak passwordsdays_since_breach: Days since most recent breachlookalikes_with_mx: High-risk lookalike domains
The risk score (0-10) is calculated based on:
- Breach Volume (up to 6 points): Employee, user, and third-party compromises
- Password Quality (up to 2.5 points): Percentage of weak passwords
- Breach Recency (up to 2 points): More recent = higher score
- Attack Surface (up to 1.5 points): Compromised subdomains and stealer diversity
- Lookalike Threats (up to 2 points): Typosquatting domains, especially with email capability
curl -X POST "http://localhost/analyze" \
-H "Content-Type: application/json" \
-d '{"domain":"example.com"}'import requests
response = requests.post(
"http://localhost/analyze",
json={"domain": "example.com"}
)
data = response.json()
print(f"Risk Score: {data['risk']['risk_score']}/10")
print(f"Total Breaches: {data['capture']['breaches']['total']}")$body = @{
domain = "example.com"
} | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri "http://localhost/analyze" `
-ContentType "application/json" -Body $bodyconst response = await fetch('http://localhost/analyze', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ domain: 'example.com' })
});
const data = await response.json();
console.log(`Risk Score: ${data.risk.risk_score}/10`);FastAPI automatically generates interactive documentation:
- Swagger UI: http://localhost/docs
- ReDoc: http://localhost/redoc
Risker/
├── main.py # FastAPI application and risk calculation logic
├── requirements.txt # Python dependencies
├── Dockerfile # Docker container configuration
├── docker-compose.yml # Docker Compose orchestration
├── .dockerignore # Docker build exclusions
└── README.md # This file
- FastAPI: Modern web framework for building APIs
- Uvicorn: ASGI server for running FastAPI
- Pydantic: Data validation using Python type hints
- requests: HTTP library for API calls
- tldextract: Domain name parsing
- python-dateutil: Date parsing utilities
- dnstwist: Domain typosquatting detection
The application enforces Hudson Rock API rate limits:
- 50 requests per 10 seconds
- Automatic queuing and waiting when limit is reached
- Thread-safe implementation for concurrent requests
The API returns HTTP 500 with error details if:
- Hudson Rock API is unavailable
- Invalid domain format
- Network connectivity issues
- dnstwist execution fails
- All API warnings are suppressed for cleaner logs
- No authentication required (add reverse proxy with auth if needed)
- CORS not configured (configure if frontend integration needed)
- Runs on port 80 (may require elevated privileges outside Docker)
- Install Python 3.11+
- Install dependencies:
pip install -r requirements.txt
- Run the application:
python main.py
None required. All configuration is hardcoded for simplicity.
- Average response time: 10-30 seconds (depends on dnstwist execution)
- Memory usage: ~100-200 MB per container
- Recommended for low-to-medium traffic (< 100 concurrent requests)
Service won't start on port 80:
- Ensure port 80 is not in use:
netstat -ano | findstr :80 - Run with elevated privileges or change port in docker-compose.yml
Slow response times:
- dnstwist domain scanning can take 15-30 seconds
- Consider implementing caching for frequently queried domains
Hudson Rock API errors:
- Check rate limiting (50 req/10sec)
- Verify network connectivity to cavalier.hudsonrock.com
This project is provided as-is for security assessment purposes.
- Hudson Rock Cavalier API: Breach data provider
- dnstwist: Lookalike domain detection tool
For issues or questions, please review the code or check the interactive API documentation at /docs.