ZF2016-04: Potential remote code execution in zend-mail via Sendmail adapter

ZF2016-04: Potential remote code execution in zend-mail via Sendmail adapter

When using the zend-mail component
to send email via the ZendMailTransportSendmail transport, a malicious user
may be able to inject arbitrary parameters to the system sendmail program.
The attack is performed by providing additional quote characters within an
address; when unsanitized, they can be interpreted as additional command line
arguments, leading to the vulnerability.

The following example demonstrates injecting additional parameters to the
sendmail binary via the From address:

use ZendMail;

$mail = new MailMessage();
$mail->setBody('This is the text of the email.');

// inject additional parameters to sendmail command line
$mail->setFrom('"AAA" params injection"@domain', 'Sender's name');

$mail->addTo('hacker@localhost', 'Name of recipient');
$mail->setSubject('TestSubject');

$transport = new MailTransportSendmail();
$transport->send($mail);

The attack works because zend-mail filters the email addresses using
the RFC 3696 specification,
where the string "AAA" params injection"@domain is considered a valid
address. This validation is provided using the zend-validator component with
the following parameters:

ZendValidatorEmailAddress(
    ZendValidatorHostname::ALLOW_DNS | ZendValidatorHostname::ALLOW_LOCAL
)

The above accepts local domain with any string specified by double quotes as the
local part. While this is valid per RFC 3696, due to the fact that sender email
addresses are provided to the sendmail binary via the command line, they create
the vulnerability described above.

Action Taken

To fix the issue, we added a transport-specific email filter for the From
header in the Sendmail transport adapter. The filter checks for the sequence
" in the local part of the email From address.

$from = $headers->get('From');
if ($from) {
    foreach ($from->getAddressList() as $address) {
        if (preg_match('/\"/', $address->getEmail())) {
            throw new ExceptionRuntimeException("Potential code injection in From header");
        }
    }
}

The patch resolving the vulnerability is available in:

  • zend-mail, starting in version 2.7.2
  • zend-mail, 2.4.11
  • Zend Framework, 2.4.11

Zend Framework 2.5 and 3.0 versions will receive the update automatically, as
executing composer update in proejcts using these versions will update to
zend-mail
2.7.2+.

Acknowledgments

The Zend Framework team thanks the following for identifying the issues and
working with us to help protect its users:

  • The independent security researcher Dawid Golunski,
    who reported the vulnerability to Beyond Security’s SecuriTeam Secure
    Disclosure program;
  • Enrico Zimuel, who provided the patch.

Source: Zend security feed

ZF2016-03: Potential SQL injection in ORDER and GROUP functions of ZF1

ZF2016-03: Potential SQL injection in ORDER and GROUP functions of ZF1

The implementation of ORDER BY and GROUP BY in Zend_Db_Select remained
prone to SQL injection when a combination of SQL expressions and comments were
used. This security patch provides a comprehensive solution that identifies and
removes comments prior to checking validity of the statement to ensure no SQLi
vectors occur.

The implementation of ORDER BY and GROUP BY in Zend_Db_Select of ZF1 is
vulnerable by the following SQL injection:

$db = Zend_Db::factory(/* options here */);
$select = new Zend_Db_Select($db);
$select->from('p');
$select->order("MD5("a(");DELETE FROM p2; #)"); // same with group()

The above $select will render the following SQL statement:

SELECT `p`.* FROM `p` ORDER BY MD5("a(");DELETE FROM p2; #) ASC

instead of the correct one:

SELECT "p".* FROM "p" ORDER BY "MD5(""a("");DELETE FROM p2; #)" ASC

This security fix can be considered an improvement of the previous
ZF2016-02 and
ZF2014-04 advisories.

As a final consideration, we recommend developers either never use user input
for these operations, or filter user input thoroughly prior to invoking
Zend_Db. You can use the Zend_Db_Select::quoteInto() method to filter the
input data, as shown in this example:

$db    = Zend_Db::factory(...);
$input = "MD5("a(");DELETE FROM p2; #)"; // user input can be an attack
$order = $db->quoteInto("SQL statement for ORDER", $input);

$select = new Zend_Db_Select($db);
$select->from('p');
$select->order($order); // same with group()

Action Taken

We fixed the reported SQL injection by removing comments from the SQL statement
before passing it to either the order() or group() methods; this patch
effectively solves any comment-based SQLi vectors.

We used the following regex to remove comments from a SQL statement:

const REGEX_SQL_COMMENTS = '@
    ((['"]).*?[^\]) # $1 : Skip single & double quoted expressions
    |(                   # $3 : Match comments
        (?:#|--).*?$    # - Single line comments
        |                # - Multi line (nested) comments
         /*             #   . comment open marker
            (?: [^/*]    #   . non comment-marker characters
                |/(?!*) #   . ! not a comment open
                |*(?!/) #   . ! not a comment close
                |(?R)    #   . recursive case
            )*           #   . repeat eventually
        */             #   . comment close marker
    )s*                 # Trim after comments
    |(?<=;)s+           # Trim after semi-colon
    @msx';

The patch is available starting in Zend Framework 1.12.20.

Other Information

This SQL injection attack does not affect Zend Framework 2 and 3 versions because the
implementations of ZendDbSqlSelect::order() and ZendDbSqlSelect::group() do
not manage parenthetical expressions.

Acknowledgments

The Zend Framework team thanks the following for identifying the issues and
working with us to help protect its users:

  • Hiroshi Tokumaru (HASH Consulting Corp.), who discovered the issue;
  • Masanobu Katagi (Japan Computer Emergency Response Team Coordination Center),
    who reported the issue;
  • Enrico Zimuel, who provided the patch.

Source: Zend security feed

ZF2016-02: Potential SQL injection in ORDER and GROUP statements of Zend_Db_Select

ZF2016-02: Potential SQL injection in ORDER and GROUP statements of Zend_Db_Select

The implementation of ORDER BY and GROUP BY in Zend_Db_Select of ZF1 is
vulnerable by the following SQL injection:

$db = Zend_Db::factory(/* options here */);
$select = new Zend_Db_Select($db);
$select->from('p');
$select->order("MD5("(");DELETE FROM p2; #)"); // same with group()

The above $select will render the following SQL statement:

SELECT `p`.* FROM `p` ORDER BY MD5("");DELETE FROM p2; #) ASC

instead of the correct one:

SELECT `p`.* FROM `p` ORDER BY "MD5("""");DELETE FROM p2; #)" ASC

This security fix can be considered as an improvement of the previous
ZF2014-04.

Action Taken

We fixed the reported SQL injection using two regular expressions for the order() and the group()
methods in Zend_Db_Select, created as the class constants REGEX_COLUMN_EXPR_ORDER and
REGEX_COLUMN_EXPR_GROUP, respectively. These are defined as:

/^([w]+s*(([^()]|(?1))*))$/

This regexp is different from the previous REGEX_COLUMN_EXPR, which used the
character patterm [w]*; we now require at least one word boundary ([w]+).

The patch is available starting in Zend Framework 1.12.19.

Other Information

This SQL injection attack does not affect Zend Framework 2 and 3 versions because the
implementations of ZendDbSqlSelect::order() and ZendDbSqlSelect::group() do
not manage parenthetical expressions.

Acknowledgments

The Zend Framework team thanks the following for identifying the issues and
working with us to help protect its users:

  • Peter O’Callaghan, who discovered and reported the issue;
  • Enrico Zimuel, who provided the patch.

Source: Zend security feed

ZF2016-01: Potential Insufficient Entropy Vulnerability in Zend Framework 1

ZF2016-01: Potential Insufficient Entropy Vulnerability in ZF1

We discovered several methods used to generate random numbers in ZF1 that
potentially used insufficient entropy. These random number generators are used
in the following method calls:

  • Zend_Ldap_Attribute::createPassword
  • Zend_Form_Element_Hash::_generateHash
  • Zend_Gdata_HttpClient::filterHttpRequest
  • Zend_Filter_Encrypt_Mcrypt::_srand
  • Zend_OpenId::randomBytes

In each case, the methods were using rand() or mt_rand(), neither of which
can generate cryptographically secure values. This could potentially lead to
information disclosure should an attacker be able to brute force the random
number generation.

Moreover, we discovered a potential security issue in the usage of the
openssl_random_pseudo_bytes()
function in Zend_Crypt_Math::randBytes, reported in PHP BUG
#70014, and the security implications
reported in a discussion on the random_compat library.

Action Taken

We replaced the usage of rand() and mt_rand() with the random generators of
ZF1 implemented in Zend_Crypt_Math().

Moreover, we removed the usage of openssl_random_pseudo_bytes() functions in
Zend_Crypt_Math::randBytes(). This removal is not a BC break for Linux users
thanks to the usage of /dev/urandom as an entropy source. For Windows users,
this can be a BC break if the Mcrypt extension is not enabled.

The following releases contain the fixes:

  • Zend Framework 1.12.18

Recommendations

If you are using an affected version of PHP, we highly recommend upgrading
immediately to Zend Framework 1.12.18.

Other Information

Acknowledgments

The Zend Framework team thanks the following for identifying the issues and
working with us to help protect its users:

  • Brian Engert of Soliant Consulting, who
    discovered, reported, and proposed a patch for the issue;
  • Enrico Zimuel, who tested the patch and added the patch
    for the OpenSSL usage removal.

Source: Zend security feed

ZF2015-10: Potential Information Disclosure in ZendCryptPublicKeyRsaPublicKey

ZF2015-10: Potential Information Disclosure in ZendCryptPublicKeyRsaPublicKey

ZendCryptPublicKeyRsaPublicKey has a call to openssl_public_encrypt()
which uses PHP’s default $padding argument, which specifies
OPENSSL_PKCS1_PADDING, indicating usage of PKCS1v1.5 padding. This padding has
a known vulnerability, the Bleichenbacher’s chosen-ciphertext attack,
which can be used to decrypt arbitrary ciphertexts.

Action Taken

  • ZendCryptPublicKeyRsaPublicKey::encrypt() was updated to accept an
    additional argument, $padding; the default value for this argument was set
    to OPENSSL_PKCS1_OAEP_PADDING.
  • ZendCryptPublicKeyRsaPrivateKey::decrypt() was updated to accept an
    additional argument, $padding; the default value for this argument was set
    to OPENSSL_PKCS1_OAEP_PADDING.
  • ZendCryptPublicKeyRsa::encrypt() was updated to accept an additional
    optional argument, $padding, allowing the user to specify the padding to use
    with PublicKey::encrypt().
  • ZendCryptPublicKeyRsa::decrypt() was updated to accept an additional
    optional argument, $padding, allowing the user to specify the padding to use
    with PrivateKey::decrypt().

The above changes represent a backwards-compatibility break, but were necessary
to prevent the outlined vulnerability. If you were using
ZendCryptPublicKeyRsa previously, you will likely need to re-encrypt any
data you’ve previously encrypted to use the new padding. This can be done as
follows:

$decrypted = $rsa->decrypt($data, $key, $rsa::MODE_AUTO, OPENSSL_PKCS1_PADDING);
$encrypted = $rsa->encrypt($data, $key); // Encrypted using OPENSSL_PKCS1_OAEP_PADDING

The key may have a value of null in each of the examples above.

The following releases contain the fixes:

  • Zend Framework 2.4.9
  • zend-framework/zend-crypt 2.4.9
  • zend-framework/zend-crypt 2.5.2

This advisory was given the CVE identifier CVE-2015-7503

Recommendations

If you use zend-crypt via either Zend Framework 2 or the
zendframework/zend-crypt package, and are using the RSA public key
functionality, we recommend upgrading to 2.4.9/2.5.2 immediately.

Other Information

Acknowledgments

The Zend Framework team thanks the following for identifying the issues and
working with us to help protect its users:

Source: Zend security feed

ZF2015-09: Potential Information Disclosure and Insufficient Entropy vulnerability in ZendCaptchaWord

ZF2015-09: Potential Information Disclosure and Insufficient Entropy vulnerability in ZendCaptchaWord

In Zend Framework, Zend_Captcha_Word (v1) and ZendCaptchaWord (v2)
generate a "word" for a CAPTCHA challenge by selecting a sequence of random
letters from a character set. Prior to this advisory, the selection was
performed using PHP’s internal array_rand() function. This function does not
generate sufficient entropy due to its usage of rand() instead of more
cryptographically secure methods such as openssl_pseudo_random_bytes(). This
could potentially lead to information disclosure should an attacker be able to
brute force the random number generation.

Action Taken

The code used to randomly select letters was updated as follows:

  • In Zend Framework 1.12.17, the methods randBytes() and randInteger() were
    added to Zend_Crypt_Math. Zend_Captcha_AbstractWord was updated to use
    Zend_Crypt_Math::randInteger() instead of array_rand() when selecting
    letters for the CAPTCHA word.
  • In the package zendframework/zend-captcha 2.4.9/2.5.2 and Zend Framework
    2.4.9, ZendCaptchaAbstractWord was updated to use
    ZendMathRand::getInteger() instead of array_rand() when selecting
    letters for the CAPTCHA word.

The following releases contain the fixes:

  • Zend Framework 1.12.17
  • Zend Framework 2.4.9
  • zend-captcha 2.4.9
  • zend-captcha 2.5.2

Recommendations

This patch is considered a security hardening patch, and as such, was not
assigned a CVE identifier.

Regardless, if you use one of the word-based CAPTCHA adapters in Zend Framework
1 or 2, we recommend upgrading to 1.12.17, 2.4.9, or zend-captcha 2.4.9/2.5.2.

Other Information

Acknowledgments

The Zend Framework team thanks the following for identifying the issues and
working with us to help protect its users:

Source: Zend security feed

ZF2015-08: Potential SQL injection vector using null byte for PDO (MsSql, SQLite)

ZF2015-08: Potential SQL injection vector using null byte for PDO (MsSql, SQLite)

The PDO adapters of Zend Framework 1 do not filter null bytes values in SQL
statements. A PDO adapter can treat null bytes in a query as a string
terminator, allowing an attacker to add arbitrary SQL following a null byte, and
thus create a SQL injection.

We tested and verified the null byte injection using pdo_dblib (FreeTDS) on a
Linux environment to access a remote Microsoft SQL Server, and also tested
against and noted the vector against pdo_sqlite.

Action Taken

We added null byte filtering in the PDO abstract component
Zend_Db_Adapter_Pdo_Abstract. We decided to use the abstract component to
prevent null byte injection in all the PDO adapters once we discovered the
situation was not specific to pdo_dblib.

We used the PHP’s addcslashes to sanitize and properly quote null bytes:

$value = addcslashes($value, "{$content}02");

The following releases contain the fixes:

  • Zend Framework 1.12.16

Recommendations

If you use one of the PDO-based adapters in Zend Framework 1, we recommend
upgrading to 1.12.16 immediately.

Other Information

Acknowledgments

The Zend Framework team thanks the following for identifying the issues and
working with us to help protect its users:

  • Chris Kings-Lynne, who discovered and reported the issue against the
    Zend_Db_Adapter_Pdo_Mssql component of ZF1;
  • Enrico Zimuel, who provided the patch.

Source: Zend security feed