OWASP Top 10 (2021) Mapping
The following table maps each OWASP Top 10 2021 category to the controls implemented in Afunana.
| OWASP ID | Category | Afunana Controls |
|---|---|---|
| A01 | Broken Access Control | RBAC with 4 roles (admin, user, viewer, qa), collection-based isolation, JWT authentication, 404 returned for unauthorized access (prevents enumeration) |
| A02 | Cryptographic Failures | TLS 1.2+ enforced, AES-256 TDE at rest, bcrypt password hashing, SHA-256 hash chain for audit integrity, Docker secrets for credential storage |
| A03 | Injection | Parameterized SQL via pyodbc (no string concatenation), Pydantic input validation on all API endpoints, React JSX auto-escaping prevents XSS |
| A04 | Insecure Design | Defense-in-depth architecture, least-privilege DB user, non-root containers, immutable audit log with DB trigger protection |
| A05 | Security Misconfiguration | Auto-TLS via Caddy, security headers enforced on all responses, Docker secrets (not env vars), no default credentials (generated at install) |
| A06 | Vulnerable Components | pip audit + npm audit on every deploy, minimal UBI 9 base image, automated dependency scanning |
| A07 | Auth Failures | bcrypt 12 rounds, account lockout after 5 failures, idle/absolute session timeouts, token revocation on logout/password change, SSO/OIDC support |
| A08 | Software/Data Integrity | SHA-256 hash chain on audit log, DB trigger prevents UPDATE/DELETE on event log, daily integrity verification checks |
| A09 | Security Logging/Monitoring | Immutable audit log, SIEM forwarding (CEF/JSON), health endpoint with auto-restart, compliance scheduler for periodic checks |
| A10 | SSRF | No user-controlled URL fetching in the application, AS/400 connections are admin-configured only (host/port set via Admin panel) |
Authentication & Session Management
Afunana implements a layered authentication model designed to pass AppScan checks for session management, credential handling, and brute-force protection.
Credential Storage
- Password hashing: bcrypt with 12 salt rounds (72-byte input limit per bcrypt specification)
- Password complexity: Minimum 8 characters with uppercase, lowercase, digit, and special character requirements
- No default credentials: Admin password set during installation; JWT secret and DB passwords auto-generated
Session Controls
| Control | Implementation |
|---|---|
| Token format | JWT (HS256) with sub, role, jti, iat, exp, session_start claims |
| Idle timeout | 15 minutes (configurable via SESSION_IDLE_TIMEOUT_MINUTES) |
| Absolute timeout | 8 hours (configurable via SESSION_ABSOLUTE_TIMEOUT_HOURS) |
| Token revocation | Logout revokes single token; password change/admin action revokes all user tokens |
| Account lockout | 5 failed attempts triggers 15-minute lockout (database-persisted) |
SSO / OIDC
OIDC/OAuth 2.0 integration supports Azure AD, Google Workspace, Okta, and other compliant providers. New users are auto-provisioned on first SSO login (configurable). SSO sessions respect the same idle and absolute timeouts as local authentication.
Input Validation & Injection Prevention
All user input is validated and sanitized before processing, addressing SQL injection, XSS, and other injection vectors flagged by AppScan.
SQL Injection Prevention
- Parameterized queries: All database access uses pyodbc parameterized statements — no string concatenation or formatting in SQL
- ORM-free by design: Direct parameterized SQL provides full visibility into query construction
- Least-privilege DB user: Application connects with
db_datareader/db_datawriterpermissions only; no DDL in normal operation
XSS Prevention
- React JSX auto-escaping: All rendered content is automatically escaped by React’s JSX engine
- Content Security Policy: CSP header restricts script sources to
'self' - No
dangerouslySetInnerHTML: Application avoids raw HTML injection in React components
API Input Validation
- Pydantic models: All API request bodies are validated against typed Pydantic schemas
- Path parameter validation: Collection names, user IDs, and resource identifiers are validated before use
- Rate limiting: Auth endpoints rate-limited (10/min login, 5/min signup, 5/min password reset)
Security Headers & Transport Security
Caddy applies the following security headers on all HTTP responses. These are verified on every deploy and satisfy common AppScan header checks.
| Header | Value | Purpose |
|---|---|---|
Strict-Transport-Security | max-age=63072000; includeSubDomains; preload | Enforce HTTPS for 2 years, eligible for HSTS preload list |
Content-Security-Policy | default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com | Restrict resource loading origins |
X-Frame-Options | SAMEORIGIN | Prevent clickjacking via iframe embedding |
X-Content-Type-Options | nosniff | Prevent MIME-type sniffing |
Referrer-Policy | strict-origin-when-cross-origin | Limit referrer information leakage |
Permissions-Policy | geolocation=(), microphone=(), camera=() | Disable unnecessary browser APIs |
Transport Layer Security
- TLS 1.2+ enforced: Caddy automatically negotiates TLS 1.2 or 1.3; older protocols are rejected
- Automatic certificate provisioning: Let’s Encrypt certificates are obtained and renewed automatically by Caddy
- HTTP-to-HTTPS redirect: All HTTP requests are redirected to HTTPS (301) when a domain is configured
- HSTS preload eligible: Max-age of 2 years with
includeSubDomainsandpreloaddirectives
Cryptographic Controls
| Layer | Algorithm | Key Management |
|---|---|---|
| Data in transit | TLS 1.2+ (Caddy auto-negotiation) | Let’s Encrypt certificates, auto-renewed |
| Data at rest | AES-256 via SQL Server TDE | Database-managed encryption keys |
| Passwords | bcrypt (12 rounds, per-user salt) | Salt generated per password; no global key |
| Audit integrity | SHA-256 hash chain | Each event hash includes the previous event’s hash |
| Password reset tokens | 256-bit random token, SHA-256 hashed for storage | Single-use, 60-minute expiry |
| Secrets storage | Docker secrets (file-based) | Secrets mounted as files at /run/secrets/, not env vars |
Access Control
Afunana enforces access control at multiple layers to satisfy AppScan checks for authorization bypass, privilege escalation, and data leakage.
Role-Based Access Control
| Role | Permissions |
|---|---|
admin | Full access: user management, collections, configuration, builds, audit, deploy |
user | Access assigned collections, view documentation, use chat |
viewer | Read-only access to assigned collections |
qa | Read-only collection access, build triggers, project management access |
Collection-Based Isolation
- Users are assigned to specific collections via the
user_collectionstable - Every API request validates collection access before returning data
- Unauthorized access returns 404 (not 403) to prevent resource enumeration
Infrastructure Access Control
- Non-root containers: Application container runs as a non-root user
- Least-privilege DB user: Application DB user has only
db_datareader/db_datawriterpermissions - No default credentials: All passwords and secrets are generated during installation
Static Analysis & Dependency Scanning
Automated security scanning runs on every deploy cycle, catching vulnerabilities before they reach production.
Static Analysis (SAST)
| Tool | Scope | Trigger |
|---|---|---|
| Bandit | Python backend code | Every deploy |
| ESLint (security rules) | React frontend code | Build-time |
Dependency Scanning (SCA)
| Tool | Scope | Trigger |
|---|---|---|
pip audit | Python dependencies (requirements.txt) | Every deploy |
npm audit | Node.js dependencies (package-lock.json) | Every deploy |
Container Security
- Minimal base image: UBI 9 (Red Hat Universal Base Image) — minimal attack surface
- Non-root execution: Container process runs as an unprivileged user
- No unnecessary packages: Only runtime dependencies are included in the final image
Remediation Status
Summary of security controls and their implementation status across OWASP categories.
| Category | Control | Status |
|---|---|---|
| SQL Injection | Parameterized queries (pyodbc) | Implemented |
| XSS | React auto-escaping + CSP header | Implemented |
| Broken Authentication | bcrypt, lockout, timeouts, revocation | Implemented |
| Broken Access Control | RBAC, collection isolation, 404 masking | Implemented |
| Security Misconfiguration | Auto-TLS, security headers, Docker secrets | Implemented |
| Cryptographic Failures | TLS 1.2+, AES-256 TDE, bcrypt | Implemented |
| Vulnerable Components | pip audit + npm audit on every deploy | Implemented |
| Insecure Design | Defense-in-depth, least privilege, immutable audit | Implemented |
| Data Integrity | SHA-256 hash chain, DB trigger protection | Implemented |
| Logging & Monitoring | Immutable audit log, SIEM forwarding | Implemented |
| SSRF | No user-controlled URL fetching | Implemented |
| SSO / MFA | OIDC integration (MFA via IdP) | Implemented |
For the full security architecture, compliance mappings, and evidence artifacts, see the Security & Compliance page.