Unauthenticated PHP Object Injection in Gravity Forms Plugin <= 2.7.3

Published 30 May 2023
Updated 24 July 2023
Rafie Muhammad
Security Researcher at Patchstack
Table of Contents

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.

security vulnerability in Gravity Forms

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 :

security vulnerability in Gravity Forms

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

27 March, 2023We found the vulnerability and reached out to the plugin vendor.
11 April, 2023Gravity Forms plugin version 2.7.4 was published to patch the reported issues.
29 May, 2023Added the vulnerabilities to the Patchstack vulnerability database.
30 May, 2023Published the article.

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.

The latest in Security Advisories

Looks like your browser is blocking our support chat widget. Turn off adblockers and reload the page.
crossmenu