How to prevent malicious Excel macros while generating Excel document ? (Using phpExcel)

Viewed 299

Security analyst noticed a security hole in our custom-made CRM: Excel documents which are generated by PHP package phpoffice/phpexcel can have malicious macro commands. Data for Excel documents, which is taken from database, can contain these malicious macros injected somehow. He gave 2 recommendations how to remove that hole:

  1. Remove '=', '@', '+', '-' symbols if they are in the beginning of document's cell (it has been implemented and it's OK).
  2. Add apostrophe (') at the beginning of each document's cell (that apostrophe means "the beginning of comment in VB language", or so...).

The problem is with 2nd recommendation. I added " ' " apostrophe at the beginning of every document cell. Apostrophe should be invisible, but it's visible in the generated document. When I open generated document, focus cursor at the cell and press "enter" (to jump into lower cell), the apostrophe becomes invisible. I don't know how to solve this problem, can you help me? The main code which generates Excel document is below.

Maybe you know alternative solutions how to prevent executing malicious macros in Excel document, which is generated by phpExcel?

Excel::create($filename, function($excel) use ($tableFields, $results) {
    $excel->sheet('Sheet1', function($sheet) use ($tableFields, $results) {

        foreach ($results as $result) {
            $line = (array)$result;

            foreach ($line as $key=>$val) {
                // if cell contains only datetime, format it to Y-m-d H:i:s
                if (preg_match("/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2}).(\d{3})/", $val)==1 || preg_match("/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2}).(\d{7})/", $val)==1) {
                    $line[$key] = "'".Carbon::parse($val)->format('Y-m-d H:i:s');
                }
                elseif (strpos($val, '=')===0 || strpos($val, '@')===0 || strpos($val, '-')===0) {
                    $line[$key] = "'".substr($val,1);
                }
                else {
                    $line[$key] = "'".$val;
                }
            }
            $sheet->appendRow($line);
        }
    });
})->download('xls');
0 Answers
Related