The package zendframework/zend-developer-tools provides a web-based toolbar for introspecting an application. When updating the package to support PHP 7.3, a change was made that could potentially prevent toolbar entries that are enabled by default from being disabled.
A test was added to the package to verify that only whitelisted entries should be aggregated when configuring the toolbar, and the code updated to comply.
The patch resolving the vulnerability is available in zend-developer-tools 1.2.3.
We highly recommend all users of the package to update immediately.
The Zend Framework team thanks the following for identifying the issues and working with us to help protect its users:
zend-diactoros (and, by extension, Expressive), zend-http (and, by extension, Zend Framework MVC projects), and zend-feed (specifically, its PubSubHubbub sub-component) each contain a potential URL rewrite exploit. In each case, marshaling a request URI includes logic that introspects HTTP request headers that are specific to a given server-side URL rewrite mechanism.
When these headers are present on systems not running the specific URL rewriting mechanism, the logic would still trigger, allowing a malicious client or proxy to emulate the headers to request arbitrary content.
In each of the affected components, we have removed support for the specific request headers. Users can provide support within their applications to re-instate the logic if they are using the specific URL rewrite mechanism; users are encouraged to filter these headers in their web server prior to any rewrites to ensure their validity.
The patch resolving the vulnerability is available in:
Zend Framework MVC, Apigility, and Expressive users will receive relevant
updated components via composer update.
We highly recommend all users of affected projects update immediately.
The Zend Framework team thanks the following for identifying the issues and working with us to help protect its users:
When using the zend-mail component
to send email via the Zend\Mail\Transport\Sendmail 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 Zend\Mail;
$mail = new Mail\Message();
$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 Mail\Transport\Sendmail();
$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:
Zend\Validator\EmailAddress(
Zend\Validator\Hostname::ALLOW_DNS | Zend\Validator\Hostname::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.
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 Exception\RuntimeException("Potential code injection in From header");
}
}
}
The patch resolving the vulnerability is available in:
Zend Framework 2.5 and 3.0 versions will receive the update automatically, as
executing composer update in projects using these versions will update to
zend-mail
2.7.2+.
The Zend Framework team thanks the following for identifying the issues and working with us to help protect its users:
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()
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 = '@
(([\'"]).*?[^\\\]\2) # $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.
This SQL injection attack does not affect Zend Framework 2 and 3 versions because the
implementations of Zend\Db\Sql\Select::order() and Zend\Db\Sql\Select::group() do
not manage parenthetical expressions.
The Zend Framework team thanks the following for identifying the issues and working with us to help protect its users:
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.
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 pattern [\w]*; we now require at least one word boundary ([\w]+).
The patch is available starting in Zend Framework 1.12.19.
This SQL injection attack does not affect Zend Framework 2 and 3 versions because the
implementations of Zend\Db\Sql\Select::order() and Zend\Db\Sql\Select::group() do
not manage parenthetical expressions.
The Zend Framework team thanks the following for identifying the issues and working with us to help protect its users:
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.
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:
If you are using an affected version of PHP, we highly recommend upgrading immediately to Zend Framework 1.12.18.
The Zend Framework team thanks the following for identifying the issues and working with us to help protect its users:
In Zend Framework, Zend_Captcha_Word (v1) and Zend\Captcha\Word (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.
The code used to randomly select letters was updated as follows:
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.Zend\Captcha\AbstractWord was updated to use
Zend\Math\Rand::getInteger() instead of array_rand() when selecting
letters for the CAPTCHA word.The following releases contain the fixes:
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.
The Zend Framework team thanks the following for identifying the issues and working with us to help protect its users:
Zend\Crypt\PublicKey\Rsa\PublicKey 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.
Zend\Crypt\PublicKey\Rsa\PublicKey::encrypt() was updated to accept an
additional argument, $padding; the default value for this argument was set
to OPENSSL_PKCS1_OAEP_PADDING.Zend\Crypt\PublicKey\Rsa\PrivateKey::decrypt() was updated to accept an
additional argument, $padding; the default value for this argument was set
to OPENSSL_PKCS1_OAEP_PADDING.Zend\Crypt\PublicKey\Rsa::encrypt() was updated to accept an additional
optional argument, $padding, allowing the user to specify the padding to use
with PublicKey::encrypt().Zend\Crypt\PublicKey\Rsa::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
Zend\Crypt\PublicKey\Rsa 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:
This advisory was given the CVE identifier CVE-2015-7503
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.
The Zend Framework team thanks the following for identifying the issues and working with us to help protect its users:
As reported by the Doctrine Project, incorrect permissions masks when creating a new directory or file can lead to:
Such attacks typically require direct access to a user of the system to exploit, but are dangerous vectors when available.
During an audit of the Zend Framework code base, we found several instances where we were using incorrect permissions masks that could lead to such vulnerabilities.
We identified the following projects/components with vulnerabilities by checking
for mkdir() and umask() calls:
zend-cache component, specifically the Filesystem
storage adapter and CaptureCache pattern.Zend_Cloud Filesystem storage adapter,
Zend_Search_Lucene's filesystem storage, and Zend_Service_WindowsAzure's
package scaffolder.We updated the code as follows:
0775, and files to
0664.& ~0002.The following components/libraries were patched, at the version specified:
This vulnerability was originally disclosed via the Doctrine project as CVE-2015-5723.
If you use any of the components listed above, we recommend upgrading to one of these versions immediately.
The Zend Framework team thanks the following for identifying the issues and working with us to help protect its users:
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.
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, "\000\032");
The following releases contain the fixes:
If you use one of the PDO-based adapters in Zend Framework 1, we recommend upgrading to 1.12.16 immediately.
The Zend Framework team thanks the following for identifying the issues and working with us to help protect its users:
Zend_Db_Adapter_Pdo_Mssql component of ZF1;ZF2014-01 addressed potential XML eXternal Entity (XXE) injection and XML Entity Expansion (XEE) vectors in Zend Framework components that consume XML. The solution provided at the time was creation of a new component, ZendXml, which mitigates the vectors, and which we then incorporated into all components that consume XML.
However, an independent security researcher recently discovered a vector that remained open in ZendXml when running under PHP-FPM (PHP's FastCGI Process Manager) when in a threaded environment: if the XML payload is in a multibyte encoding, the heuristic we provide to detect XXE/XEE vectors can fail.
The underlying problem is threading support for libxml2 in PHP, which is what forced us to use a heuristic detection under PHP-FPM in the first place. That problem has been fixed in the upstream PHP project, but it only applies to PHP versions 5.5 at 5.5.22 and higher, PHP 5.6 at 5.6.6 and higher, and the PHP 7 development branch. This means that, in order to protect all users of Zend Framework, we had to create better heuristic detection when using an older version of PHP.
We updated our heuristic to do the following:
<!ENTITY and test for the encoded string in the document. If
discovered, the heuristic fails, and we mark the document as a security
violation.For users of PHP 5.5 >= 5.5.22, PHP 5.6 >= 5.6.6, and PHP 7 development builds, we never use the heuristic, and instead use the tools provided by libxml2 to prevent external entity loading and entity expansions.
The following components/libraries were patched, at the version specified:
This vulnerability has also been disclosed as CVE-2015-5161.
If you use any Zend Framework components that consume XML, and use or will use PHP-FPM during deployment, we recommend upgrading to one of these versions immediately.
The Zend Framework team thanks the following for identifying the issues and working with us to help protect its users:
We discovered a potential issue in the Web-Server Application scenario (also
termed "Authorization Code") of zf-oauth2.
An attacker can pass a user_id value in the query string when using the
scenario, and associate the authorization code and the token to a different
user. Passing the user_id in the query string is a bad practice; the user
identity should be managed server side using a value from original authorization
(e.g. from the original login page).
The vulnerability exists in all stable versions of zf-oauth2 from 1.1.0 forward.
Only applications using the authorization_code scenario are affected.
We removed the ability to specify the user_id in the query string when
utilizing the /authorize resource, and we now use
Zend\Authorization\AuthorizationService as the default mechanism for managing
the identity of the user under this OAuth2 scenario.
The patch fixing the issues has been applied in the following versions:
Additionally, we have released corresponding versions of the Apigility skeleton, used by our installer, to ensure they use these versions of zf-oauth2 by default.
If you are using zf-oauth2 with the web application/authorization code
scenario, we recommend upgrading zf-oauth2 to either 1.2.1 or 1.3.1. This can
usually be done using composer update zfcampus/zf-oauth2.
The Zend Framework team thanks the following for identifying the issues and working with us to help protect its users:
The Drupal Security Team notified us of a potential issue with the Diactoros URI implementation. Diactoros is a PSR-7 implementation of HTTP messages.
If the path from a Zend\Diactoros\Uri instance is used to generate links, form
targets, or headers, and omits the scheme and authority, a potential XSS and/or
open redirect vector is possible if the path starts with double slashes and a
path segment that validates as a hostname; in such a situation, it may be
interpreted as a scheme-relative link.
The vulnerability exists in all stable versions of zend-diactoros prior to 1.0.4.
Zend\Diactoros\Uri::filterPath() was updated to ensure that the returned path
will never begin with double slashes. Tests were also added to prevent a
regression in the future.
The patch fixing the issues has been applied in the following versions:
This vulnerability has also been disclosed as CVE-2015-3257.
If you are using Zend\Diactoros\Uri to generate links, form targets, or
headers without including the scheme and authority, we recommend:
Uri instance to a string).The Zend Framework team thanks the following for identifying the issues and working with us to help protect its users:
The CRLF Injection Attack (sometimes also referred to as HTTP Response Splitting) is a fairly simple, yet extremely powerful web attack. It has been reported in detail in "CWE-113 Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Response Splitting')".
CRLF (Carriage Return "\r" and Line Feed "\n") is a significant sequence of
characters, representing the the End Of Line (EOL) marker for many Internet
protocols, including, but not limited to MIME (e-mail), NNTP (newsgroups), and,
more importantly, HTTP. When programmers write code for web applications, they
split headers based on where the CRLF is found. If a malicious user is able to
inject his own CRLF sequence into an HTTP stream, he is able to maliciously
control the way a web application functions.
For instance, the following attack is possible using Zend\Mail:
$message = new Zend\Mail\Message();
$message->setSubject(
"test1\r\nContent-Type: text/html; charset = \"iso-8859-1\"\r\n\r\n"
. "<iframe src=\"http://example.com/\"></iframe>"
. "<!--"
);
$message->setBody("This is the real body!");
var_dump($message->toString());
This var_dump() shows that the string contains a double CRLF sequence. A mail
server will interpret the HTML code as the message body, instead of the correct
one, executing the attack!
The other Zend Framework component affected by CRLF Injection Attack is Zend\Http.
In Zend Framework 2, we added three new classes:
Zend\Mail\Header\HeaderName
Zend\Mail\Header\HeaderValue
Zend\Http\Header\HeaderValue
Each defines three static methods:
filter($value), for filtering a value based on the relevant IETF specification.isValid($value), for validating that a value only contains characters defined in the relevant IETF specification.assertValid($value), for asserting that a value is valid (raises an exception for invalid values).We updated the header classes in each component to use the isValid() and
assertValid() methods to validate data provided to the class and raise an
exception for invalid data. These utilities are used both when deserializing a
header value, as well as when providing data via constructors and setters,
ensuring that the classes can only emit valid data.
Additionally, we updated deserialization methods in classes representing mail messages and HTTP request and response messages to scan for CRLF injection attempts, and they now raise exceptions on detection.
Users may use the isValid() methods to pro-actively check for invalid values,
and/or the filter() methods to sanitize data to use for headers. In the latter
case, developers should be aware that filtering is lossy, as it strips any
invalid characters detected.
For Zend Framework 1, we applied a similar solution as for Zend Framework2,
introducing Zend_Mail_Header_HeaderName, Zend_Mail_Header_HeaderValue, and
Zend_Http_Header_HeaderValue, each with the same static methods and approach
as above. The Zend_Mail_Message, Zend_Mail_Part, Zend_Http_Client,
Zend_Http_Request, Zend_Http_Response, and Zend_Http_Header_SetCookie
classes were audited to ensure that they assert valid values.
The following specifications were used when developing the solution:
The patch fixing the issues has been applied in the following versions:
This vulnerability has also been disclosed as CVE-2015-3154.
If you are using Zend\Mail or Zend\Http from Zend Framework 2 (either
standalone, or within components like Zend\Mvc), or if you are using the
Zend_Mail or Zend_Http components from Zend Framework 1, we recommend
upgrading immediately.
The Zend Framework team thanks the following for identifying the issues and working with us to help protect its users:
Zend\Mail; andZend\Http issue, and
who reviewed the patch and proposed improvements; andZend\Validator\Csrf, starting in the Zend Framework 2.3 series, was not
correctly identifying null or mal-formatted token identifiers, leading to false
positive validations, and thus potentially allowing for Cross-Site Request
Forgery vectors.
A patch was written that correctly identifies invalid token identifiers, ensuring that they invalidate the provided value.
The patch fixing the issue has been applied in the following versions:
Note: in testing the patch, we discovered that the vulnerability was introduced specifically in the 2.3 series, and thus no patch was necessary against the 2.2 series.
This vulnerability has also been disclosed as CVE-2015-1786.
If you are using Zend\Validator\Csrf (either standalone, or within
Zend\InputFilter or via Zend\Form\Element\Csrf) in the 2.3 series of Zend
Framework, we recommend upgrading immediately.
The Zend Framework team thanks the following for identifying the issues and working with us to help protect its users: