This document describes the implementation of breach detection using the Have I Been Pwned (HIBP) API to detect if user passwords or emails appear in known data breaches.
Defines TypeScript interfaces for:
BreachData- Breach information from HIBP APIBreachCheckResult- Result of a breach checkStoredBreachResult- Persistent storage formatBreachSeverity- Severity levels (critical, high, medium, low, safe)BreachCheckOptions- Configuration for breach checks
Core service implementing:
- k-anonymity password checking - Only sends first 5 characters of SHA-1 hash to HIBP
- Rate limiting - 1500ms between requests per HIBP guidelines
- In-memory caching - 24-hour cache to minimize API calls
- Exponential backoff - Handles rate limit errors (429) with retry logic
- Password breach checking (
checkPasswordBreach) - Uses Pwned Passwords API - Email breach checking (
checkEmailBreach) - Requires HIBP API key (optional)
Security Features:
- SHA-1 hashing using
@noble/hashes - k-anonymity: Only first 5 hash characters sent to API
- Add-Padding header for additional privacy
- Local caching to reduce external requests
- Added
StoredBreachResulttable to IndexedDB schema (version 2) - Indexes:
id,credentialId,checkType,breached,severity,checkedAt,expiresAt - Automatic cache expiration (24 hours)
Repository pattern implementation:
saveBreachResult- Store breach check resultsgetBreachResult- Retrieve cached resultsgetAllBreachedCredentials- Get all breached itemsgetBreachStatistics- Aggregate statisticsdeleteBreachResults- Remove results for credentialcleanupExpiredResults- Remove expired cache entries
Prominent alert banner shown on dashboard:
- Auto-displays when breached credentials detected
- Dismissable (7-day reminder)
- Shows count of breached passwords
- Quick navigation to Security Audit page
- Color-coded severity (critical/warning)
Detailed breach information dialog:
- Lists all breaches for a credential
- Shows breach date, affected accounts, data classes
- Displays recommended security actions
- Links to HIBP website for more info
- HIBP attribution and credits
Enhanced SecurityAuditPage.tsx with:
- Breach Detection Card - Summary statistics
- Manual Scan Button - Scan all credentials for breaches
- Breach Issues - Added "breached" issue type
- Visual Indicators - Red "BREACHED" chip for affected credentials
- View Details Button - Opens BreachDetailsModal
- Statistics Display:
- Breached passwords count
- Safe passwords count
- Total checked count
- Priority Recommendations - Breached passwords shown first
Updated DashboardPage.tsx:
- Added
BreachAlertBannercomponent - Displays at top of dashboard for immediate visibility
- Auto-refreshes when breach data updates
Updated .env.example:
# Have I Been Pwned (HIBP) API Configuration
VITE_HIBP_API_ENABLED=true
VITE_HIBP_USER_AGENT=TrustVault-PWA
# VITE_HIBP_API_KEY=your-api-key-here # Optional for email checking-
Enable Breach Detection:
cp .env.example .env # Edit .env and set: VITE_HIBP_API_ENABLED=true VITE_HIBP_USER_AGENT=TrustVault-PWA -
(Optional) Enable Email Breach Checking:
- Get API key from https://haveibeenpwned.com/API/Key
- Add to
.env:VITE_HIBP_API_KEY=your-key
-
Manual Scan:
- Navigate to Security Audit page
- Click "Scan All" button in Breach Detection card
- Wait for scan to complete (rate-limited)
- Review results in the issues list
-
View Breach Details:
- Click "View Breach Details" on any breached credential
- Review breach information and recommendations
- Take action (change password, enable 2FA, etc.)
-
Dismiss Alerts:
- Click X on BreachAlertBanner to dismiss
- Banner will re-appear after 7 days if issue persists
User Action (Scan)
↓
SecurityAuditPage.scanForBreaches()
↓
For each credential:
checkPasswordBreach(password)
↓
SHA-1 Hash → Send first 5 chars to HIBP
↓
Match suffix → Count occurrences
↓
Save to breachResultsRepository
↓
Store in IndexedDB (24hr cache)
Display Results:
↓
SecurityAuditPage (issues list)
DashboardPage (alert banner)
- k-anonymity: Never sends full password or hash to HIBP
- Local Hashing: SHA-1 computed client-side using
@noble/hashes - Rate Limiting: Prevents API abuse, respects HIBP guidelines
- Caching: Reduces external requests, improves performance
- Offline Support: Cached results available offline
- No Email Tracking: Email checks require explicit API key
- In-memory cache: Fast lookups for repeated checks
- IndexedDB persistence: 24-hour cache reduces API calls
- Rate limiting: 1500ms between requests
- Batch scanning: Process all credentials sequentially
- Lazy loading: Components loaded on-demand
// Check if password is breached
const result = await checkPasswordBreach('myPassword123', {
forceRefresh: false // Use cache if available
});
// Result structure
{
breached: boolean,
breaches: BreachData[], // Empty for password checks
severity: 'critical' | 'high' | 'medium' | 'low' | 'safe',
checkedAt: number,
breachCount: number // Times seen in breaches
}
// Check if email is breached (requires API key)
const result = await checkEmailBreach('user@example.com', {
includeUnverified: false, // Filter unverified breaches
truncateResponse: false // Get full breach details
});// Save breach result
await saveBreachResult(credentialId, 'password', result);
// Get cached result
const cached = await getBreachResult(credentialId, 'password');
// Get all breached credentials
const breached = await getAllBreachedCredentials();
// Get statistics
const stats = await getBreachStatistics();
// Returns: { total, breached, safe, bySeverity: {...} }For testing breach detection:
- Breached:
password123(seen millions of times) - Safe: Use password generator for unique password
- Add test credential with known breached password
- Navigate to Security Audit
- Click "Scan All"
- Verify breach detected and severity displayed
- Click "View Breach Details"
- Verify modal shows correct information
- Check dashboard shows BreachAlertBanner
All code passes TypeScript strict mode:
npm run type-check # Must pass
npm run build # Must complete successfullysrc/core/breach/breachTypes.ts- Type definitionssrc/core/breach/hibpService.ts- HIBP API integrationsrc/data/repositories/breachResultsRepository.ts- Data access layersrc/presentation/components/BreachAlertBanner.tsx- Alert banner componentsrc/presentation/components/BreachDetailsModal.tsx- Details modal component
src/data/storage/database.ts- Added BreachResults tablesrc/presentation/pages/SecurityAuditPage.tsx- Breach detection UIsrc/presentation/pages/DashboardPage.tsx- Alert banner integration.env.example- HIBP configuration
@noble/hashes- SHA-1 hashing (already in project)- No additional dependencies required
Potential improvements:
- Background Scanning: Automatic periodic scans
- Email Breach Checks: Integrate with email credentials
- Breach Notifications: Push notifications for new breaches
- Export Reports: PDF/CSV export of breach audit
- Breach History: Track breach detection over time
- Auto-Remediation: Prompt to change password immediately
- Breach Severity Badges: Visual indicators on credential cards
- Breach data provided by Have I Been Pwned
- Created by Troy Hunt
- k-anonymity implementation based on HIBP Pwned Passwords API
This implementation follows TrustVault PWA's license and respects HIBP's acceptable use policy.