Skip to content

Commit

Permalink
mitigate efail
Browse files Browse the repository at this point in the history
This commit prevents the gpg backend from decrypting non integrity
protected messages. The efail [0] vurneability relies on the attacker
being able to inject content into an encrypted mail.

According to [1], the correct way of detecting if decryption succeeded
is not to check the return code. Instead the `--status-fd` should be
checked for DECRYPTION_OKAY.

Imp currently displays the decrypted body (including the gpg warning)
in the message pane. This opens up decryption oracle attacks.

[0] https://efail.de/
[1] https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob_plain;f=doc/DETAILS
  • Loading branch information
Immerda committed May 14, 2018
1 parent f3bceee commit ef329a8
Showing 1 changed file with 29 additions and 0 deletions.
29 changes: 29 additions & 0 deletions lib/Horde/Crypt/Pgp/Backend/Binary.php
Expand Up @@ -567,6 +567,7 @@ public function decryptMessage($text, $params)
true
);
$this->_ensureResult($result);
$this->_ensureDecryptionOk($result);

return $this->_checkSignatureResult($result->stderr, $result->output);
}
Expand Down Expand Up @@ -685,12 +686,16 @@ public function _callGpg(
$data->output = null;
$data->stderr = null;
$data->stdout = null;
$data->status = null;

/* Verbose output? */
if (!$verbose) {
array_unshift($options, '--quiet');
}

$status_file = $this->_createTempFile('horde-pgp-stat', false);
array_unshift($options, '--status-file ' . $status_file);

/* Create temp files for output. */
if ($output) {
$output_file = $this->_createTempFile('horde-pgp', false);
Expand Down Expand Up @@ -751,6 +756,9 @@ public function _callGpg(
}
pclose($fp);

$data->status = file_get_contents($status_file);
unlink($status_file);

if ($output) {
$data->output = file_get_contents($output_file);
unlink($output_file);
Expand Down Expand Up @@ -850,6 +858,27 @@ protected function _ensureResult($result)
}
}

/**
* Checks whether the decryption succeeded.
*
* @param object $result A result from _callGpg().
*
* @throws Horde_Crypt_Exception with messages from stderr if the result
* is not a successful decryption.
*/
protected function _ensureDecryptionOk($result)
{
if (!preg_match("/DECRYPTION_OKAY/", $result->status)) {
throw new Horde_Crypt_Exception(
preg_replace(
array('/^gpg: /', '/\n/'),
array('', '. '),
$result->stderr
)
);
}
}

/**
* Create a temporary file that will be deleted at the end of this
* process.
Expand Down

0 comments on commit ef329a8

Please sign in to comment.