Merge pull request #11901 from snipe/security/escape_formats_in_csv

Use `EscapeFormula()` in CSV export
This commit is contained in:
snipe 2022-09-30 11:59:11 -07:00 committed by GitHub
commit b9419c7454
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 44 additions and 2 deletions

View file

@ -2729,6 +2729,15 @@
"contributions": [ "contributions": [
"code" "code"
] ]
},
{
"login": "Vautia",
"name": "Vautia",
"avatar_url": "https://avatars.githubusercontent.com/u/111710123?v=4",
"profile": "https://github.com/Vautia",
"contributions": [
"security"
]
} }
] ]
} }

View file

@ -173,3 +173,4 @@ IMPORT_MEMORY_LIMIT=500M
REPORT_TIME_LIMIT=12000 REPORT_TIME_LIMIT=12000
REQUIRE_SAML=false REQUIRE_SAML=false
API_THROTTLE_PER_MINUTE=120 API_THROTTLE_PER_MINUTE=120
CSV_ESCAPE_FORMULAS=true

View file

@ -22,6 +22,8 @@ use Illuminate\Support\Facades\View;
use Input; use Input;
use League\Csv\Reader; use League\Csv\Reader;
use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\HttpFoundation\StreamedResponse;
use League\Csv\EscapeFormula;
/** /**
* This controller handles all actions related to Reports for * This controller handles all actions related to Reports for
@ -411,6 +413,7 @@ class ReportsController extends Controller
$customfields = CustomField::get(); $customfields = CustomField::get();
$response = new StreamedResponse(function () use ($customfields, $request) { $response = new StreamedResponse(function () use ($customfields, $request) {
\Log::debug('Starting streamed response'); \Log::debug('Starting streamed response');
\Log::debug('CSV escaping is set to: '.config('app.escape_formulas'));
// Open output stream // Open output stream
$handle = fopen('php://output', 'w'); $handle = fopen('php://output', 'w');
@ -666,6 +669,9 @@ class ReportsController extends Controller
$executionTime = microtime(true) - $_SERVER['REQUEST_TIME_FLOAT']; $executionTime = microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'];
\Log::debug('Walking results: '.$executionTime); \Log::debug('Walking results: '.$executionTime);
$count = 0; $count = 0;
$formatter = new EscapeFormula("`");
foreach ($assets as $asset) { foreach ($assets as $asset) {
$count++; $count++;
$row = []; $row = [];
@ -855,7 +861,17 @@ class ReportsController extends Controller
$row[] = $asset->$column_name; $row[] = $asset->$column_name;
} }
} }
fputcsv($handle, $row);
// CSV_ESCAPE_FORMULAS is set to false in the .env
if (config('app.escape_formulas') === false) {
fputcsv($handle, $row);
// CSV_ESCAPE_FORMULAS is set to true or is not set in the .env
} else {
fputcsv($handle, $formatter->escapeRecord($row));
}
$executionTime = microtime(true) - $_SERVER['REQUEST_TIME_FLOAT']; $executionTime = microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'];
\Log::debug('-- Record '.$count.' Asset ID:'.$asset->id.' in '.$executionTime); \Log::debug('-- Record '.$count.' Asset ID:'.$asset->id.' in '.$executionTime);
} }

View file

@ -394,7 +394,7 @@ return [
'allow_purge' => env('ALLOW_DATA_PURGE', false), 'allow_purge' => env('ALLOW_DATA_PURGE', false),
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Allow Backup Deletion | Allow Backup Deletion
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
@ -405,4 +405,20 @@ return [
'allow_backup_delete' => env('ALLOW_BACKUP_DELETE', false), 'allow_backup_delete' => env('ALLOW_BACKUP_DELETE', false),
/*
|--------------------------------------------------------------------------
| Escape Excel formulas in CSV exports
|--------------------------------------------------------------------------
|
| This determins whether or not we should escape Excel formulas in CSV exports.
| This can be UNSAFE in untrusted environments, and therefore defaults to true
| so that Excel forumals WILL be escaped in CSV exports, however if your workflow
| is designed around using formulas in your fields, you
| you can set CSV_ESCAPE_FORMULAS to 'false' in your .env.
|
*/
'escape_formulas' => env('CSV_ESCAPE_FORMULAS', true),
]; ];