diff --git a/src/Rules/SensitiveParameterPropagationRule.php b/src/Rules/SensitiveParameterPropagationRule.php index dce6465..ee80958 100644 --- a/src/Rules/SensitiveParameterPropagationRule.php +++ b/src/Rules/SensitiveParameterPropagationRule.php @@ -143,6 +143,12 @@ private function resolveCallee(CallLike $node, Scope $scope): ?array return null; } + // Wrapping a sensitive value in SensitiveParameterValue is the + // intended safe pattern – never flag it as missing propagation. + if ($type->getObjectClassNames() === ['SensitiveParameterValue']) { + return null; + } + $method = $type->getMethod('__construct', $scope); $variant = $this->selectVariant($scope, $node, $method->getVariants(), $method->getNamedArgumentsVariants()); diff --git a/tests/Fixtures/Propagation/PropagationCases.php b/tests/Fixtures/Propagation/PropagationCases.php index 27c9198..a2e1977 100644 --- a/tests/Fixtures/Propagation/PropagationCases.php +++ b/tests/Fixtures/Propagation/PropagationCases.php @@ -5,6 +5,7 @@ namespace Tests\Fixtures\Propagation; use SensitiveParameter; +use SensitiveParameterValue; /** * Test fixture for SensitiveParameterPropagationRule: a parameter marked @@ -88,6 +89,12 @@ public function reassignedParameterIsNotFlagged(#[SensitiveParameter] string $pa $this->nonSensitiveMethod($password); } + // $value is marked sensitive and wrapped in SensitiveParameterValue - should NOT trigger warning + public function wrappedInSensitiveParameterValueIsNotFlagged(#[SensitiveParameter] string $value): void + { + new SensitiveParameterValue($value); + } + // Helper callee whose parameter is NOT sensitive public function nonSensitiveMethod(string $password): void { diff --git a/tests/Propagation/SensitiveParameterPropagationTest.php b/tests/Propagation/SensitiveParameterPropagationTest.php index 258e58c..a3f1836 100644 --- a/tests/Propagation/SensitiveParameterPropagationTest.php +++ b/tests/Propagation/SensitiveParameterPropagationTest.php @@ -6,23 +6,23 @@ $this->analyse([__DIR__.'/../Fixtures/Propagation/PropagationCases.php'], [ [ 'Parameter $password is marked #[\\SensitiveParameter] but is passed to a parameter ($password) that is not itself marked with #[\\SensitiveParameter]. Add the attribute there too or ignore with `@phpstan-ignore sensitiveParameter.propagation`.', - 24, + 25, ], [ 'Parameter $token is marked #[\\SensitiveParameter] but is passed to a parameter ($token) that is not itself marked with #[\\SensitiveParameter]. Add the attribute there too or ignore with `@phpstan-ignore sensitiveParameter.propagation`.', - 61, + 62, ], [ 'Parameter $secret is marked #[\\SensitiveParameter] but is passed to a parameter ($secret) that is not itself marked with #[\\SensitiveParameter]. Add the attribute there too or ignore with `@phpstan-ignore sensitiveParameter.propagation`.', - 67, + 68, ], [ 'Parameter $apiKey is marked #[\\SensitiveParameter] but is passed to a parameter ($apiKey) that is not itself marked with #[\\SensitiveParameter]. Add the attribute there too or ignore with `@phpstan-ignore sensitiveParameter.propagation`.', - 73, + 74, ], [ 'Parameter $secret is marked #[\\SensitiveParameter] but is passed to a parameter ($values) that is not itself marked with #[\\SensitiveParameter]. Add the attribute there too or ignore with `@phpstan-ignore sensitiveParameter.propagation`.', - 80, + 81, ], ]); });