mailaccess 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mailaccess-0.1.0/.env.example +101 -0
- mailaccess-0.1.0/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
- mailaccess-0.1.0/.github/ISSUE_TEMPLATE/feature_request.md +23 -0
- mailaccess-0.1.0/.github/ISSUE_TEMPLATE/new_module.md +39 -0
- mailaccess-0.1.0/.gitignore +52 -0
- mailaccess-0.1.0/.python-version +1 -0
- mailaccess-0.1.0/CONTRIBUTING.md +90 -0
- mailaccess-0.1.0/DISCLAIMER.md +29 -0
- mailaccess-0.1.0/Makefile +42 -0
- mailaccess-0.1.0/PKG-INFO +160 -0
- mailaccess-0.1.0/README.md +119 -0
- mailaccess-0.1.0/SECURITY.md +39 -0
- mailaccess-0.1.0/backend/Dockerfile +30 -0
- mailaccess-0.1.0/backend/__init__.py +0 -0
- mailaccess-0.1.0/backend/api/__init__.py +0 -0
- mailaccess-0.1.0/backend/api/middleware/auth.py +49 -0
- mailaccess-0.1.0/backend/api/queue_registry.py +13 -0
- mailaccess-0.1.0/backend/api/router.py +11 -0
- mailaccess-0.1.0/backend/api/routes/__init__.py +0 -0
- mailaccess-0.1.0/backend/api/routes/health.py +28 -0
- mailaccess-0.1.0/backend/api/routes/investigations.py +167 -0
- mailaccess-0.1.0/backend/api/routes/maltego.py +83 -0
- mailaccess-0.1.0/backend/api/routes/modules.py +26 -0
- mailaccess-0.1.0/backend/api/websocket.py +111 -0
- mailaccess-0.1.0/backend/config.py +101 -0
- mailaccess-0.1.0/backend/core/__init__.py +24 -0
- mailaccess-0.1.0/backend/core/aggregator.py +37 -0
- mailaccess-0.1.0/backend/core/engine.py +243 -0
- mailaccess-0.1.0/backend/core/http_client.py +53 -0
- mailaccess-0.1.0/backend/core/permutator.py +96 -0
- mailaccess-0.1.0/backend/core/proxy.py +55 -0
- mailaccess-0.1.0/backend/core/rate_limiter.py +61 -0
- mailaccess-0.1.0/backend/core/result_aggregator.py +101 -0
- mailaccess-0.1.0/backend/core/scheduler.py +29 -0
- mailaccess-0.1.0/backend/core/service.py +199 -0
- mailaccess-0.1.0/backend/db/__init__.py +12 -0
- mailaccess-0.1.0/backend/db/database.py +23 -0
- mailaccess-0.1.0/backend/db/models.py +97 -0
- mailaccess-0.1.0/backend/exporters/__init__.py +30 -0
- mailaccess-0.1.0/backend/exporters/base.py +14 -0
- mailaccess-0.1.0/backend/exporters/csv_exporter.py +51 -0
- mailaccess-0.1.0/backend/exporters/json_exporter.py +26 -0
- mailaccess-0.1.0/backend/exporters/maltego_exporter.py +91 -0
- mailaccess-0.1.0/backend/exporters/markdown_exporter.py +140 -0
- mailaccess-0.1.0/backend/exporters/pdf_exporter.py +527 -0
- mailaccess-0.1.0/backend/exporters/stix_exporter.py +201 -0
- mailaccess-0.1.0/backend/integrations/integration_webhook.py +39 -0
- mailaccess-0.1.0/backend/integrations/maltego_transform.py +260 -0
- mailaccess-0.1.0/backend/integrations/webhooks.py +208 -0
- mailaccess-0.1.0/backend/main.py +96 -0
- mailaccess-0.1.0/backend/modules/__init__.py +57 -0
- mailaccess-0.1.0/backend/modules/account_discovery.py +110 -0
- mailaccess-0.1.0/backend/modules/base.py +41 -0
- mailaccess-0.1.0/backend/modules/dns_lookup.py +16 -0
- mailaccess-0.1.0/backend/modules/domain_intel.py +284 -0
- mailaccess-0.1.0/backend/modules/emailrep.py +105 -0
- mailaccess-0.1.0/backend/modules/ghunt_module.py +240 -0
- mailaccess-0.1.0/backend/modules/google_dork.py +111 -0
- mailaccess-0.1.0/backend/modules/google_search.py +12 -0
- mailaccess-0.1.0/backend/modules/gravatar.py +88 -0
- mailaccess-0.1.0/backend/modules/haveibeenpwned.py +1 -0
- mailaccess-0.1.0/backend/modules/hibp.py +154 -0
- mailaccess-0.1.0/backend/modules/hudson_rock.py +175 -0
- mailaccess-0.1.0/backend/modules/hunter_io.py +17 -0
- mailaccess-0.1.0/backend/modules/permutation_discovery.py +194 -0
- mailaccess-0.1.0/backend/modules/shodan.py +18 -0
- mailaccess-0.1.0/backend/modules/social.py +448 -0
- mailaccess-0.1.0/backend/modules/social_links.py +16 -0
- mailaccess-0.1.0/backend/modules/whatsmyname.py +151 -0
- mailaccess-0.1.0/backend/modules/whois_lookup.py +15 -0
- mailaccess-0.1.0/cli/__init__.py +0 -0
- mailaccess-0.1.0/cli/main.py +276 -0
- mailaccess-0.1.0/docker/Dockerfile.backend +14 -0
- mailaccess-0.1.0/docker/Dockerfile.frontend +13 -0
- mailaccess-0.1.0/docker-compose.prod.yml +57 -0
- mailaccess-0.1.0/docker-compose.yml +52 -0
- mailaccess-0.1.0/docs/api.md +315 -0
- mailaccess-0.1.0/docs/architecture.md +98 -0
- mailaccess-0.1.0/docs/exports.md +107 -0
- mailaccess-0.1.0/docs/ghunt-setup.md +83 -0
- mailaccess-0.1.0/docs/integrations.md +87 -0
- mailaccess-0.1.0/docs/modules.md +492 -0
- mailaccess-0.1.0/docs/self-hosting.md +201 -0
- mailaccess-0.1.0/frontend/Dockerfile +26 -0
- mailaccess-0.1.0/frontend/index.html +22 -0
- mailaccess-0.1.0/frontend/nginx.conf +30 -0
- mailaccess-0.1.0/frontend/package-lock.json +2721 -0
- mailaccess-0.1.0/frontend/package.json +27 -0
- mailaccess-0.1.0/frontend/postcss.config.js +6 -0
- mailaccess-0.1.0/frontend/public/ma_logo.png +0 -0
- mailaccess-0.1.0/frontend/src/App.tsx +16 -0
- mailaccess-0.1.0/frontend/src/api/client.ts +47 -0
- mailaccess-0.1.0/frontend/src/components/DeleteConfirmModal.tsx +42 -0
- mailaccess-0.1.0/frontend/src/components/ExportBar.tsx +65 -0
- mailaccess-0.1.0/frontend/src/components/ExposureGauge.tsx +75 -0
- mailaccess-0.1.0/frontend/src/components/FindingCard.tsx +116 -0
- mailaccess-0.1.0/frontend/src/components/InvestigationRow.tsx +161 -0
- mailaccess-0.1.0/frontend/src/components/ModuleStatusRail.tsx +109 -0
- mailaccess-0.1.0/frontend/src/components/NavBar.tsx +41 -0
- mailaccess-0.1.0/frontend/src/components/RiskBadge.tsx +29 -0
- mailaccess-0.1.0/frontend/src/components/SkeletonCard.tsx +19 -0
- mailaccess-0.1.0/frontend/src/components/SummaryBar.tsx +52 -0
- mailaccess-0.1.0/frontend/src/hooks/useInvestigationWS.ts +58 -0
- mailaccess-0.1.0/frontend/src/index.css +78 -0
- mailaccess-0.1.0/frontend/src/main.tsx +10 -0
- mailaccess-0.1.0/frontend/src/pages/HistoryPage.tsx +237 -0
- mailaccess-0.1.0/frontend/src/pages/Home.tsx +193 -0
- mailaccess-0.1.0/frontend/src/pages/InvestigationView.tsx +114 -0
- mailaccess-0.1.0/frontend/src/store/investigationStore.ts +171 -0
- mailaccess-0.1.0/frontend/src/types.ts +35 -0
- mailaccess-0.1.0/frontend/tailwind.config.js +12 -0
- mailaccess-0.1.0/frontend/tsconfig.json +17 -0
- mailaccess-0.1.0/frontend/vite.config.ts +18 -0
- mailaccess-0.1.0/public/ma_logo.png +0 -0
- mailaccess-0.1.0/pyproject.toml +73 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# MailAccess Environment Configuration
|
|
2
|
+
|
|
3
|
+
# Application Environment
|
|
4
|
+
# Can be 'development' or 'production'
|
|
5
|
+
MAILACCESS_ENV=development
|
|
6
|
+
|
|
7
|
+
# Database Connection
|
|
8
|
+
# Leave empty to use SQLite. Default: sqlite+aiosqlite:///./data/mailaccess.db
|
|
9
|
+
# To use Postgres, set this to your connection string. Example:
|
|
10
|
+
# DATABASE_URL=postgresql://user:password@db:5432/mailaccess
|
|
11
|
+
# DATABASE_URL=
|
|
12
|
+
|
|
13
|
+
# Backend Configuration
|
|
14
|
+
# The URL where the backend is accessible
|
|
15
|
+
BACKEND_URL=http://localhost:8000
|
|
16
|
+
|
|
17
|
+
# CORS Allowed Origins
|
|
18
|
+
# Comma-separated list of origins allowed to access the backend API (maps to CORS_ORIGINS in config)
|
|
19
|
+
CORS_ORIGINS=["http://localhost:3000","http://localhost:5173"]
|
|
20
|
+
|
|
21
|
+
# Application debug mode (true/false)
|
|
22
|
+
DEBUG=false
|
|
23
|
+
# Log level: DEBUG, INFO, WARNING, ERROR
|
|
24
|
+
LOG_LEVEL=INFO
|
|
25
|
+
|
|
26
|
+
# Investigation Settings
|
|
27
|
+
# Maximum number of modules to run concurrently
|
|
28
|
+
MAX_CONCURRENT_MODULES=10
|
|
29
|
+
# Per-module timeout in seconds
|
|
30
|
+
MODULE_TIMEOUT_SECONDS=30
|
|
31
|
+
# Per-module timeout in seconds. Global default is MODULE_TIMEOUT_SECONDS.
|
|
32
|
+
MODULE_TIMEOUT_OVERRIDES={"whatsmyname": 200, "account_discovery": 120}
|
|
33
|
+
|
|
34
|
+
# Whether to enable investigation history persistence
|
|
35
|
+
ENABLE_HISTORY=true
|
|
36
|
+
|
|
37
|
+
# Account discovery module: probes registration/reset endpoints across 57 platforms.
|
|
38
|
+
# Opt-in because it is noisy (many HTTP probes) and may trigger rate limits.
|
|
39
|
+
# Enable via --modules account_discovery in the CLI or by setting this to true.
|
|
40
|
+
ENABLE_ACCOUNT_DISCOVERY=false
|
|
41
|
+
|
|
42
|
+
# WhatsMyName module: username enumeration across 700+ platforms.
|
|
43
|
+
# Opt-in because it fires ~700 HTTP requests and takes 60–90 seconds.
|
|
44
|
+
# Data is fetched from GitHub and cached locally for 24h (data/cache/wmn-data.json).
|
|
45
|
+
ENABLE_WHATSMYNAME=false
|
|
46
|
+
|
|
47
|
+
# Permutation discovery: if breach/Gravatar/other modules recover a real name,
|
|
48
|
+
# auto-generates up to 60 email variations and probes each with HIBP + Hudson Rock.
|
|
49
|
+
# Opt-in because it adds 30–60 seconds and up to 120 extra API calls.
|
|
50
|
+
ENABLE_PERMUTATION_DISCOVERY=false
|
|
51
|
+
|
|
52
|
+
# GHunt: deep Google account intelligence (GAIA ID, YouTube channel, Maps reviews, profile photo).
|
|
53
|
+
# Requires ghunt>=2.3 installed (`pip install "mailaccess[ghunt]"`) and a valid session obtained
|
|
54
|
+
# via `ghunt login`. Cookies expire periodically and must be refreshed manually.
|
|
55
|
+
# See docs/ghunt-setup.md for the one-time setup guide.
|
|
56
|
+
# Only runs against @gmail.com, @googlemail.com, or Google Workspace domains.
|
|
57
|
+
ENABLE_GHUNT=false
|
|
58
|
+
# Absolute path to the ghunt_creds.json file generated by `ghunt login`
|
|
59
|
+
GHUNT_CREDS_PATH=
|
|
60
|
+
|
|
61
|
+
# Optional proxy for all requests (e.g. Tor or HTTP proxy)
|
|
62
|
+
# Example: socks5://127.0.0.1:9050 (Tor) or http://user:pass@proxy:port
|
|
63
|
+
PROXY_URL=
|
|
64
|
+
# Set to true to activate the proxy. Proxy is ignored when false.
|
|
65
|
+
PROXY_ENABLED=false
|
|
66
|
+
|
|
67
|
+
# Per-domain rate limiting
|
|
68
|
+
# Set to false to disable all rate limiting (not recommended in production)
|
|
69
|
+
RATE_LIMIT_ENABLED=true
|
|
70
|
+
# Default minimum delay between requests to the same domain (milliseconds)
|
|
71
|
+
REQUEST_DELAY_MS=1000
|
|
72
|
+
# Per-domain overrides as a JSON object (values in milliseconds)
|
|
73
|
+
# Example: RATE_LIMIT_OVERRIDES={"api.github.com": 500, "haveibeenpwned.com": 1500}
|
|
74
|
+
RATE_LIMIT_OVERRIDES={}
|
|
75
|
+
# Legacy per-domain delays in seconds (JSON object): RATE_LIMIT_DELAYS={"haveibeenpwned.com": 1.5}
|
|
76
|
+
RATE_LIMIT_DELAYS={}
|
|
77
|
+
|
|
78
|
+
# Integrations (Webhooks)
|
|
79
|
+
SLACK_WEBHOOK_URL=
|
|
80
|
+
DISCORD_WEBHOOK_URL=
|
|
81
|
+
INTEGRATION_WEBHOOK_URL=
|
|
82
|
+
INTEGRATION_WEBHOOK_SECRET=
|
|
83
|
+
|
|
84
|
+
# API Keys (all optional, features will be disabled if key is missing)
|
|
85
|
+
# MAILACCESS_API_KEY restricts access to the REST API if set
|
|
86
|
+
MAILACCESS_API_KEY=
|
|
87
|
+
|
|
88
|
+
# Have I Been Pwned API Key for breach data (hibp module)
|
|
89
|
+
HIBP_API_KEY=
|
|
90
|
+
|
|
91
|
+
# SerpAPI Key for Google dork queries (google_dork module)
|
|
92
|
+
SERPAPI_KEY=
|
|
93
|
+
|
|
94
|
+
# Shodan API Key for host intelligence (shodan module and domain_intel)
|
|
95
|
+
SHODAN_API_KEY=
|
|
96
|
+
|
|
97
|
+
# EmailRep API Key for email reputation checking (emailrep module, optional - raises rate limits)
|
|
98
|
+
EMAILREP_API_KEY=
|
|
99
|
+
|
|
100
|
+
# Hunter.io API Key for email deliverability checks (hunter_io module)
|
|
101
|
+
HUNTER_IO_API_KEY=
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug Report
|
|
3
|
+
about: Something is broken or behaving incorrectly
|
|
4
|
+
title: '[bug] '
|
|
5
|
+
labels: bug
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## What happened
|
|
10
|
+
|
|
11
|
+
<!-- A clear description of the bug. What did you expect to happen? What actually happened? -->
|
|
12
|
+
|
|
13
|
+
## Steps to reproduce
|
|
14
|
+
|
|
15
|
+
1.
|
|
16
|
+
2.
|
|
17
|
+
3.
|
|
18
|
+
|
|
19
|
+
## Environment
|
|
20
|
+
|
|
21
|
+
- MailAccess version / commit:
|
|
22
|
+
- Deployment: [ ] Docker Compose [ ] Manual
|
|
23
|
+
- Database: [ ] SQLite [ ] PostgreSQL
|
|
24
|
+
- OS:
|
|
25
|
+
|
|
26
|
+
## Relevant logs or output
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
paste logs here
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Which module or endpoint is affected
|
|
33
|
+
|
|
34
|
+
<!-- e.g. "hibp module", "GET /api/investigations", "WebSocket stream" -->
|
|
35
|
+
|
|
36
|
+
## Additional context
|
|
37
|
+
|
|
38
|
+
<!-- Screenshots, curl commands, example emails (use a fake address), anything else useful -->
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature Request
|
|
3
|
+
about: Suggest a new feature or improvement
|
|
4
|
+
title: '[feature] '
|
|
5
|
+
labels: enhancement
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## What problem does this solve
|
|
10
|
+
|
|
11
|
+
<!-- Describe the gap or pain point. What are you trying to do that you can't do today? -->
|
|
12
|
+
|
|
13
|
+
## Proposed solution
|
|
14
|
+
|
|
15
|
+
<!-- How would you like this to work? Be as specific as you can — API shape, UI behavior, module output, etc. -->
|
|
16
|
+
|
|
17
|
+
## Alternatives considered
|
|
18
|
+
|
|
19
|
+
<!-- Other approaches you thought about and why you ruled them out -->
|
|
20
|
+
|
|
21
|
+
## Additional context
|
|
22
|
+
|
|
23
|
+
<!-- Mockups, links to similar tools, related issues -->
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: New Module Proposal
|
|
3
|
+
about: Propose adding a new OSINT data source as a module
|
|
4
|
+
title: '[module] '
|
|
5
|
+
labels: module
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Data source
|
|
10
|
+
|
|
11
|
+
**Name:** <!-- e.g. FullContact, Hunter.io, Shodan -->
|
|
12
|
+
**URL:** <!-- link to the API or service -->
|
|
13
|
+
|
|
14
|
+
## What it checks
|
|
15
|
+
|
|
16
|
+
<!-- What information does this source provide for a given email address? -->
|
|
17
|
+
|
|
18
|
+
## Example output
|
|
19
|
+
|
|
20
|
+
<!-- Paste a sample API response or describe what findings would look like. -->
|
|
21
|
+
|
|
22
|
+
## API key required?
|
|
23
|
+
|
|
24
|
+
- [ ] Yes — free tier available
|
|
25
|
+
- [ ] Yes — paid only
|
|
26
|
+
- [ ] No
|
|
27
|
+
|
|
28
|
+
## Rate limits
|
|
29
|
+
|
|
30
|
+
<!-- Requests per minute / day on the free tier, if known -->
|
|
31
|
+
|
|
32
|
+
## Why it belongs in MailAccess
|
|
33
|
+
|
|
34
|
+
<!-- What OSINT value does this add that existing modules don't cover? -->
|
|
35
|
+
|
|
36
|
+
## Will you implement it?
|
|
37
|
+
|
|
38
|
+
- [ ] Yes, I plan to submit a PR
|
|
39
|
+
- [ ] No, I'm requesting someone else implement it
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.pyc
|
|
4
|
+
*.pyo
|
|
5
|
+
*.pyd
|
|
6
|
+
.Python
|
|
7
|
+
*.egg-info/
|
|
8
|
+
dist/
|
|
9
|
+
build/
|
|
10
|
+
.venv/
|
|
11
|
+
venv/
|
|
12
|
+
.env
|
|
13
|
+
|
|
14
|
+
# Node
|
|
15
|
+
node_modules/
|
|
16
|
+
dist/
|
|
17
|
+
.next/
|
|
18
|
+
*.local
|
|
19
|
+
|
|
20
|
+
# OS
|
|
21
|
+
.DS_Store
|
|
22
|
+
Thumbs.db
|
|
23
|
+
|
|
24
|
+
# Logs
|
|
25
|
+
*.log
|
|
26
|
+
logs/
|
|
27
|
+
|
|
28
|
+
# Runtime data
|
|
29
|
+
*.db
|
|
30
|
+
data/
|
|
31
|
+
maltego/*.mtz
|
|
32
|
+
|
|
33
|
+
# IDE
|
|
34
|
+
.vscode/
|
|
35
|
+
.idea/
|
|
36
|
+
*.swp
|
|
37
|
+
*.swo
|
|
38
|
+
|
|
39
|
+
# Secrets (never commit)
|
|
40
|
+
.env
|
|
41
|
+
.env.local
|
|
42
|
+
.env.*.local
|
|
43
|
+
|
|
44
|
+
# Test artifacts
|
|
45
|
+
test_*.py
|
|
46
|
+
verify_*.py
|
|
47
|
+
.pytest_cache/
|
|
48
|
+
coverage/
|
|
49
|
+
.coverage
|
|
50
|
+
|
|
51
|
+
# Documentation
|
|
52
|
+
!.env.example
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.10
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
## Adding a Module
|
|
4
|
+
|
|
5
|
+
Each OSINT module is a single `.py` file in `backend/modules/`. The auto-discovery registry (`backend/modules/__init__.py`) scans the package at import time — no manual wiring needed.
|
|
6
|
+
|
|
7
|
+
### The five things every module must implement
|
|
8
|
+
|
|
9
|
+
```python
|
|
10
|
+
from backend.modules.base import BaseModule, ModuleResult, ModuleStatus
|
|
11
|
+
|
|
12
|
+
class MyModule(BaseModule):
|
|
13
|
+
name = "my_module" # 1. unique slug — used in API responses and DB records
|
|
14
|
+
description = "One line." # 2. human-readable purpose (shown in GET /api/modules/)
|
|
15
|
+
requires_key = True # 3. True if the module should skip when its API key is absent
|
|
16
|
+
|
|
17
|
+
async def run(self, email: str) -> ModuleResult: # 4. async, takes the email string
|
|
18
|
+
...
|
|
19
|
+
return ModuleResult( # 5. always return ModuleResult — never raise
|
|
20
|
+
status=ModuleStatus.SUCCESS, # SUCCESS | PARTIAL | FAILED | SKIPPED
|
|
21
|
+
findings=[ # list of dicts — flexible schema per module
|
|
22
|
+
{
|
|
23
|
+
"platform": "my_service",
|
|
24
|
+
"url": "https://...",
|
|
25
|
+
"metadata": {...},
|
|
26
|
+
"confidence": "high", # high | medium | low
|
|
27
|
+
}
|
|
28
|
+
],
|
|
29
|
+
metadata={}, # module-level supplementary info (counts, API version, etc.)
|
|
30
|
+
errors=[], # human-readable error strings
|
|
31
|
+
)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Key constraints
|
|
35
|
+
|
|
36
|
+
- **Never raise from `run()`.** Catch all exceptions and return `ModuleResult(status=ModuleStatus.FAILED, errors=[str(e)])`.
|
|
37
|
+
- **Check for missing keys early.** If `requires_key = True`, check `settings.your_api_key` at the top of `run()` and return `ModuleStatus.SKIPPED` if absent.
|
|
38
|
+
- **Use `build_client()`** from `backend.core.http_client` for all outbound HTTP — it respects proxy settings and the rate limiter.
|
|
39
|
+
- The engine enforces `MODULE_TIMEOUT_SECONDS` (default 30 s) per module via `asyncio.wait_for`. Plan accordingly.
|
|
40
|
+
- Do not call blocking libraries directly on the event loop — wrap them with `asyncio.to_thread()`.
|
|
41
|
+
|
|
42
|
+
### File placement
|
|
43
|
+
|
|
44
|
+
Drop the file at `backend/modules/my_module.py`. The next server start auto-registers it. Module `name` values must be unique across the package.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Adding an Exporter
|
|
49
|
+
|
|
50
|
+
Exporters live in `backend/exporters/`. Each inherits `BaseExporter`:
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
from backend.exporters.base import BaseExporter
|
|
54
|
+
|
|
55
|
+
class MyExporter(BaseExporter):
|
|
56
|
+
format_name = "myformat" # matched against ?format= query param
|
|
57
|
+
content_type = "application/x-mine" # MIME type returned in the HTTP response
|
|
58
|
+
|
|
59
|
+
def export(self, investigation_id: str, data: dict) -> bytes:
|
|
60
|
+
...
|
|
61
|
+
return result_bytes
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
After writing the class, register it in `backend/exporters/__init__.py` — add it to the import list and to the `EXPORTERS` dict.
|
|
65
|
+
|
|
66
|
+
The `data` argument is the enriched report dict produced by `enrich_report()` in `backend/core/service.py`. It contains: `id`, `email`, `status`, `exposure_score`, `risk_level`, `summary`, `findings`, `module_runs`, `findings_by_module`, `metadata_table`.
|
|
67
|
+
|
|
68
|
+
PDF exports use an async `generate()` method instead of `export()`; see `PdfExporter` for the pattern.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Code Style
|
|
73
|
+
|
|
74
|
+
- Python 3.11+, `from __future__ import annotations` at the top of every file
|
|
75
|
+
- Type annotations on all function signatures
|
|
76
|
+
- `async`/`await` throughout — no blocking I/O on the event loop
|
|
77
|
+
- No comments that describe *what* the code does — only comments explaining *why* when the reason is non-obvious
|
|
78
|
+
- Line length: 100 characters
|
|
79
|
+
- Formatter: `ruff format` (black-compatible)
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## PR Checklist
|
|
84
|
+
|
|
85
|
+
- [ ] Module or exporter follows the contracts above
|
|
86
|
+
- [ ] `requires_key = True` modules return `SKIPPED` (not `FAILED`) when the key is absent
|
|
87
|
+
- [ ] No blocking I/O executed directly on the asyncio event loop
|
|
88
|
+
- [ ] No hardcoded credentials, tokens, or identifying user-agent strings
|
|
89
|
+
- [ ] Existing tests pass (`pytest`)
|
|
90
|
+
- [ ] PR description explains what data source is queried, what the findings look like, and why they are useful for OSINT
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Disclaimer
|
|
2
|
+
|
|
3
|
+
## Intended Use
|
|
4
|
+
|
|
5
|
+
MailAccess is designed for:
|
|
6
|
+
|
|
7
|
+
- **Security research** — investigating the exposure of your own or client-authorized addresses
|
|
8
|
+
- **OSINT investigations** — open-source intelligence gathering in professional or journalistic contexts
|
|
9
|
+
- **Penetration testing** — with explicit written authorization from the target organization
|
|
10
|
+
- **Personal exposure audits** — checking your own email addresses against breach databases and public sources
|
|
11
|
+
|
|
12
|
+
## All Data Is from Public Sources
|
|
13
|
+
|
|
14
|
+
Every data point MailAccess retrieves comes from publicly accessible sources: breach notification databases, public APIs, DNS records, WHOIS registries, and the open web. MailAccess does not exploit vulnerabilities, bypass authentication, or access any non-public system or dataset.
|
|
15
|
+
|
|
16
|
+
## Not a Hacking Tool
|
|
17
|
+
|
|
18
|
+
MailAccess is not designed or intended for:
|
|
19
|
+
|
|
20
|
+
- Unauthorized access to accounts, systems, or private data
|
|
21
|
+
- Surveillance, stalking, or targeted harassment of individuals
|
|
22
|
+
- Aggregating personal data about individuals without their consent or a lawful basis
|
|
23
|
+
- Any activity that violates the Computer Fraud and Abuse Act (CFAA), the UK Computer Misuse Act, GDPR, or equivalent laws in your jurisdiction
|
|
24
|
+
|
|
25
|
+
## User Responsibility
|
|
26
|
+
|
|
27
|
+
By using MailAccess you accept sole legal and ethical responsibility for how you deploy and use it. The authors provide this software as-is, without warranty of any kind. If you are unsure whether a particular use is lawful in your jurisdiction, consult a qualified attorney before proceeding.
|
|
28
|
+
|
|
29
|
+
Misuse of this tool may violate federal, state, or local laws. The project maintainers are not liable for any misuse or damage arising from use of this software.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
.PHONY: dev prod logs shell help
|
|
2
|
+
|
|
3
|
+
# MailAccess Docker Workflow Commands
|
|
4
|
+
#
|
|
5
|
+
# Note for Production:
|
|
6
|
+
# This setup does not include Kubernetes, CI/CD pipelines, or SSL termination.
|
|
7
|
+
# For production deployments exposed to the internet, you MUST put a reverse proxy
|
|
8
|
+
# such as Nginx, Caddy, or Traefik in front of the application to handle SSL/TLS
|
|
9
|
+
# termination.
|
|
10
|
+
|
|
11
|
+
# Load environment variables to detect POSTGRES_ENABLED
|
|
12
|
+
ifneq (,$(wildcard ./.env))
|
|
13
|
+
include .env
|
|
14
|
+
export
|
|
15
|
+
endif
|
|
16
|
+
|
|
17
|
+
# Determine if we should activate the postgres profile
|
|
18
|
+
ifeq ($(POSTGRES_ENABLED),true)
|
|
19
|
+
COMPOSE_PROFILES := --profile postgres
|
|
20
|
+
else
|
|
21
|
+
COMPOSE_PROFILES :=
|
|
22
|
+
endif
|
|
23
|
+
|
|
24
|
+
help:
|
|
25
|
+
@echo "Available commands:"
|
|
26
|
+
@echo " make dev - Starts the development environment with hot-reload"
|
|
27
|
+
@echo " make prod - Builds and starts the production-optimized environment"
|
|
28
|
+
@echo " make logs - Tails logs for all running containers"
|
|
29
|
+
@echo " make shell - Opens an interactive shell inside the backend container"
|
|
30
|
+
|
|
31
|
+
dev:
|
|
32
|
+
docker compose $(COMPOSE_PROFILES) -f docker-compose.yml up --build
|
|
33
|
+
|
|
34
|
+
prod:
|
|
35
|
+
@echo "Starting production environment. Ensure you have SSL termination configured upstream!"
|
|
36
|
+
docker compose $(COMPOSE_PROFILES) -f docker-compose.prod.yml up --build -d
|
|
37
|
+
|
|
38
|
+
logs:
|
|
39
|
+
docker compose logs -f
|
|
40
|
+
|
|
41
|
+
shell:
|
|
42
|
+
docker compose exec backend /bin/bash || docker compose exec backend /bin/sh
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mailaccess
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Open-source OSINT email intelligence tool
|
|
5
|
+
Project-URL: Homepage, https://github.com/YOUR_USERNAME/mailaccess
|
|
6
|
+
Project-URL: Documentation, https://github.com/YOUR_USERNAME/mailaccess/docs
|
|
7
|
+
Project-URL: Issues, https://github.com/YOUR_USERNAME/mailaccess/issues
|
|
8
|
+
Author: Katriel Moses
|
|
9
|
+
License: MIT
|
|
10
|
+
Keywords: email,intelligence,osint,security
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Information Technology
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Topic :: Security
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Requires-Dist: aiosqlite>=0.20
|
|
18
|
+
Requires-Dist: asyncpg>=0.29
|
|
19
|
+
Requires-Dist: dnspython>=2.6
|
|
20
|
+
Requires-Dist: fastapi>=0.111
|
|
21
|
+
Requires-Dist: holehe>=1.61
|
|
22
|
+
Requires-Dist: httpx>=0.27
|
|
23
|
+
Requires-Dist: pydantic-settings>=2.3
|
|
24
|
+
Requires-Dist: pydantic[email]>=2.0
|
|
25
|
+
Requires-Dist: python-whois>=0.9
|
|
26
|
+
Requires-Dist: rich>=13
|
|
27
|
+
Requires-Dist: sqlalchemy>=2.0
|
|
28
|
+
Requires-Dist: stix2>=3.0
|
|
29
|
+
Requires-Dist: typer[all]>=0.25.1
|
|
30
|
+
Requires-Dist: uvicorn[standard]>=0.29
|
|
31
|
+
Requires-Dist: weasyprint>=62
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: httpx>=0.27; extra == 'dev'
|
|
34
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
35
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
36
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
37
|
+
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
38
|
+
Provides-Extra: ghunt
|
|
39
|
+
Requires-Dist: ghunt>=2.3; extra == 'ghunt'
|
|
40
|
+
Description-Content-Type: text/markdown
|
|
41
|
+
|
|
42
|
+
<p align="center">
|
|
43
|
+
<img src="frontend/public/ma_logo.png" width="120" alt="MailAccess Logo" />
|
|
44
|
+
</p>
|
|
45
|
+
|
|
46
|
+
<h1 align="center">MailAccess</h1>
|
|
47
|
+
|
|
48
|
+
[](LICENSE)
|
|
49
|
+
[](https://www.python.org/)
|
|
50
|
+
[](docker-compose.yml)
|
|
51
|
+
|
|
52
|
+
Self-hostable OSINT platform for investigating email addresses. Fan out across breach databases, social networks, DNS records, and the open web — get back a unified exposure score and structured findings you can export or pipe into Maltego.
|
|
53
|
+
|
|
54
|
+
Built for security researchers, OSINT analysts, and penetration testers operating under authorization. Read [DISCLAIMER.md](DISCLAIMER.md) before use.
|
|
55
|
+
|
|
56
|
+
## Install
|
|
57
|
+
|
|
58
|
+
### CLI only (fastest)
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
pip install mailaccess
|
|
62
|
+
# or (recommended)
|
|
63
|
+
pipx install mailaccess
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Full self-hosted stack
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
git clone https://github.com/YOUR_USERNAME/mailaccess
|
|
70
|
+
cd mailaccess
|
|
71
|
+
docker compose up -d
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Usage
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
mailaccess investigate you@example.com
|
|
78
|
+
mailaccess investigate you@example.com --format json
|
|
79
|
+
mailaccess investigate you@example.com --modules hibp,gravatar,social
|
|
80
|
+
mailaccess history
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
<!-- screenshot -->
|
|
84
|
+
|
|
85
|
+
## Features
|
|
86
|
+
|
|
87
|
+
- Concurrent module execution — all modules run in parallel, results stream as they arrive
|
|
88
|
+
- WebSocket streaming — partial results arrive in real time without polling
|
|
89
|
+
- REST API + web UI + CLI — use whatever interface fits your workflow
|
|
90
|
+
- Plugin module system — drop a `.py` file in `backend/modules/` and it auto-registers; no wiring required
|
|
91
|
+
- 6 export formats: JSON, CSV, PDF, Markdown, STIX 2.1, Maltego XML
|
|
92
|
+
- Maltego local transform server — run investigations directly from the Maltego desktop app
|
|
93
|
+
- Webhook notifications — Slack, Discord, or any HTTP endpoint
|
|
94
|
+
- Exposure score (0–100) with risk label: low / medium / high / critical
|
|
95
|
+
- SQLite by default; PostgreSQL optional via Docker Compose profile
|
|
96
|
+
|
|
97
|
+
## Quick Start
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
cp .env.example .env # all API keys are optional
|
|
101
|
+
docker compose up # backend :8000 · frontend :3000
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Open **http://localhost:3000** in your browser.
|
|
105
|
+
|
|
106
|
+
## Modules
|
|
107
|
+
|
|
108
|
+
| Module | What it checks | Requires key |
|
|
109
|
+
|--------|---------------|:------------:|
|
|
110
|
+
| `hibp` | Known data breaches via the HIBP v3 API | Yes — `HIBP_API_KEY` |
|
|
111
|
+
| `emailrep` | Reputation score, risk flags, linked profiles (EmailRep.io) | No (key optional) |
|
|
112
|
+
| `gravatar` | Gravatar and Libravatar profile, linked accounts | No |
|
|
113
|
+
| `google_dork` | Google dork queries via SerpAPI — LinkedIn, GitHub, Pastebin, open web | Yes — `SERPAPI_KEY` |
|
|
114
|
+
| `domain_intel` | WHOIS, SPF / DMARC / MX, website presence, Shodan subdomains | No (Shodan optional) |
|
|
115
|
+
| `social` | Account existence on 13 platforms (GitHub, Discord, Spotify, Skype, and more) | No |
|
|
116
|
+
| `account_discovery` | Account probing across 120+ platforms via Holehe (opt-in) | No |
|
|
117
|
+
| `whatsmyname` | Username enumeration across 800+ platforms via WhatsMyName dataset (opt-in) | No |
|
|
118
|
+
| `hudson_rock` | Infostealer credential log lookup via Hudson Rock Cavalier API | No |
|
|
119
|
+
| `permutation_discovery` | Generates email permutations from recovered name, probes with HIBP + Hudson Rock (opt-in) | No |
|
|
120
|
+
| `ghunt` | Deep Google account intel: GAIA ID, YouTube, Maps reviews, Drive (Gmail only, opt-in) | Yes — `GHUNT_CREDS_PATH` |
|
|
121
|
+
| `dns_lookup` | MX, SPF, DMARC, DKIM DNS records | No |
|
|
122
|
+
| `whois_lookup` | WHOIS registration data | No |
|
|
123
|
+
| `shodan` | Hosts and open services for the email's domain | Yes — `SHODAN_API_KEY` |
|
|
124
|
+
| `social_links` | Social profiles inferred from the email username | No |
|
|
125
|
+
| `google_search` | Google search mentions of the email | No |
|
|
126
|
+
|
|
127
|
+
## Export Formats
|
|
128
|
+
|
|
129
|
+
| Format | `?format=` value | Use case |
|
|
130
|
+
|--------|-----------------|----------|
|
|
131
|
+
| JSON | `json` | Programmatic use, archiving |
|
|
132
|
+
| CSV | `csv` | Spreadsheet analysis |
|
|
133
|
+
| PDF | `pdf` | Human-readable reports |
|
|
134
|
+
| Markdown | `markdown` | Wikis, issue trackers |
|
|
135
|
+
| STIX 2.1 | `stix` | Threat intelligence platforms |
|
|
136
|
+
| Maltego XML | `maltego` | Maltego graph import |
|
|
137
|
+
|
|
138
|
+
## Integrations
|
|
139
|
+
|
|
140
|
+
| Integration | How |
|
|
141
|
+
|-------------|-----|
|
|
142
|
+
| Maltego | Local transform server at `POST /maltego/email_investigate` (no API key required) |
|
|
143
|
+
| Slack | Set `SLACK_WEBHOOK_URL` in `.env` |
|
|
144
|
+
| Discord | Set `DISCORD_WEBHOOK_URL` in `.env` |
|
|
145
|
+
| Generic webhook | `INTEGRATION_WEBHOOK_URL` + optional `INTEGRATION_WEBHOOK_SECRET` (HMAC) |
|
|
146
|
+
|
|
147
|
+
## Documentation
|
|
148
|
+
|
|
149
|
+
| Page | Contents |
|
|
150
|
+
|------|----------|
|
|
151
|
+
| [Self-hosting](docs/self-hosting.md) | Docker Compose, `.env` reference, PostgreSQL, proxy/Tor, Maltego setup |
|
|
152
|
+
| [Module reference](docs/modules.md) | All modules, findings schema, adding new modules |
|
|
153
|
+
| [API reference](docs/api.md) | REST endpoints, WebSocket events, authentication |
|
|
154
|
+
| [Export formats](docs/exports.md) | Supported formats, MIME types, filename conventions |
|
|
155
|
+
| [Integrations](docs/integrations.md) | Maltego, Slack, Discord, generic webhooks |
|
|
156
|
+
| [Contributing](CONTRIBUTING.md) | Adding modules, adding exporters, code style, PR checklist |
|
|
157
|
+
|
|
158
|
+
## License
|
|
159
|
+
|
|
160
|
+
MIT. All data queried by MailAccess comes from public sources. See [DISCLAIMER.md](DISCLAIMER.md) for authorized use cases and legal responsibility.
|