Files
MarketingTool/docs/SECURITY.md
T

82 lines
15 KiB
Markdown
Raw Normal View History

2026-09-02 17:38:50 +02:00
# Security Notes
## Current safety boundary
- **Automated outreach is disabled.** The Compose file sets `AUTOMATED_OUTREACH_ENABLED=false` for both services. The MVP sends no email, SMS, or other outbound communication.
2026-09-02 18:58:10 +02:00
- Phase 5 source handling is **registered, approval-gated, and fail-closed**. The current runtime has no live network source or network discovery implementation. CSV and manual reference adapters are operator-supplied only; neither proves a fact or grants contact permission.
- Source registry entries must have an accountable terms owner, permitted purpose, approval status/expiry, rate/concurrency limits, retention class, and health/circuit policy before an adapter can be enabled.
- Discovery queries must be tenant-scoped, bounded, auditable, and explicit about execution mode. `dry_run` validates/plans without contacting a source or writing prospect facts. No live source may run without recorded product/legal/security approval and explicit operational enablement.
- Raw source records are sensitive lineage data: retain only the minimum needed to reproduce a normalized result, under the approved retention class, with tenant/source/query IDs, capture time, adapter version, and redaction metadata. Never store secrets or unnecessary personal/contact data.
- Phase 3 intelligence is **manual and provenance-first**. Operators enter child intelligence/evidence records; the platform does not perform automated prospect discovery, DNS resolution, website/HTTP scanning, or external enrichment.
- Every business, child record, note, pipeline transition, and audit/activity read or write must be constrained to the authenticated user's organization. A child identifier must never bypass the parent/tenant check. Cross-tenant misses should be indistinguishable from an absent record.
- Evidence provenance (source reference/label, captured or observed time, actor, and confidence where supported) is data lineage, not proof that the platform independently verified the source. Do not fabricate provenance or silently upgrade an observation to a verified fact.
- List and child-record APIs use bounded pagination and server-side filters. Bounds must be enforced before query execution and filters must be combined with the tenant predicate; never use client-side filtering as an authorization control.
- Pipeline and notes are collaboration metadata. A reviewed pipeline state does not authorize contact, and suppression takes precedence over every other state. Audit entries should capture actor, tenant, target, action, timestamp, and safe details without secrets or unnecessary contact data.
2026-09-02 17:38:50 +02:00
- No credentials are committed. `.env.example` contains non-secret names and local defaults only.
2026-09-02 17:45:57 +02:00
- Authentication uses server-side sessions for browser clients. The session identifier is carried in an `HttpOnly` cookie; logout/revocation must invalidate the server-side session. Health endpoints are deliberately public and must remain usable without a session.
2026-09-02 17:38:50 +02:00
- Containers run as an unprivileged user, drop Linux capabilities, use `no-new-privileges`, and use read-only root filesystems. The API data volume is the only intended writable persistent location.
2026-09-02 18:12:21 +02:00
- Phase 4 job/live-log controls are not enabled in the current runtime. If added, job IDs, idempotency keys, status, cancellation, retries, and event cursors must all be authorized against the authenticated organization; never accept a job or child identifier as authorization by itself.
- Persisted job events must be append-only, sequence-ordered per job, replayable from a cursor, and redacted to safe operational data. Never emit credentials, session cookies, API keys, full request bodies, or unnecessary contact/prospect data in polling responses, SSE frames, logs, or error details.
2026-09-02 17:38:50 +02:00
2026-09-03 08:46:22 +02:00
## Phase 6 normalization and deduplication controls
- Treat normalization as a deterministic, versioned derivation, never as identity proof. SA phone normalization must use an explicit `+27` context for local `0` forms and retain the original/display value; location normalization must retain raw input and flag missing or ambiguous province/municipality/city rather than guessing.
- Exact duplicate keys and fuzzy suggestions must be reproducible from the same tenant data, normalization version, and algorithm version. Expose the score and reasons, and use `>=0.90` for a strong suggestion, `0.750.8999` for a review suggestion, and `<0.75` for no suggestion. Thresholds are triage policy, not permission to merge.
- Never auto-merge. Require an authenticated, authorized human to select the survivor and explicitly confirm each merge. Enforce this server-side; a hidden UI control, submitted score, or candidate ID is not authorization.
- Create a tenant-scoped merge snapshot before mutation. It must cover the complete parent/child graph, contacts, domains/websites, evidence and provenance, source-record links/raw lineage, notes, pipeline state, and audit context, plus actor/time, algorithm/normalization versions, score/reasons, and conflict decisions. Protect snapshots from ordinary mutation and make them sufficient for reversal.
- Preserve child, evidence, provenance, and source-record identity by re-parenting or retaining links; never discard a losing observation or silently overwrite conflicting values. A merge or reversal must be transactional or fail closed.
- Audit candidate generation (without leaking cross-tenant data), suggestion/rejection, confirmation, snapshot creation, merge, conflict resolution, and reversal with tenant, actor, target IDs, timestamp, versions, and safe details. Audit reads and snapshots require the same tenant predicate as business reads; cross-tenant candidates are never compared.
The MVP provides deterministic match suggestions, an explicit human confirmation dialog, a tenant-scoped merge ledger/snapshot, and reversal routes. These are pilot controls, not a compliance-grade merge system: add a dedicated merge permission, server-verifiable confirmation/re-authentication, complete parent/conflict snapshots, transactional concurrency protection, and tamper-evident retention before production. Do not present derived normalization or a suggestion as verified identity, discovery, enrichment, or outreach permission.
2026-09-03 10:43:18 +02:00
## Phase 7 domain-intelligence controls
- Registrable-domain derivation must use a pinned/versioned PSL. Never use a naive last-two-label fallback. Preserve the raw input and return unresolved for unknown/private suffixes, public suffixes, malformed/single-label names, localhost, and IP literals; handle IDN/punycode deterministically and treat subdomains conservatively.
- DNS status is not a business fact. Expose `not_checked`, `pending`, `resolved`, `nxdomain`, `no_data`, `timeout`, `servfail`, `blocked`, and `error` separately. A failed, blocked, stale, or empty response must not be upgraded to “no domain,” “no email,” or “unowned.”
- MX, NS, and TXT observations require independent provenance, resolver/source, observed time, TTL, truncation/partial and uncertainty/error metadata. MX absence does not prove mail inability; NS does not prove control; TXT does not prove ownership. Treat TXT values as untrusted input and redact secrets where applicable.
- DNS caches must be bounded and keyed by normalized name/type/class plus resolver policy and PSL version where relevant. Honor received TTLs without extending authority, expose freshness/staleness, invalidate on policy/PSL changes, and prevent one tenant's cached evidence from being disclosed to another. A cache hit is not a fresh check.
- Association confidence is an explainable, versioned review signal separate from DNS status and duplicate score. Candidate generation must enforce tenant scope before comparison, reject public-suffix-only/malformed/IP candidates, flag shared/parked/wildcard/homograph/sibling-subdomain and conflicting-evidence cases, and require authorized human accept/reject decisions. Never auto-attach or infer ownership.
- Domain availability must remain `unknown` unless an explicitly authorized provider is registered and checked at execution time for current product/legal/security approval, terms, tenant scope, rate/concurrency limits, retention, and health/circuit state. DNS `nxdomain`/`no_data`, stale cache, timeout, or provider failure is never availability. Fail closed; do not purchase, reserve, contact, or report availability from DNS alone.
No Phase 7 resolver, cache, or availability provider is enabled in the current Compose runtime. Before production, add egress/SSRF controls, provider and PSL update review, retention/deletion handling, monitoring, permission/audit coverage, and failure/rollback tests for all domain observations.
2026-09-02 18:58:10 +02:00
## Phase 5 source security controls
Source adapters are a security boundary, not a generic fetch facility. Registry review must verify the source identity, terms/robots and licensing owner, permitted collection purpose, approval expiry, tenant scope, rate/concurrency budget, raw-record retention/deletion policy, and circuit thresholds. Keep these controls server-side and auditable; a UI flag or client-supplied source ID is not authorization.
- `dry_run` is the safe default: validate a bounded discovery query and produce a plan without network I/O, adapter side effects, or prospect-fact writes.
- CSV and manual reference adapters accept operator-supplied material only. Preserve citation/reference, actor, capture time, adapter/version, and normalization lineage; label it as supplied/observed rather than verified.
- Raw source records must be access-controlled, tenant-scoped, minimally retained, immutable enough for replay/audit, and redacted for secrets and unnecessary personal data. Apply the approved retention class and deletion schedule.
- Enforce per-source request, concurrency, byte, timeout, and retry limits. Rate-limit responses must not be bypassed by rotating identities or silently selecting another source.
- Health controls must record success/failure/latency signals and use a circuit breaker with `closed`, `open`, and guarded `half-open` states. Open circuits fail closed, suppress live attempts, and surface a safe deferred/unavailable outcome.
- No live network source is allowed without explicit product, legal, and security approval plus operational enablement of the registered adapter. Approval must be checked at execution time and expire safely.
If a future approved adapter fetches URLs, apply the SSRF requirements below in addition to source approval. Network discovery is not implemented by this documentation or by the current Compose stack.
2026-09-02 17:38:50 +02:00
## Known limitations before production
2026-09-02 17:45:57 +02:00
1. **Password storage:** production passwords must be hashed with Argon2id using a reviewed cost/memory/parallelism policy. Never store plaintext or reversible passwords, and never log bootstrap credentials. Rehash on login when the policy changes.
2. **MFA:** require phishing-resistant or TOTP MFA for administrator accounts in production, including the bootstrap admin before granting ongoing administrative access. Define recovery, enrollment, reset, and revocation procedures; do not treat a password-only bootstrap as production-ready.
3. **Authentication and authorization:** enforce authorization server-side on every protected route, including every child-record, note, pipeline, and audit route. Rotate/regenerate sessions at login and privilege changes, expire idle/absolute sessions, revoke on logout/password reset, and test tenant isolation.
4. **Cookies and CSRF:** use `HttpOnly`, `Secure` (production HTTPS), and an appropriate `SameSite` policy. Browser state-changing endpoints require CSRF tokens (or a rigorously reviewed equivalent); do not rely on CORS or cookie flags alone.
5. **SSRF and future scanners:** no scanner is enabled in this release. If a future approved feature fetches a URL, allow only `http`/`https`, validate DNS/IP targets, block loopback/private/link-local/cloud-metadata ranges after resolution, limit redirects, enforce size/time limits, and re-check each redirect.
6. **Input/output safety:** validate schema and content types, bound request and note/evidence sizes, parameterize database queries, escape output, and reject unsafe provenance URLs or markup. Treat operator-entered notes and sources as untrusted data.
7. **Audit and retention:** the current audit/activity behavior is an MVP trail, not an immutable compliance log. Define append-only guarantees, retention, redaction/deletion rules, access controls, alerting, and export procedures before production.
8. **Secrets:** inject production secrets from a secret manager or orchestrator secret store. Do not place them in images, Compose files, source, CI logs, or committed `.env` files. Remove bootstrap variables after first-run provisioning.
9. **Transport and perimeter:** terminate TLS at a trusted ingress, restrict exposed ports, add network policy, and place admin surfaces behind appropriate access controls.
10. **Data protection:** define retention and deletion rules for prospect/contact data and provenance, restrict volume access, encrypt backups, and maintain a tested access/audit trail.
2026-09-02 18:12:21 +02:00
11. **Jobs and idempotency:** require tenant-scoped idempotency keys for side-effecting job creation and bind each key to a request fingerprint; reject conflicting reuse and make retries safe against duplicate side effects. Persist lifecycle transitions transactionally and define lease/timeout/recovery behavior.
12. **Live delivery:** SSE, if introduced, must authenticate before opening the stream, enforce tenant scope on every replay query, bound event/backlog size, support `Last-Event-ID`/cursor replay, send heartbeats, and provide polling fallback. Treat event-stream connections as untrusted clients and avoid cross-tenant timing/detail leaks.
13. **Worker boundary:** the current SQLite/in-process MVP is not durable or horizontally safe. A production worker migration requires reviewed queue semantics, leases, visibility timeouts, dead-letter handling, concurrency limits, cancellation races, metrics, and deployment isolation. Redis/Celery are not implemented today.
2026-09-03 10:43:18 +02:00
14. **Domain intelligence:** implement and security-review PSL pin/update handling, bounded DNS resolution, TTL-aware cache isolation/invalidation, uncertainty-preserving MX/NS/TXT parsing, tenant-scoped association decisions, and an authorized availability provider before exposing any live domain status. No DNS response may authorize acquisition, ownership, outreach, or verification.
2026-09-02 17:38:50 +02:00
## Source and contact policy
Treat manually supplied business information, notes, and source references as potentially personal or copyrighted data. Collect only what is needed for the documented product purpose, preserve source attribution where required, respect site terms and robots/access policies, and provide suppression/deletion handling. Do not infer consent to contact from public availability or a reviewed pipeline state. Any future outreach or discovery feature requires explicit product/legal and security review and must remain off by default.
2026-09-02 17:38:50 +02:00
## CI/dependency hygiene
Pin or review base-image and dependency updates, scan images before release, use least-privilege GitHub tokens, and avoid printing environment values. CI may validate Compose with empty optional bootstrap variables and call unauthenticated health checks; it is not a substitute for authorization/tenant-isolation tests, provenance policy review, Argon2id parameter review, MFA testing, or a security assessment.
2026-09-02 17:38:50 +02:00
Report vulnerabilities privately to the repository maintainers; do not include live credentials or personal data in an issue.