DEV Community

Cover image for PHP Attribute: SensitiveParameter
Travis van der F.
Travis van der F.

Posted on

PHP Attribute: SensitiveParameter

If you're not using it, the risk is already live. The SensitiveParameter attribute introduced in PHP 8.2 is a thoughtful security feature designed to prevent accidental exposure of sensitive data in stack traces, a small piece of metadata with a big safety payoff. It lets you mark specific function or method parameters as “do not show this if something goes wrong.” When PHP builds a backtrace (stack trace) for an exception, error, or debugging output that includes arguments, the value of any parameter marked sensitive is automatically wrapped in a protective wrapper rather than the actual value. In practice, that means a password, API key, access token, or other secret is far less likely to appear in logs, error pages, monitoring dashboards, or bug reports, where it can be copied, indexed, forwarded, or accidentally exposed.

What makes it especially useful is that it targets a very common leak path: “helpful” diagnostics. It does not encrypt anything and does not prevent your code from using the value normally; it simply reduces accidental disclosure when PHP reports what happened. Think of it as a seatbelt for observability: it will not replace good security practices like careful logging policies, secret management, and least-privilege access, but it meaningfully reduces the risk that a single crash becomes a credential leak. PHP also provides the related SensitiveParameterValue class, which prevents sensitive values from being exposed in traces.

The SensitiveParameter Attribute

This attribute marks function or method parameters as sensitive, instructing PHP to redact their values in stack traces. Instead of showing the actual value, PHP displays Object(SensitiveParameterValue) for the parameter.

class GardenAccess
{
    public function unlockGreenhouse(
        string $gardenerName,
        #[SensitiveParameter] string $accessCode): bool
    {
        // validate access code
        if (strlen($accessCode) < 8) {
            throw new InvalidArgumentException('Access code too short');
        }

        return $this->validateAccess($gardenerName, $accessCode);
    }

    private function validateAccess(string $gardenerName, string $accessCode): bool
    {
        // access validation logic (simplified example)
        $validCode = 'tomato2024secret';
        return $accessCode === $validCode;
    }
}

$garden = new GardenAccess();

try { // usage (plain text user and password (simplified example)
    $garden->unlockGreenhouse('Travis', 'carrot');
}
catch (Exception $e)
{
    echo $e->getMessage()."\n";
    echo $e->getTraceAsString();
}
Enter fullscreen mode Exit fullscreen mode

In the stack trace, the $accessCode parameter appears as Object(SensitiveParameterValue) rather than showing "carrot", protecting the sensitive data even though it was invalid.

The SensitiveParameterValue Class

While #[SensitiveParameter] handles automatic redaction, the SensitiveParameterValue class provides manual control over sensitive values. This proves useful when working with values that need protection beyond just function parameters.

class VegetablePatchConfig
{
    private SensitiveParameterValue $irrigationApiKey;

    public function __construct(string $apiKey)
    {
        $this->irrigationApiKey = new SensitiveParameterValue($apiKey);
    }

    public function connectToIrrigationSystem(): void
    {
        $actualKey = $this->irrigationApiKey->getValue();

        // key for API authentication
        if (!$this->authenticateWithKey($actualKey)) {
            throw new RuntimeException('Irrigation system authentication failed');
        }
    }

    private function authenticateWithKey(string $key): bool
    {
        // authentication logic (simplified example)
        return strlen($key) > 0;
    }
}
Enter fullscreen mode Exit fullscreen mode

The getValue() method retrieves the actual sensitive value when needed, but the wrapped object itself won't expose the value in stack traces or when debugging.

When to Use these Features

These attributes shine in scenarios involving:

  • Authentication credentials (passwords, tokens, orbAPI keys).
  • Encryption keys or secrets.
  • Personal identification numbers.
  • Credit card details or payment information.
  • Any data that should never appear in logs.

Best Practice(s)

Apply #[SensitiveParameter] liberally to any parameter that handles confidential information. The performance impact is negligible, and the security benefit is substantial. Remember that this feature only protects values in stack traces—it doesn't encrypt data or prevent logging elsewhere in the application. For properties or variables that require similar protection, wrap them in SensitiveParameterValue instances. This ensures consistent security handling throughout the codebase.

The combination of these features reflects PHP's recognition that security often breaks down not through sophisticated attacks, but through simple oversights, such as forgetting that error logs might expose sensitive data. By making it easy to mark and protect sensitive parameters, PHP helps developers build more secure applications by default. Perhaps a bit too long for an attribute article, but worth exploring and explaining.

Mistakes do happen, one stack trace, one exposed secret.
#HappyCoding

Top comments (0)