docs: add architecture, design spec, and security notes
Analyze the NS App and document what it does: NMI card payments on Sales Invoices, AutoPay vaulting, multi-invoice settlement, guided Customer Quick Entry, and branded print formats. - docs/ARCHITECTURE.md — functional overview, component map, payment flow, data model, dependencies, config, known tech debt - docs/DESIGN_SPEC.md — goals, requirements, API contracts, failure modes, acceptance criteria - docs/SECURITY_NOTES.md — posture + hardening list - docs/README.md — docs index; link from root README Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
33
docs/SECURITY_NOTES.md
Normal file
33
docs/SECURITY_NOTES.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# NS App — Security Notes & Hardening
|
||||
|
||||
Companion to [ARCHITECTURE.md](./ARCHITECTURE.md) §9 and
|
||||
[DESIGN_SPEC.md](./DESIGN_SPEC.md) §7.
|
||||
|
||||
## Current posture (as implemented)
|
||||
|
||||
- **PCI scope minimized.** Card number, expiry, and CVV are entered into
|
||||
NMI-hosted Collect.js iframes. ERPNext receives only a single-use
|
||||
`payment_token`. Raw card data never reaches the browser JS context or the
|
||||
server.
|
||||
- **No card storage.** Only the NMI Customer Vault ID is persisted on the
|
||||
Customer (`custom_auto_pay_id`).
|
||||
- **Secret handling.** `nmi_security_key` is read from `site_config.json`
|
||||
(server-side) and sent only in server→NMI requests.
|
||||
- **Transport.** All gateway calls use HTTPS to `secure.nmi.com`.
|
||||
|
||||
## Gaps & recommended hardening
|
||||
|
||||
| # | Issue | Recommendation |
|
||||
|---|-------|----------------|
|
||||
| 1 | **Unauthenticated webhook.** `crystalclear_webhook` is `allow_guest=True` and creates Payment Entries from any POST whose `orderid` matches an invoice. | Require a shared secret / HMAC signature; verify before writing. Optionally allow-list source IPs. |
|
||||
| 2 | **Debug logging of gateway payloads.** `payments.py` writes request/response snippets via `frappe.log_error`. | Confirm no PAN/PII is ever logged; use a dedicated logger at an appropriate level; consider truncation/redaction and log retention limits. |
|
||||
| 3 | **Hard-coded tokenization key** in `sales_invoice.js`. | Move to a server-provided value / site config; makes key rotation and per-environment keys possible. |
|
||||
| 4 | **Hard-coded ledger account** `"ENB Bank Account - NIL"`. | Make company-aware via config or a Company-level custom field. |
|
||||
| 5 | **Permissions.** Payment endpoints are whitelisted to any logged-in user. | Add role checks (as `create_customer_full` does with `frappe.only_for`) and/or rate limiting. |
|
||||
| 6 | **`ignore_permissions=True`** on Payment Entry and Customer writes. | Acceptable for a system flow, but document the trust boundary and ensure the whitelisted entry points are themselves access-controlled. |
|
||||
|
||||
## Operational reminders
|
||||
|
||||
- Keep `enable_autopay_signup = 0` in production until vaulting is fully tested.
|
||||
- Never commit `site_config.json` or the NMI security key to version control.
|
||||
- Rotate the NMI security key and Collect.js key on any suspected exposure.
|
||||
Reference in New Issue
Block a user