ranierif.dev

Software Engineer

Protecting Sensitive Data with #[SensitiveParameter] and Other PHP Attributes
PHPAttributesSensitiveParameterDataProtecting

Protecting Sensitive Data with #[SensitiveParameter] and Other PHP Attributes

In PHP 8.2, the #[SensitiveParameter] attribute was introduced to help developers protect sensitive data. By marking a parameter as sensitive, you prevent its value from being exposed in stack traces, error messages, or debugging tools.

This is especially useful in contexts like payment processing, where information such as credit card numbers, CVV codes, or identity documents should never appear in logs.

In this article, we’ll explore how this attribute works, when to use it, and how it fits with other useful PHP attributes.


The problem

Imagine a payment processor that receives a customer’s credit card data:

class PaymentProcessor
{
    public function charge(string $cardNumber, string $cardCvv, int $amount): void
    {
        // ...
        throw new RuntimeException('Payment failed');
    }
}

$processor = new PaymentProcessor();
$processor->charge('4111111111111111', '123', 10000);

If something goes wrong, the exception will include a full stack trace with parameter values:

RuntimeException: Payment failed
#0 /app/index.php(12): PaymentProcessor->charge('4111111111111111', '123', 10000)

⚠️ The customer’s credit card number and CVV are now leaked in the log — a serious security and compliance issue (think PCI DSS, GDPR, etc.).


How #[SensitiveParameter] fixes this

We can annotate the sensitive parameters:

class PaymentProcessor
{
    public function charge(
        #[SensitiveParameter] string $cardNumber,
        #[SensitiveParameter] string $cardCvv,
        int $amount
    ): void {
        throw new RuntimeException('Payment failed');
    }
}

$processor = new PaymentProcessor();
$processor->charge('4111111111111111', '123', 10000);

Now the stack trace looks like this:

RuntimeException: Payment failed
#0 /app/index.php(12): PaymentProcessor->charge(Object(SensitiveParameterValue), Object(SensitiveParameterValue), 10000)

Instead of exposing the actual credit card data, PHP replaces it with a safe placeholder.


When to use it

You should apply #[SensitiveParameter] to any argument that contains:

  • Credentials (passwords, API tokens, private keys);
  • Personal data (credit card numbers, identity documents, SSN, etc.);
  • Anything that must not end up in logs.

Important: This attribute does not encrypt or hide the value in memory. It only prevents sensitive values from being dumped into stack traces and error logs.


Other useful attributes in PHP

Alongside #[SensitiveParameter], PHP provides other attributes that help improve code semantics:

  • #[\Deprecated] (since PHP 8.2) Marks methods or classes as deprecated, warning developers when they are used.
#[\Deprecated(reason: "Use chargeV2() instead")]
public function charge() {}
  • #[\AllowDynamicProperties]: Allows dynamic properties in classes even though they are deprecated by default in PHP 8.2.
  • #[\ReturnTypeWillChange]: Temporary compatibility for methods missing explicit return types.
  • Custom attributes: You can also define your own attributes for validation, caching, or API metadata.

Best practices

  • Be selective: Only mark parameters that are truly sensitive.
  • Use structured logging: Even with this attribute, mask or redact data manually in your logs.
  • Define team guidelines: Ensure everyone knows when and how to apply these attributes.

Conclusion

The #[SensitiveParameter] attribute is a small but powerful addition to PHP 8.2. It helps avoid accidental leaks of sensitive data, especially in high-risk domains such as payments and identity verification.

Combined with other PHP attributes, it contributes to writing secure, modern, and maintainable code.


Published on October 1, 2025