movidas openspec a /docs
This commit is contained in:
parent
0ef0c9951c
commit
aae6b6096e
9 changed files with 486 additions and 0 deletions
|
|
@ -0,0 +1,61 @@
|
|||
## ADDED Requirements
|
||||
|
||||
### Requirement: Hardened Odoo configuration
|
||||
|
||||
Production `odoo.conf` SHALL set a strong `admin_passwd` (not the default `admin`), `list_db =
|
||||
False`, a `dbfilter` scoping databases per host, `proxy_mode = True`, `workers > 0`, request/time
|
||||
limits, `without_demo = True`, and a strong database password (not the literal `odoo`). The
|
||||
database manager SHALL NOT be reachable publicly.
|
||||
|
||||
#### Scenario: Database manager not exposed
|
||||
- **WHEN** an anonymous client requests `/web/database/manager` on production
|
||||
- **THEN** it is not served (blocked at the proxy and/or `list_db=False`)
|
||||
|
||||
#### Scenario: Real client IP reaches Odoo logs
|
||||
- **WHEN** a login fails behind the reverse proxy
|
||||
- **THEN** with `proxy_mode=True` the Odoo log records the real client IP (from `X-Forwarded-For`),
|
||||
not the proxy IP
|
||||
|
||||
### Requirement: Reverse proxy enforces TLS, rate limiting and security headers
|
||||
|
||||
The nginx/traefik layer SHALL terminate TLS with strong protocols/ciphers, apply `limit_req` to
|
||||
`/web/login`, `/web/session/authenticate`, `/jsonrpc` and `/xmlrpc`, and set security headers
|
||||
(HSTS, X-Frame-Options/CSP, X-Content-Type-Options, Referrer-Policy). The `session_id` cookie
|
||||
SHALL be `Secure`, `HttpOnly` and `SameSite`.
|
||||
|
||||
#### Scenario: Login rate limited
|
||||
- **WHEN** a client exceeds the configured request rate on `/web/login`
|
||||
- **THEN** the proxy returns 429 and further attempts are throttled
|
||||
|
||||
#### Scenario: Security headers present
|
||||
- **WHEN** a response is returned from production
|
||||
- **THEN** it includes HSTS, anti-clickjacking and content-type-options headers, and the session
|
||||
cookie carries Secure/HttpOnly/SameSite
|
||||
|
||||
### Requirement: Brute-force sources banned on web and API
|
||||
|
||||
fail2ban SHALL ban source IPs that exceed a failed-authentication threshold, covering both the web
|
||||
login route and the API authentication routes (`/web/session/authenticate`, `/xmlrpc/2/common`),
|
||||
using the real client IP.
|
||||
|
||||
#### Scenario: Repeated web login failures banned
|
||||
- **WHEN** a source exceeds the failed-login threshold on `/web/login`
|
||||
- **THEN** fail2ban bans that IP for the configured duration
|
||||
|
||||
#### Scenario: API auth brute force banned
|
||||
- **WHEN** a source brute-forces `/web/session/authenticate` or `/xmlrpc/2/common`
|
||||
- **THEN** the same fail2ban jail bans it (attacks via API do not bypass protection)
|
||||
|
||||
### Requirement: Secrets and database access hardened
|
||||
|
||||
Database and master secrets SHALL be strong and SHALL NOT be committed in plaintext in versioned
|
||||
files. The PostgreSQL port SHALL NOT be reachable from outside the host/network (firewalled), and
|
||||
the database user SHALL have least privilege.
|
||||
|
||||
#### Scenario: DB port not externally reachable
|
||||
- **WHEN** an external client attempts to connect to PostgreSQL (5432) on production
|
||||
- **THEN** the connection is refused/filtered by the firewall
|
||||
|
||||
#### Scenario: No plaintext secrets in repo
|
||||
- **WHEN** the repository is inspected
|
||||
- **THEN** production database/master passwords are not present in plaintext in versioned files
|
||||
Loading…
Add table
Add a link
Reference in a new issue