-
Notifications
You must be signed in to change notification settings - Fork 0
Security Model
OpenWP implements defense-in-depth security with multiple layers of protection.
Request
│
├── 1. WordPress Nonce / Bearer Token (authentication)
├── 2. Capability Check (authorization)
├── 3. Policy Engine (action-level permissions)
├── 4. Schema Validation (input sanitization)
├── 5. SQL Guard (query safety for db_query action)
├── 6. Rate Limiter (abuse prevention)
├── 7. Approval Queue (human-in-the-loop for risky actions)
└── 8. Pre-Action Backup (rollback capability)
The PolicyEngine evaluates every action execution:
-
Capability check - Verifies
current_user_can($capability)for the action - Action enabled - Checks per-action policy overrides (can disable individual actions)
-
Approval routing - Determines if the action needs human approval based on:
- Risk level settings (
medium_requires_approval,high_requires_approval,critical_requires_approval) - Per-action policy override (
require_approval)
- Risk level settings (
- Backup requirement - Auto-requires backup for mutating high/critical actions
- Typed confirmation - Critical actions require the user to type "APPROVE"
{
"wp_create_post": {
"enabled": true,
"require_approval": false
},
"wp_delete_plugin": {
"enabled": true,
"require_approval": true
}
}Validates raw SQL queries before execution via the db_query action:
-
Read-only:
SELECT,SHOW,DESCRIBE,EXPLAIN -
Mutating:
INSERT,UPDATE,DELETE,REPLACE,ALTER,DROP,TRUNCATE,CREATE,RENAME,OPTIMIZE,REPAIR,ANALYZE
The following SQL primitives are always blocked:
-
INTO OUTFILE- File write exploitation -
LOAD_FILE- File read exploitation -
INTO DUMPFILE- Binary file write -
BENCHMARK(- Timing attacks -
SLEEP(- Time-based injection -
INFORMATION_SCHEMA.FILES- File system enumeration
- Multi-statement queries (containing
;mid-query) are rejected - LIMIT extraction for read safety monitoring
- Unsupported statement types are rejected
Prevents abuse through configurable daily limits:
| Limit | Default | Scope |
|---|---|---|
max_actions_user_day |
50 | Per user per day |
max_actions_site_day |
500 | Site-wide per day |
max_tokens_user_day |
120,000 | Per user per day |
max_tokens_site_day |
1,200,000 | Site-wide per day |
min_seconds_between_runs |
5 | Per user cooldown |
Rate limit data is stored in the openwp_usage_daily table.
Encrypts sensitive data (API keys) for storage in the WordPress options table.
-
Sodium (
sodium_crypto_secretbox) - Preferred, available in PHP 7.2+ -
OpenSSL (
AES-256-CBC) - Fallback
The encryption key is derived from site-specific material:
SHA-256(wp_salt('auth') | DB_NAME | site_url())
sodium:base64(nonce + ciphertext)
openssl:base64(iv + ciphertext)
Manages encrypted storage and retrieval of LLM provider API keys:
- Keys are encrypted via
Encryption_Servicebefore storage - Masked keys are returned to the UI (showing only last 4 characters)
- Stored in
OPENWP_OPTION_PROVIDER_KEYSoption
Two custom capabilities granted to administrators on activation:
| Capability | Purpose |
|---|---|
openwp_run_agent |
Execute agent commands, access console |
openwp_manage_settings |
Manage plugin settings, memory |
Critical safety design: OpenWP never executes arbitrary PHP code. All actions must be pre-registered in the Action_Registry at boot time. The LLM can only select from the catalog of registered actions - it cannot invent new ones.
The Schema_Validator (inc/Utils/Schema_Validator.php) validates all action parameters against their registered JSON schema before execution. This prevents:
- Type mismatches
- Missing required fields
- Unexpected additional properties (when
additionalProperties: false)
OpenWP v0.1.4 | GitHub Repository | GPLv2+