Skip to content

Latest commit

 

History

History
87 lines (68 loc) · 6.69 KB

File metadata and controls

87 lines (68 loc) · 6.69 KB

Mitigation Strategies Analysis for phpoffice/phpexcel

  1. Locate Initialization: Identify the exact point in your code where PHPExcel/PhpSpreadsheet is used to load an Excel file. This is typically where you use a reader object (e.g., PHPExcel_IOFactory::createReader(), \PhpOffice\PhpSpreadsheet\IOFactory::createReader(), or a specific reader like new \PhpOffice\PhpSpreadsheet\Reader\Xlsx()).
  2. Insert libxml_disable_entity_loader(true);: Immediately before the line that loads the spreadsheet (e.g., $spreadsheet = $reader->load($filename);), insert:
    libxml_disable_entity_loader(true);
  3. Ensure Correct Scope: Make absolutely certain this line executes before any spreadsheet loading, even within helper functions or class methods. The best practice is to have this as close as possible to the loading operation, within the same function or method, to avoid any potential race conditions or missed execution paths.
  4. Test: After implementing, use a test Excel file containing a harmless XXE payload (e.g., referencing a non-existent file) to confirm that the entity is not loaded. You should not see any errors related to the non-existent file.
  • List of Threats Mitigated:

    • XXE (XML External Entity) Injection: (Severity: Critical) - Prevents attackers from exploiting XXE vulnerabilities within PHPExcel/PhpSpreadsheet's XML parsing.
    • DoS via XML Parsing (related to XXE): (Severity: High) - Reduces the risk of DoS attacks that leverage XXE to cause excessive resource consumption.
  • Impact:

    • XXE: Risk reduced from Critical to Very Low (within the context of PHPExcel/PhpSpreadsheet's handling of the file).
    • DoS (XXE-related): Risk reduced from High to Low.
  • Currently Implemented:

    • Implemented directly before the $reader->load() call within the loadSpreadsheet() method of app/Services/SpreadsheetService.php.
  • Missing Implementation:

    • Potentially missing in any legacy code that directly instantiates reader objects without using the SpreadsheetService. A code audit is needed to identify and remediate these instances.
  1. Identify Cell Writing: Locate all instances in your code where you write data to spreadsheet cells using PHPExcel/PhpSpreadsheet's API. This typically involves methods like setCellValue(), setCellValueByColumnAndRow(), or similar.
  2. Implement Sanitization Function: Create (or reuse) a function that prefixes potentially dangerous values with a single quote (').
    function sanitizeCellValue($value) {
        $formulaChars = ['=', '+', '-', '@'];
        if (in_array(substr($value, 0, 1), $formulaChars)) {
            $value = "'" . $value;
        }
        return $value;
    }
  3. Apply Sanitization Immediately Before Writing: Immediately before calling the cell-writing method, apply the sanitization function to the value being written.
    $userInput = $_POST['user_input']; // Example
    $sanitizedInput = sanitizeCellValue($userInput); // Sanitize *right here*
    $worksheet->setCellValue('A1', $sanitizedInput); // Write sanitized value
  4. Consistency is Key: Ensure this is done consistently for every cell write operation that involves potentially untrusted data. Any omission creates a vulnerability.
  5. Test: Create test cases that write values starting with =, +, -, and @ to cells, then export the spreadsheet as CSV and open it in a spreadsheet program to verify that the values are treated as text, not formulas.
  • List of Threats Mitigated:

    • Formula Injection (CSV Injection): (Severity: High) - Prevents attackers from injecting formulas that could execute when the spreadsheet (or a CSV export) is opened.
  • Impact:

    • Formula Injection: Risk reduced from High to Very Low (within the context of data written by your application).
  • Currently Implemented:

    • A sanitizeCellValue() function is used within the writeDataToSheet() method of app/Services/SpreadsheetService.php, and it's called immediately before any setCellValue() calls.
  • Missing Implementation:

    • Missing in any direct cell-writing operations outside of the SpreadsheetService. A code review is needed to identify and fix these.
  1. Locate Spreadsheet Object: Identify where you have access to the main Spreadsheet object (usually after loading or creating a new spreadsheet).
  2. Access Properties: Use the getProperties() method to access the spreadsheet's metadata.
  3. Remove or Sanitize: Use methods like setCreator(), setLastModifiedBy(), setTitle(), etc., to either remove sensitive metadata fields (by setting them to empty strings) or sanitize them (e.g., replace specific values with generic placeholders).
    // Example (PhpSpreadsheet):
    $spreadsheet->getProperties()->setCreator('');
    $spreadsheet->getProperties()->setLastModifiedBy('');
    $spreadsheet->getProperties()->setTitle('');
    // ... (remove or sanitize other fields as needed)
  4. Timing: Perform this before saving, serving, or otherwise processing the spreadsheet in a way that might expose the metadata.
  5. Test: After implementing, generate a spreadsheet and examine its properties (using a suitable tool or library) to confirm that the sensitive metadata has been removed or sanitized.
  • List of Threats Mitigated:

    • Information Disclosure through Metadata: (Severity: Low to Medium, depending on the data) - Prevents the unintentional exposure of potentially sensitive information embedded in the spreadsheet's metadata.
  • Impact:

    • Information Disclosure: Risk reduced from Low/Medium to Very Low.
  • Currently Implemented:

    • Implemented in app/Services/SpreadsheetService.php within the prepareSpreadsheetForDownload() method, which is called before sending the spreadsheet to the user.
  • Missing Implementation:

    • None identified. The current implementation covers all known cases where spreadsheets are generated or modified.