This blog post is about the security vulnerability in Gravity Forms. If you’re a Gravity Forms user, please update the plugin to at least version 2.7.4.
Patchstack Developer and Business plan users are protected from the vulnerability. You can also sign up for the Patchstack Community plan to be notified about vulnerabilities as soon as they become disclosed.
For plugin developers, we have security audit services and Threat Intelligence Feed API for hosting companies.
About the Gravity Forms WordPress plugin
The plugin Gravity Forms (versions 2.7.3 and below, premium version), which has nearly 1 million active installations is known as one of the more popular custom form plugins in WordPress.
This plugin is a premium WordPress plugin that lets us create forms to place on our website. With this plugin, we are able to add contact forms, quizzes, and surveys to our website with ease.
The security vulnerability in Gravity Forms
This plugin suffers from an unauthenticated PHP Object Injection vulnerability. The Gravity Forms plugin vulnerability occurs when user-supplied input is not properly sanitized before being passed to the maybe_unserialize
function which is a wrapper for PHP unserialize function.
Since PHP allows object serialization, an unauthenticated user could pass ad-hoc serialized strings to a vulnerable unserialize
call, resulting in an arbitrary PHP object(s) injection into the application scope. The described vulnerability was fixed in version 2.7.4 and assigned CVE-2023-28782.
Find out more from the Patchstack database
The underlying vulnerable code is located in the get_field_input
function:
public function get_field_input( $form, $value = '', $entry = null ) {
if( GFCommon::is_legacy_markup_enabled( $form ) ) {
return $this->get_legacy_field_input( $form, $value, $entry );
}
$form_id = $form['id'];
$is_form_editor = $this->is_form_editor();
if ( ! empty( $value ) ) {
$value = maybe_unserialize( $value );
}
-----------------------------------------------------------------------
This function is located in includes/fields/class-gf-field-list.php
which will handle the input field processing of a list field on Gravity Forms. There is also a legacy get_legacy_field_input
function which has identical code that is also vulnerable. The input value comes from the $value
variable, since there is no proper check or sanitization on the variable and the $value
variable will be directly passed to the maybe_unserialize
function, any unauthenticated user is able to trigger PHP object injection by submitting to a list field on the form created from the Gravity Forms plugin.
The get_field_input
function from the list field could be called from the get_field_input
function located in common.php
which will act as an initial handler of input and will forward the process to each field function handler:
public static function get_field_input( $field, $value = '', $lead_id = 0, $form_id = 0, $form = null ) {
if ( ! $field instanceof GF_Field ) {
$field = GF_Fields::create( $field );
}
$is_form_editor = GFCommon::is_form_editor();
$is_entry_detail = GFCommon::is_entry_detail();
$is_admin = $is_form_editor || $is_entry_detail;
----------------------------------------------------------------------------
$type = RGFormsModel::get_input_type( $field );
switch ( $type ) {
----------------------------------------------------------------------------
default :
if ( ! empty( $post_link ) ) {
return $post_link;
}
if ( $form === null ) {
$form = array( 'id' => 0 );
}
if ( ! isset( $lead ) ) {
$lead = null;
}
return $field->get_field_input( $form, $value, $lead );
break;
}
Note that this vulnerability could be triggered on a default installation or configuration of the Gravity Forms plugin and only needs a created form that contains a list field.
At the time this article was published, we were not able to discover a significant POP chain in the vulnerable plugin, making the impact of this issue limited. If a POP chain is present via an additional plugin or theme installed on the WordPress site, it could allow the attacker to delete arbitrary files, retrieve sensitive data, or execute code, depending on the available POP chain.
The patch in Gravity Forms
Since the issue is mainly because the plugin uses the unsafe maybe_unserialize
function, replacing the function should be enough to fix the issue. The patch can be found below :
Conclusion
The maybe_unserialize
function is a wrapper for PHP unserialize function which is one of the more sensitive processes that could lead to a security issue. In general, we do not recommend using this method to process data that could be partially or fully controlled by user input.
We recommend using JSON instead of serialization to process more complex data structures. If the unserialize process is still needed on the application, we recommend at least configuring the allowed_classes
option set to false
.
Timeline
Help us make the Internet a safer place
Making the WordPress ecosystem more secure is a team effort, and we believe that plugin developers and security researchers should work together.
- If you’re a plugin developer, join our mVDP program that makes it easier to report, manage and address vulnerabilities in your software.
- If you’re a security researcher, join Patchstack Alliance to report vulnerabilities & earn rewards.