On December 29th, 2022, the security researcher reported to us an SSTI (server-side template injection) vulnerability impacting our users-permission plugin’s email template system. Please note the users-permissions plugin is installed by default. This SSTI vulnerability made it possible to modify the email template to execute malicious code via RCE (remote code execution). This vulnerability’s scope was originally believed to be exploitable only if a malicious actor had access to the Strapi Admin Panel. On January 4th 2022, a CVE was submitted in a draft state with the following ID: CVE-2023-22621.
While we won’t go into the deep details of this vulnerability (please see the related blog post by the security researcher who reported the vulnerability to us) we did want to communicate on the IoC’s (indicators of compromise) so that our users are able to review their application logs to detect if they were impacted. Do note that this vulnerability impacts all known Strapi v3 and Strapi v4 versions prior to v4.5.6. If you have not already upgraded beyond Strapi v4.5.6 we do urge you to do so as quickly as possible (we strongly advise upgrading beyond v4.8.0 where other security vulnerabilities were patched). If you are unable to upgrade we have released several patch-package patches for this particular vulnerability.
Using just the request log files, the only IoC to search for is a PUT
request to URL path /users-permissions/email-templates
. This IoC only indicates that a Strapi email template was modified on your server and by itself does not indicate if your Strapi server has been compromised. If this IoC is detected, you will need to manually review your email templates on your Strapi server and backups of your database to see if any of the templates contain a lodash
template delimiter (eg. <%STUFF HERE%>
) that contains suspicious JavaScript code. Generally speaking these templates should look like the following, you may have minor adjustments but any unrecognized code should be considered suspicious.
Reset Password Template:
1<p>We heard that you lost your password. Sorry about that!</p>
2
3<p>But don’t worry! You can use the following link to reset your password:</p>
4<p><%= URL %>?code=<%= TOKEN %></p>
5
6<p>Thanks.</p>
Email Confirmation Template:
1<p>Thank you for registering!</p>
2
3<p>You have to confirm your email address. Please click on the link below.</p>
4
5<p><%= URL %>?confirmation=<%= CODE %></p>
6
7<p>Thanks.</p>
Specifically you should look for odd code contained within the <%STUFF HERE%>
blocks as this is what is used to bypass the lodash templating system. If you find any code that is not a variable name, or a variable name that is not defined in the template you are most likely impacted and should take immediate steps to confirm there are no malicious applications running on your servers.
Time | Event |
---|---|
2022/12/30 02:40 AM UTC | Report of the vulnerability received by the Strapi security team. |
2022/12/30 02:57 AM UTC | Sent first response acknowledging the report and began testing reproduction. |
2022/12/30 02:12 PM UTC | Confirmation sent that we were able to successfully reproduce the vulnerability and provided an estimated 1 week timeline to patch the vulnerability due to the holiday period. |
2023/01/02 02:39 AM UTC | Security Researcher sent request to Mitre to reserve a CVE ID for this vulnerability. |
2023/01/03 08:00 PM UTC | Strapi team developed a fix for this vulnerability and released a nightly build for testing the patch. |
2023/01/05 12:09 AM UTC | Mitre reserved CVE ID CVE-2023-22621 for this vulnerability. |
2023/01/08 08:13 AM UTC | Security researcher identified a minor issue with the patch. |
2023/01/10 10:00 AM UTC | Strapi team fixed the minor issue with the patch. |
2023/01/11 04:00 PM UTC | Strapi released version 4.5.6 with the patch and announced a security warning for previous versions. |
2023/01/18 08:05 AM UTC | We were informed of a method of exploiting CVE-2023-22894 to hijack admin accounts, that enables this vulnerability being exploited as an unauthenticated user. |
2023/01/19 03:08 PM UTC | Strapi and the security researcher both decided to delay the public disclosure of this vulnerability until CVE-2023-22894 has been patched. |
2023/04/17 09:00 AM UTC | Released the full disclosure of the vulnerability. |
On January 1st, 2023, the security researcher reported to us an authentication bypass specifically for the AWS Cognito authentication provider for the users-permissions plugin. This vulnerability made it possible for any user to authenticate against a Strapi application using this authentication provider by spoofing the JWT token using a valid victims email address as the contents of the JWT were not properly verified against AWS. This vulnerability only impacted the users-permissions plugin and not Strapi Enterprise's SSO feature as the two systems use entirely different authentication provider packages (users-permissions uses Grant/Purest whereas the Admin Panel uses Passport.js).
While we won’t go into the deep details of this vulnerability (please see the related blog post by the security researcher who reported the vulnerability to us) we did want to communicate on the IoC’s (indicators of compromise) so that our users are able to review their application logs to detect if they were impacted. Do note that this vulnerability impacts all known Strapi v3 and Strapi v4 versions prior to v4.6.0. If you have not already upgraded beyond Strapi v4.6.0 we do urge you to do so as quickly as possible (we strongly advise upgrading beyond v4.8.0 where other security vulnerabilities were patched). Again please note that if you do not currently use the AWS Cognito authentication provider you are not impacted by this vulnerability.
Reviewing of application logs is recommended to detect any suspicious activity. Running the following regex pattern will extract all ID tokens sent to /api/auth/cognito/callback
1/\/api\/auth\/cognito\/callback\?[\s\S]*id_token=\s*([\S]*)/
Once you have a list of the ID tokens, you will need to verify each token using the public key file for your AWS Cognito user pool that you can download from https://cognito-idp.{region}.amazonaws.com/{userPoolId}/.well-known/jwks.json
. If there are any JWT tokens that cannot be verified using the correct public key, then you need to inspect the JWT body and see if it contains the email
and cognito:username
claims (example below).
1{
2 "cognito:username": "auth-bypass-example",
3 "email": "user@example.com"
4}
If there are any JWTs that have this body, verify when the account with the email address was created. If the account was created earlier than the request to /api/auth/cognito/callback
with the invalid JWT token, then you need to contact the user to inform them their account has been breached!
After upgrading to Strapi v4.6.0 or greater you will need to reconfigure your AWS Cognito provider to include the JWKS URL for it to work properly. If you do not reconfigure your provider you will receive an error message when attempting to login.
Time | Event |
---|---|
2023/01/01 09:14 AM UTC | Report of the vulnerability received by the Strapi security team. |
2023/01/01 08:35 PM UTC | Sent first response acknowledging the report and began testing reproduction. |
2023/01/04 10:53 AM UTC | Confirmation sent that we were able to successfully reproduce the vulnerability. |
2023/01/09 01:06 AM UTC | Mitre reserved CVE ID CVE-2023-22893 for this vulnerability. |
2023/01/09 04:49 PM UTC | The Strapi team developed a fix for this vulnerability and released a nightly build for testing the patch. |
2023/01/10 12:19 PM UTC | From a static analysis, the security researcher reported to Strapi that the fix still had an authentication bypass vulnerability by modifying the iss claim. |
2023/01/11 11:57 AM UTC | The Strapi team developed an additional patch for the vulnerability by adding a configurable JWKS url. |
2023/01/19 03:08 PM UTC | Strapi and the security researcher both decided to delay the public disclosure of this vulnerability until CVE-2023-22894 has been patched. |
2023/01/25 08:21 PM UTC | Strapi released version 4.6.0 that patches this vulnerability. |
2023/04/17 09:00 AM UTC | Released the full disclosure of the vulnerability. |
The exploitation of CVE-2023-22894 is easily detectable, since the payload is within the GET parameters and are normally included in request logs. The following regex pattern will extract requests that are exploiting this vulnerability to leak user's email, password and password reset token columns.
1/(\[|%5B)\s*(email|password|reset_password_token|resetPasswordToken)\s*(\]|%5D)/
You can search log files for this IoC by using the following grep
command.
grep -iE '(\[|%5B)\s*(email|password|reset_password_token|resetPasswordToken)\s*(\]|%5D)' $PATH_TO_LOG_FILE
If the above regex pattern matches any lines in your log files, take extra precaution to look out for multiple requests that include password
, reset_password_token
or resetPasswordToken
. This would indicate that an attacker has leaked the password hashes and reset tokens on your Strapi server and you need to immediately start an incident response!
Time | Event |
---|---|
2023/01/03 01:26 PM UTC | Report of the vulnerability received by the Strapi security team as Medium severity since the first vector was only accessible by Strapi administrators. |
2023/01/03 07:03 PM UTC | Sent first response acknowledging the report and began testing reproduction. |
2023/01/18 08:05 AM UTC | The security researcher discovered and notified Strapi that unauthenticated users could exploit this vulnerability and escalated the severity from Medium to Critical. However, at the time it was believed that an attacker can exploit under certain conditions. |
2023/01/21 10:26 AM UTC | The security researcher discovered a method to exploit this vulnerability as an unauthenticated user on all Strapi servers. The security researcher also sent Strapi a POC that would achieve Unauthenticated Remote Code Execution on all Strapi <=4.5.5 servers by chaining CVE-2023-22894 and CVE-2023-22621 together. |
2023/02/23 02:31 PM UTC | The Strapi team developed a fix for this vulnerability and released a nightly build for testing the patch. |
2023/03/05 02:51 AM UTC | The security researcher confirmed Strapi's patch fixed this vulnerability. |
2023/03/15 03:39 PM UTC | Strapi released version 4.8.0 that patches this vulnerability. |
2023/04/17 09:00 AM UTC | Released the full disclosure of the vulnerability. |
Thanks to the diligent work of the security researcher it was made apparent that it was possible to combine both CVE-2023-22621 and CVE-2023-22894 which combined allow for an unauthenticated RCE on all Strapi <=4.5.5 servers. By exploiting and hijacking a super admin account via the admin panel and using that account to modify the users-permissions template it would be possible to execute arbitrary code on the server.
Exploiting CVE-2023-22894
Exploiting CVE-2023-22621
We on the Strapi security team wanted to give a massive shout out to the security researcher GhostCcamm. Never in Strapi's history have we had a security researcher go above and beyond to help us improve the security of our product. We are very thankful for their work and dedication, the amount of detail they placed in their PoCs was simply outstanding and allowed us to quickly verify and patch the vulnerabilities. We simply cannot thank them enough for their work and for transparency; Strapi does not have a bug bounty program (for several reasons, largely because it tends to attract very mundane and invalid security reports) but in this case we did want to reward GhostCcamm for their work and did offer them a monetary reward.
For additional information about each of the vulnerabilities from the security researcher's perspective, please see their extremely detailed blog post, additionally below are their social links.
We cannot thank GhostCcamm enough and look forward to continuing to work with them in the future. Their patience and constant communication throughout the process was simply outstanding and we sincerely hope that others will follow your example.
We at Strapi do believe in responsible disclosure, in the case of these vulnerabilities we have worked with the security researcher to ensure that the vulnerabilities were patched before the full disclosure of the vulnerabilities. Once a vulnerability is patched, we added a notice to our release notes to inform users there was a security vulnerability but initially wanted to delay detailed disclosure for a few weeks to give time for users to upgrade before release of the full disclosure. As an additional step we did immediately notify our customers via several emails beforehand to ensure they were aware of the vulnerabilities and to upgrade their Strapi servers.
We do believe that delaying the detailed disclosure in this case was important to ensure that users had the time required to upgrade their Strapi servers before making the details of each vulnerability public and thus placing that information in the hands of bad actors. We also believe that the security researcher was very professional and responsible in their handling of the vulnerabilities and we are very thankful for their work in helping us to improve the security of Strapi.
We urge anyone who believes they have discovered a security vulnerability to assist us in responsibly disclosing the vulnerability to us by emailing security@strapi.io.
Thanks,
The Strapi Security Team