CVE-2023-39345
Executive Summary
CVE-2023-39345 is an authorization bypass vulnerability in Strapi, an open-source headless CMS, affecting all versions prior to 4.13.1. The flaw resides in the user registration endpoint, where write access to fields marked as "private" is not properly restricted, allowing authenticated malicious users to modify their own user records in unintended ways. With a CVSS score of 7.6, this vulnerability poses a high risk to organizations using vulnerable Strapi deployments, particularly those relying on field-level privacy controls for security segregation.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Technical Analysis
Vulnerability Mechanism
Strapi's user registration endpoint processes profile updates and self-service modifications. The platform supports a field-level permission system where certain fields within a user schema can be designated as "private" — these fields are intended to be read-only to the user themselves, viewable or editable only by administrators or through server-side logic.
The vulnerability arises from an incomplete access control check in versions prior to 4.13.1. When a user submits a registration or profile-update request, the server fails to filter out or reject write attempts to fields marked as private. Instead of enforcing the privacy designation at the validation/sanitization layer, the vulnerable code path permits the submitted values to be persisted to the database regardless of the field's privacy flag.
This is fundamentally an Incorrect Default Permissions issue (CWE-276): the system's default behavior is to allow writes to fields rather than denying them unless explicitly permitted. The privacy flag is applied only at the read/serialization layer (e.g., hiding fields from API responses) but not consistently enforced at the write/validation layer in the registration flow.
Attack Surface
- Affected Component: User registration API endpoint
- Attack Vector: Network-based; the endpoint is publicly exposed by default in most Strapi deployments
- Authentication: Requires a valid user account (authenticated attacker)
- Access Level: User-level privileges are sufficient to trigger the vulnerability — no admin role required
Technical Context
The registration endpoint in Strapi's user-permission plugin handles incoming requests to create or update user profiles. The vulnerable code path accepts a JSON payload containing user attributes and directly maps them to the database schema. The missing check allows fields with the private attribute to be included in the write operation, thereby overwriting their current values.
This is not a classic injection vulnerability (SQLi, XSS, etc.); it is a logic/authorization flaw where the application fails to distinguish between fields the user may self-manage and fields reserved for server-side or administrative control. The root cause is insufficient input validation at the authorization layer — a whitelist of editable fields is either absent or incorrectly configured for the registration endpoint.
Exploitation Scenarios
Note: No public PoC or exploit code is available at the time of this report. The attack chain below is inferred from the vulnerability class and the NVD description.
Step 1: Reconnaissance / Target Identification
An attacker first identifies Strapi-powered applications. This can be accomplished via internet-wide scanning using search queries such as:
http.title:"Strapi"(Shodan/Censys)Strapi CMSbanners in HTTP headers- Default Strapi API paths commonly exposed (e.g., the admin panel or user registration endpoint)
The attacker then enumerates the registration endpoint and confirms it is active and accepting requests.
Step 2: Triggering the Flaw
The attacker registers a normal account (or logs in with an existing account they control) to obtain valid user credentials. They then craft a request to the user registration endpoint with a payload that includes fields marked as private in the target Strapi configuration. Examples of such fields would be elevated privilege flags, account status indicators, or other server-managed attributes (exact field names are unknown without examining the target's schema).
The request is sent with the attacker's session token or API key — the attack operates at the application layer and does not require bypassing network-level controls.
Step 3: Payload / Execution Method
At the vulnerability-class level, the attack is a mass assignment / parameter pollution attack. The attacker submits all writable fields they can discover (through schema enumeration or API documentation) plus one or more private fields. Because the server fails to reject or strip the private fields, they are persisted to the database.
Example conceptual payload (field names are illustrative only, not taken from the CVE description):
{
"username": "attacker",
"email": "attacker@example.com",
"password": "newpassword123",
"isAdmin": true,
"role": "super_admin"
}
Step 4: Post-Exploitation Impact
Depending on which private fields are overwritten, the attacker may:
- Escalate their own privileges to administrative levels
- Modify account status (e.g., enable/disable restrictions)
- Alter trust flags or multi-factor authentication settings
- Gain access to restricted content or functionality reserved for higher-privilege roles
If privilege escalation is successful, the attacker gains full administrative control over the CMS, which can lead to arbitrary code execution, data exfiltration, defacement, or lateral movement within the hosting environment.
Impact Assessment
Business Impact
| Dimension | Assessment |
|---|---|
| Confidentiality | High — Successful exploitation can expose administrative interfaces and sensitive user data |
| Integrity | High — Attackers can modify access controls, privilege flags, and server-managed fields |
| Availability | Moderate — Depending on modified fields, services may become destabilized or locked out |
| Compliance | GDPR, HIPAA, or PCI-DSS violations if CMS manages regulated user data |
CVSS Rationale (Score: 7.6)
The high CVSS score reflects the combination of:
- Network attack vector (AV:N) — remotely exploitable
- High attack complexity (AC:H) — requires knowledge of the target's field schema and a valid user account
- Low privileges required (PR:L) — any registered user can exploit the flaw
- No user interaction (UI:N) — attack executes automatically
- Unchanged scope (S:U) — the compromised component is the CMS itself
- High impact on Confidentiality and Integrity — privilege escalation and data manipulation are likely outcomes
- High impact on Availability — if administrative accounts are altered, service disruption is possible
Affected Systems
- All Strapi instances running versions below 4.13.1
- Deployments utilizing custom user schemas with field-level privacy settings
- Organizations hosting Strapi in public cloud environments or on the open internet
Blast Radius
The vulnerability affects the identity and access management layer of the CMS. Since Strapi often serves as the backend for mobile apps, SPAs, and customer-facing portals, a compromise of user records can cascade to all downstream applications that rely on Strapi's authentication and authorization services.
Detection Guidance
Sigma Rule
title: Strapi User Registration - Mass Assignment Attempt
id: 0f7c9a1e-3d5b-4f2a-9d8e-2c4b6a8f0e1d
status: experimental
description: Detects attempts to modify private fields via Strapi user registration endpoint
date: 2024/01/15
author: Valtersit Threat Intelligence
logsource:
category: web
product: nginx
service: http
detection:
selection:
http.url|contains:
- "/api/auth/local/register"
http.method: POST
private_field_indicators:
http.request_body|contains|all:
- "role"
- "permissions"
- "isActive"
- "isAdmin"
- "blocked"
condition: selection and private_field_indicators
fields:
- client_ip
- http.user_agent
- http.request_body
- http.response.status_code
falsepositives:
- Legitimate administrator operations through other endpoints
- Custom plugins modifying role assignments
level: high
YARA Rule
rule Strapi_Private_Field_Mass_Assignment
{
meta:
author = "Valtersit Threat Intelligence"
description = "Detects HTTP payloads attempting to modify private fields in Strapi registration"
cve = "CVE-2023-39345"
date = "2024-01-15"
score = 75
strings:
$register_path = "auth/local/register" ascii wide
$priv_field1 = "\"role\"" ascii wide nocase
$priv_field2 = "\"isAdmin\"" ascii wide nocase
$priv_field3 = "\"blocked\"" ascii wide nocase
$priv_field4 = "\"confirmed\"" ascii wide nocase
$priv_field5 = "\"permissions\"" ascii wide nocase
$priv_field6 = "isActive" ascii wide nocase
$json_start = "{ \"username\"" ascii wide
condition:
uint16(0) == 0x0D0A and
$register_path in (0..filesize) and
filesize < 20KB and
1 of ($priv_field*) and
$json_start
}
Suricata IDS Rule
alert http any any -> $EXTERNAL_NET any (
msg:"CVE-2023-39345 - Strapi Registration Mass Assignment Attempt";
flow:to_server,established;
http.method; content:"POST";
http.uri; content:"/api/auth/local/register"; nocase;
http.request_body; content:"role"; nocase; http.request_body; content:"isAdmin"; nocase; within:200;
http.request_body; content:"confirmed"; nocase; http.request_body; content:"blocked"; nocase; within:200;
sid:2023393450;
rev:1;
metadata:attack_target Web_Server, created_at 2024_01_15, deployment Perimeter, signature_severity Critical, updated_at 2024_01_15;
reference:cve,2023-39345;
classtype:attempted-admin;
)
Elastic Detection
any where
process.name == "node" and
event.action in ("exec", "spawn") and
network.protocol == "http" and
url.path == "/api/auth/local/register" and
http.request.method == "POST" and
/* Look for private field names in request body */
(wildcard(http.request.body.content, "*\"role\"*") or
wildcard(http.request.body.content, "*\"isAdmin\"*") or
wildcard(http.request.body.content, "*\"blocked\"*") or
wildcard(http.request.body.content, "*\"confirmed\"*") or
wildcard(http.request.body.content, "*\"permissions\"*")) and
not user.id in ("elastic", "kibana", "logstash")
Splunk SPL Query
index=web sourcetype=access_combined
| where method="POST"
| where uri="/api/auth/local/register"
| rex field=_raw "tickets=\"(?<request_body>[^\"]*)\""
| eval has_role=if(like(request_body, "%\"role\"%"), 1, 0)
| eval has_admin=if(like(request_body, "%\"isAdmin\"%"), 1, 0)
| eval has_blocked=if(like(request_body, "%\"blocked\"%"), 1, 0)
| eval has_confirmed=if(like(request_body, "%\"confirmed\"%"), 1, 0)
| eval private_field_count = has_role + has_admin + has_blocked + has_confirmed
| where private_field_count >= 2
| table _time, src_ip, user_agent, uri, request_body, response_status
| sort -_time
| eval algorithm = "CVE-2023-39345 Mass Assignment Detection"
Wazuh OSSEC Rule
<group name="strapi,cve-2023-39345,">
<rule id="100345" level="15">
<decoded_as>json</decoded_as>
<match>auth/local/register</match>
<regex>\"role\"</regex>
<regex>\"isAdmin\"</regex>
<description>CVE-2023-39345: Strapi registration mass assignment - role & admin fields detected</description>
<group>attack,web,access_control,</group>
<mitre>
<id>T1190</id>
</mitre>
<info type="cve">2023-39345</info>
</rule>
<rule id="100346" level="12">
<decoded_as>json</decoded_as>
<match>auth/local/register</match>
<regex>\"blocked\"</regex>
<regex>\"confirmed\"</regex>
<description>CVE-2023-39345: Strapi registration mass assignment - account state fields detected</description>
<group>attack,web,access_control,</group>
<mitre>
<id>T1190</id>
</mitre>
<info type="cve">2023-39345</info>
</rule>
</group>
Mitigation & Patch Guidance
Patch Confidence Assessment
0/4 — UNPATCHED: Despite the vendor's advisory indicating a fix exists in version 4.13.1, no patch evidence has been obtained from any tracked source. This discrepancy is noted. The confirmed fix version is 4.13.1 per the NVD description, but exploitation status and patch availability should be verified against the Strapi advisory.
Immediate Mitigations (Pre-Patch)
- Upgrade immediately to Strapi 4.13.1 or later — this is the only confirmed remediation
- Restrict network access to the user registration endpoint:
- Use Web Application Firewall (WAF) rules to block direct access to
/api/auth/local/registerfrom untrusted IPs - Place the endpoint behind a reverse proxy with access control lists (ACLs)
- Use Web Application Firewall (WAF) rules to block direct access to
- Apply virtual patching at the WAF/API gateway layer:
- Block request bodies containing private field names such as
role,isAdmin,blocked,permissionsin the registration endpoint
- Block request bodies containing private field names such as
- Temporarily disable user self-registration if business workflows permit, reverting to admin-only account creation
Patch / Upgrade Steps
- Backup the current database and file system
- Review custom plugins and extensions for compatibility with newer Strapi versions
- Upgrade Strapi using the official migration guide:
or via Docker:npm install strapi@4.13.1docker pull strapi/strapi:4.13.1 - Run database migrations as provided by the upgrade guide
- Verify the registration endpoint behavior after upgrade with a test account
- Monitor logs for residual exploitation attempts
Long-Term Hardening
- Enforce least-privilege field access — ensure all user-writable fields are explicitly whitelisted in project configuration
- Audit user schemas — remove the
privateflag from fields that genuinely need user write access, or add server-side validation to prevent client-supplied values - Implement server-side field whitelist — configure Strapi's sanitization layer to strip unknown/untrusted fields before persistence
- Enable comprehensive logging for all user self-service endpoints
- Subscribe to Strapi security advisories and monitor the NVD for new CVEs
- Conduct periodic penetration tests focused on API authorization and mass assignment vulnerabilities
References
- NVD Entry — CVE-2023-39345: https://nvd.nist.gov/vuln/detail/CVE-2023-39345
- Strapi Security Advisory — https://github.com/strapi/strapi/security/advisories (refer to version 4.13.1 release notes)
- Strapi GitHub Releases — https://github.com/strapi/strapi/releases/tag/v4.13.1 (fix version confirmation)
- CVE.org Record — https://cve.org/CVERecord?id=CVE-2023-39345
- Exploit-DB / Metasploit — No public exploit available; monitor for future researcher publications
Threat Actor Activity: As of this report, there is no evidence of active exploitation in the wild or known threat actor campaigns targeting this specific CVE. EPSS score of 0.00496 (40th percentile) suggests low but non-zero exploitation probability. Organizations should remain vigilant, as mass assignment vulnerabilities in CMS platforms are frequently weaponized once public PoCs emerge.