[FIX] computeFair: validazione range input (no overflow DECIMAL, no negativi/NaN/vuln>1) - finding review
TEF cap 1M ev/anno, LM cap 1000 mld EUR -> ALE resta entro DECIMAL(16,2). Rifiuta valori negativi/non finiti e vuln>1 con 422. Verificato E2E: valido 200; LM enorme/vuln>1/negativo -> 422. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a3f821122a
commit
d89f73bf2d
@ -340,6 +340,12 @@ class RiskController extends BaseController
|
|||||||
$this->jsonError('Rischio non trovato', 404, 'NOT_FOUND');
|
$this->jsonError('Rischio non trovato', 404, 'NOT_FOUND');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Limiti coerenti con le colonne DB per evitare overflow:
|
||||||
|
// fair_tef_* DECIMAL(10,2) -> max ~99.999.999 | fair_lm_* DECIMAL(14,2) -> max ~999 mld
|
||||||
|
// ale_* DECIMAL(16,2). Cappiamo TEF e Loss Magnitude a valori realistici così che
|
||||||
|
// ALE = TEF * vuln * LM resti entro DECIMAL(16,2).
|
||||||
|
$TEF_MAX = 1000000.0; // 1M eventi/anno (limite prudenziale)
|
||||||
|
$LM_MAX = 1000000000000.0; // 1.000 mld EUR per evento
|
||||||
$params = [
|
$params = [
|
||||||
'tef_min' => (float) $this->getParam('tef_min', 0),
|
'tef_min' => (float) $this->getParam('tef_min', 0),
|
||||||
'tef_ml' => (float) $this->getParam('tef_ml', 0),
|
'tef_ml' => (float) $this->getParam('tef_ml', 0),
|
||||||
@ -349,6 +355,25 @@ class RiskController extends BaseController
|
|||||||
'lm_ml' => (float) $this->getParam('lm_ml', 0),
|
'lm_ml' => (float) $this->getParam('lm_ml', 0),
|
||||||
'lm_max' => (float) $this->getParam('lm_max', 0),
|
'lm_max' => (float) $this->getParam('lm_max', 0),
|
||||||
];
|
];
|
||||||
|
// Validazione: niente valori negativi o NaN/inf
|
||||||
|
foreach ($params as $k => $v) {
|
||||||
|
if (!is_finite($v) || $v < 0) {
|
||||||
|
$this->jsonError("Parametro FAIR non valido: {$k}", 422, 'INVALID_FAIR_PARAM');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (['tef_min', 'tef_ml', 'tef_max'] as $k) {
|
||||||
|
if ($params[$k] > $TEF_MAX) {
|
||||||
|
$this->jsonError("Frequenza eventi ({$k}) oltre il limite ammesso ({$TEF_MAX})", 422, 'FAIR_OUT_OF_RANGE');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (['lm_min', 'lm_ml', 'lm_max'] as $k) {
|
||||||
|
if ($params[$k] > $LM_MAX) {
|
||||||
|
$this->jsonError("Magnitudo di perdita ({$k}) oltre il limite ammesso ({$LM_MAX})", 422, 'FAIR_OUT_OF_RANGE');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($params['vuln'] > 1) {
|
||||||
|
$this->jsonError('La vulnerabilità deve essere compresa tra 0 e 1', 422, 'FAIR_OUT_OF_RANGE');
|
||||||
|
}
|
||||||
$iterations = (int) $this->getParam('iterations', FairService::DEFAULT_ITERATIONS);
|
$iterations = (int) $this->getParam('iterations', FairService::DEFAULT_ITERATIONS);
|
||||||
|
|
||||||
$sim = FairService::simulate($params, $iterations);
|
$sim = FairService::simulate($params, $iterations);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user