Encryption at rest
OwnPay encrypts sensitive data before writing it to MySQL using AES-256-GCM with a per-installation key stored in theENCRYPTION_KEY environment variable.
What gets encrypted:
- Gateway API keys and credentials in
op_gateway_configs - Customer names, emails, and phone numbers in
op_customers - TOTP secrets for two-factor authentication
- Any plugin-stored secrets via the encryption helper
How it works:
- Each encryption operation generates a random 12-byte IV and produces a 16-byte auth tag
- The IV, auth tag, and ciphertext are stored together in a single base64-encoded string
- Decryption verifies the auth tag before returning plaintext, detecting tampering
Webhook signature verification
Every outbound webhook delivery is signed with HMAC-SHA256. The signature is sent in theX-OwnPay-Signature header using the format sha256={hex_digest}.
The signed payload is constructed as {timestamp}.{raw_body}, where timestamp is a Unix epoch value sent in the X-OwnPay-Timestamp header. This prevents replay attacks - you should reject webhooks older than 5 minutes.
CSRF protection
OwnPay generates a unique CSRF token per session usingSecurityHelpers::csrfToken(). The CsrfMiddleware enforces token validation on every POST, PUT, and DELETE request to web routes (not API routes, which use Bearer/JWT authentication instead).
The token is stored in an HTTP-only, SameSite=Lax cookie. Twig templates include it automatically in every form via the csrf_field() function. AJAX requests must read the token from the meta tag or cookie and include it in a custom header.
SQL injection prevention
Every database query in OwnPay uses parameterized statements through the PDO wrapper. No user input is ever concatenated into SQL strings. TheDatabase class does not expose a query() method that accepts raw SQL with interpolation.
When writing plugins, always use the provided repository methods or the
Database wrapper. The plugin sandbox will reject any code that attempts to construct raw PDO statements.XSS prevention
All output in Twig templates is auto-escaped by default. The|raw filter is only safe for content you control (like system-generated HTML). Never use |raw on user-submitted data, customer names, or gateway response values.
The Content Security Policy (CSP) middleware adds a per-request nonce to all inline scripts and styles. Any inline script without the correct nonce is blocked by the browser, providing defense-in-depth even if an XSS vector is discovered.
Rate limiting
OwnPay implements a sliding window rate limiter using Redis (or the file system as fallback). Rate limits are enforced per IP address on sensitive endpoints and per API key on authenticated endpoints. See the Rate Limiting page for the full reference on tiers, headers, and configuration.Session security
Sessions are stored in Redis when available, falling back to the file system. Key security properties:- HTTP-only cookies - session IDs are not accessible to JavaScript
- SameSite=Lax - prevents cross-site request forgery via cookies
- IP binding - the session is invalidated if the client IP changes
- Idle timeout - sessions expire after a configurable period of inactivity
- Fingerprinting - optional browser fingerprint validation on each request
Password hashing
OwnPay uses Argon2id as the default password hashing algorithm, with bcrypt as a legacy fallback for upgraded installations. Passwords are never stored in plaintext or reversible form. For API keys, OwnPay generates a 192-bit random string prefixed withop_live_ or op_test_. The plain key is shown only once at creation time. At rest, the key is stored as a SHA-256 hash and compared using hash_equals() to prevent timing attacks.
File upload security
Uploaded files (logos, favicons, dispute evidence) are validated before storage:- File extension whitelist (images only for logos/favicons)
- MIME type verification against the file content, not just the extension
- Random filenames prevent path prediction and directory traversal
- Files are stored outside the web root when possible, served through a controller
Security headers
TheSecurityHeadersMiddleware adds the following headers to every response:
Checkout Content Security Policy
Checkout pages use a stricter CSP than the admin panel. The nonce-based policy allows scripts only from OwnPay’s own domain and the gateway provider domains configured for the brand. This prevents a compromised admin session from injecting malicious scripts into customer-facing checkout pages. Gateway-specific CSP origins are automatically added to the policy when a gateway is enabled for a brand, so no manual configuration is needed.Audit logging
Every significant action in OwnPay is recorded in theop_audit_log table with:
- The actor (user ID or system)
- The entity type and ID affected
- The action performed (create, update, delete, login, etc.)
- Old and new values for updates
- The client IP address
- A cryptographic signature to detect post-creation tampering
PII such as customer emails and phone numbers is automatically masked in audit log output using the
LogSanitizer.Compliance considerations
PCI DSS
OwnPay operates under a gateway delegation model for PCI compliance. Credit card numbers, CVVs, and payment card data are never stored on your server. Instead, payment data is collected and tokenized directly by the upstream gateway (Stripe, Adyen, etc.) via their own PCI-certified iframes or redirect flows. This means OwnPay itself typically falls under PCI DSS SAQ-A (the simplest self-assessment questionnaire), since no cardholder data touches your infrastructure. However, you should consult with a Qualified Security Assessor for your specific deployment.GDPR
OwnPay supports GDPR compliance through:- Data minimization - only necessary PII is collected at checkout
- Encryption at rest - customer data encrypted with AES-256-GCM
- Hash-based lookup - email and phone stored as hashes; decryption only needed for display
- Data export - customer data can be exported via CSV from the admin panel
- Data deletion - customer records and associated transactions can be deleted (ledger entries are anonymized to preserve accounting integrity)
- Audit trail - all access to customer data is logged and reviewable
Related Pages
- Two-Factor Authentication - Enable TOTP for staff accounts
- API Keys - Generate, scope, and revoke API keys
- Backup and Export - Secure backup procedures
- Rate Limiting - Full rate limit tiers and configuration