Skip to content
Permalink
Browse files

security: CSV Formula Injection

This addresses a security issue discovered by Aishwarya Iyer where a User
can change their Full Name to a windows formula and when an Agent exports a
list of Users containing said User and opens the export file, the formula
will be executed on their computer (if it's windows of course). This adds a
new validator called `is_formula()` to all text fields disallowing the use
of the following characters `= + - @` at the beginning of text. This should
mitigate CSV Formula injections for any text field that allows user-input in
the system. To further prevent CSV Formula injections this adds an escape
mechanism to the Exporter that will escape any content matching the formula
regex with a single quote (as mentioned in many posts about this subject).
  • Loading branch information...
JediKev committed Jun 4, 2019
1 parent bbfff1a commit 99818486c5b1d8aa445cee232825418d6834f249
Showing with 38 additions and 3 deletions.
  1. +7 −1 include/class.export.php
  2. +25 −1 include/class.forms.php
  3. +1 −1 include/class.user.php
  4. +5 −0 include/class.validator.php
@@ -356,7 +356,13 @@ function dump() {
fputs($this->output, chr(0xEF) . chr(0xBB) . chr(0xBF));
fputcsv($this->output, $this->getHeaders(), $delimiter);
while ($row=$this->next())
fputcsv($this->output, $row, $delimiter);
fputcsv($this->output, array_map(
function($v){
if (preg_match('/^[=\-+@].*/', $v))
return "'".$v;
return $v;
}, $row),
$delimiter);
fclose($this->output);
}
@@ -1300,7 +1300,8 @@ function validateEntry($value) {
parent::validateEntry($value);
$config = $this->getConfiguration();
$validators = array(
'' => null,
'' => array(array('Validator', 'is_formula'),
__('Content cannot start with the following characters: = - + @')),
'email' => array(array('Validator', 'is_valid_email'),
__('Enter a valid email address')),
'phone' => array(array('Validator', 'is_phone'),
@@ -1379,6 +1380,29 @@ function getConfigurationOptions() {
);
}
function validateEntry($value) {
parent::validateEntry($value);
if (!$value)
return;
$config = $this->getConfiguration();
$validators = array(
'' => array(array('Validator', 'is_formula'),
__('Content cannot start with the following characters: = - + @')),
);
// Support configuration forms, as well as GUI-based form fields
if (!($valid = $this->get('validator')) && isset($config['validator']))
$valid = $config['validator'];
if (!isset($validators[$valid]))
return;
$func = $validators[$valid];
$error = $func[1];
if ($config['validator-error'])
$error = $this->getLocal('validator-error', $config['validator-error']);
if (is_array($func) && is_callable($func[0]))
if (!call_user_func($func[0], $value))
$this->_errors[] = $error;
}
function hasSpecialSearch() {
return false;
}
@@ -248,7 +248,7 @@ static function fromForm($form, $create=true) {
//Validate the form
$valid = true;
$filter = function($f) use ($thisstaff) {
return !isset($thisstaff) || $f->isRequiredForStaff();
return !isset($thisstaff) || $f->isRequiredForStaff() || $f->isVisibleToStaff();
};
if (!$form->isValid($filter))
$valid = false;
@@ -204,6 +204,11 @@ static function is_username($username, &$error='') {
return $error == '';
}
static function is_formula($text, &$error='') {
if (!preg_match('/^[^=\+@-].*$/', $text))
$error = __('Content cannot start with the following characters: = - + @');
return $error == '';
}
/*
* check_ip

0 comments on commit 9981848

Please sign in to comment.
You can’t perform that action at this time.