OWASP Top 10 in 2021: Software and Data Integrity Failures Practical Overview
Software and Data Integrity Failures is #8 in the current OWASP Top Ten Most Critical Web Application Security Risks.
Software and Data Integrity Failures
The new Software and Data Integrity Failures OWASP entry covers 10 CWEs, related to data and software integrity, such as CWE-502: deserialization of untrusted data, CWE-345: Insufficient data authenticity, CWE-494: Download of code without integrity check.
Do you want to have an in-depth understanding of all modern aspects of
Software and Data Integrity Failures?
Read this article and bookmark it to get back later, we regularly update this page.
If critical data used by the application is not verified, attackers can tamper with it, which can lead to quite serious issues, such as introduction of malicious code into software.
Many applications now include automatic software update functionality, which raises concerns about data integrity during the update process. If attackers are able to perform MitM attack and push malicious code to the application during the update process, it is very important that such updates are never installed, otherwise the application gets compromised.
Attack vectors
In 2021 over 18000 organizations received a malicious update onto their SolarWinds Orion installation. The attackers were able to compromise the vendor’s CI/CD pipeline and introduced a malicious code directly into original software.
Missing integrity checks issues are very common in SOHO segment as well. Numerous home routers, set-top boxes, IoT devices do not verify firmware integrity, which leads to devices takeover.
Example
To demonstrate the vulnerability let’s have a look at the following code:
- function admin_init() {
- if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
- add_action( 'wp_ajax_swpsmtp_clear_log', array( $this, 'clear_log' ) );
- add_action( 'wp_ajax_swpsmtp_self_destruct', array( $this, 'self_destruct_handler' ) );
- }
- //view log file
- if ( isset( $_GET[ 'swpsmtp_action' ] ) ) {
- if ( $_GET[ 'swpsmtp_action' ] === 'view_log' ) {
- $log_file_name = $this->opts[ 'smtp_settings' ][ 'log_file_name' ];
- if ( ! file_exists( plugin_dir_path( __FILE__ ) . $log_file_name ) ) {
- if ( $this->log( "Easy WP SMTP debug log file\r\n\r\n" ) === false ) {
- wp_die( 'Can\'t write to log file. Check if plugin directory (' . plugin_dir_path( __FILE__ ) . ') is writeable.' );
- };
- }
- $logfile = fopen( plugin_dir_path( __FILE__ ) . $log_file_name, 'rb' );
- if ( ! $logfile ) {
- wp_die( 'Can\'t open log file.' );
- }
- header( 'Content-Type: text/plain' );
- fpassthru( $logfile );
- die;
- }
- }
- //check if this is export settings request
- $is_export_settings = filter_input( INPUT_POST, 'swpsmtp_export_settings', FILTER_SANITIZE_NUMBER_INT );
- if ( $is_export_settings ) {
- $data = array();
- $opts = get_option( 'swpsmtp_options', array() );
- $data[ 'swpsmtp_options' ] = $opts;
- $swpsmtp_pass_encrypted = get_option( 'swpsmtp_pass_encrypted', false );
- $data[ 'swpsmtp_pass_encrypted' ] = $swpsmtp_pass_encrypted;
- if ( $swpsmtp_pass_encrypted ) {
- $swpsmtp_enc_key = get_option( 'swpsmtp_enc_key', false );
- $data[ 'swpsmtp_enc_key' ] = $swpsmtp_enc_key;
- }
- $smtp_test_mail = get_option( 'smtp_test_mail', array() );
- $data[ 'smtp_test_mail' ] = $smtp_test_mail;
- $out = array();
- $out[ 'data' ] = serialize( $data );
- $out[ 'ver' ] = 1;
- $out[ 'checksum' ] = md5( $out[ 'data' ] );
- $filename = 'easy_wp_smtp_settings.txt';
- header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
- header( 'Content-Type: text/plain' );
- echo serialize( $out );
- exit;
- }
- $is_import_settings = filter_input( INPUT_POST, 'swpsmtp_import_settings', FILTER_SANITIZE_NUMBER_INT );
- if ( $is_import_settings ) {
- $err_msg = __( 'Error occurred during settings import', 'easy-wp-smtp' );
- if ( empty( $_FILES[ 'swpsmtp_import_settings_file' ] ) ) {
- echo $err_msg;
- wp_die();
- }
- $in_raw = file_get_contents( $_FILES[ 'swpsmtp_import_settings_file' ][ 'tmp_name' ] );
- try {
- $in = unserialize( $in_raw );
- if ( empty( $in[ 'data' ] ) ) {
- echo $err_msg;
- wp_die();
- }
- if ( empty( $in[ 'checksum' ] ) ) {
- echo $err_msg;
- wp_die();
- }
- if ( md5( $in[ 'data' ] ) !== $in[ 'checksum' ] ) {
- echo $err_msg;
- wp_die();
- }
- $data = unserialize( $in[ 'data' ] );
- foreach ( $data as $key => $value ) {
- update_option( $key, $value );
- }
- set_transient( 'easy_wp_smtp_settings_import_success', true, 60 * 60 );
- $url = admin_url() . 'options-general.php?page=swpsmtp_settings';
- wp_safe_redirect( $url );
- exit;
- } catch ( Exception $ex ) {
- echo $err_msg;
- wp_die();
- }
- }
- }
This is the admin_init() function from the easy-wp-smtp.php file of the Easy WP SMTP WordPress plugin version 1.3.9. The unserialize() function is called to the “data” string and then the values are used to update WordPress settings with the update_option() function.
Apart from unsafe unserialize() call, the plugin allows unauthenticated file upload, as the affected function is by design accessible by non-authenticated users.
This vulnerability was exploited in the wild by attackers to alter the value of the WordPress wp_user_roles option in order to assign administrative privileges to all registered WordPress users.
Solution
Developers should follow the steps below in order to protect the application against data integrity failures:
- Always sign your application components to make sure that both software and data that come from the trusted source and have not been altered
- Make sure that dependencies and third-party libraries use only trusted repositories.
- Review the source code of your application to avoid unwanted configuration changes or introduction on malicious code into the software.
- Make sure that no serialized data is sent unencrypted or unsigned to the clients to avoid data tampering or replay attacks.
OWASP Top 10: Broken Access Control Practical Overview
OWASP Top 10: Cryptographic Failures Practical Overview
OWASP Top 10: Injection Practical Overview
OWASP Top 10: Insecure Design Practical Overview
OWASP Top 10: Security Misconfiguration Practical Overview
OWASP Top 10: Vulnerable and Outdated Components Practical Overview
OWASP Top 10: Identification and Authentication Failures Practical Overview
OWASP Top 10: Software and Data Integrity Failures Practical Overview
OWASP Top 10: Security Logging and Monitoring Failures Practical Overview
OWASP Top 10: Server-Side Request Forgery (SSRF) Practical Overview