Skip to content

CookieDeletionScopeMismatch ​

warning native on by default

Group: Probable bugs

Cookie deletion must target the same path and domain as creation. Use the original scope when expiring the cookie.

Example ​

php
<?php
setcookie("auth","token",["path"=>"/app"]); setcookie("auth","",["expires"=>1,"path"=>"/"]);

Reported:

  • line 2: Delete the cookie using its original path and domain.

Detection ​

  • Two resolved cookie setters (setcookie/setrawcookie) are consecutive statements and use the same literal name; the first stores a nonempty literal value, the second clears the value with a known positive expiry <=1. Highlight the deletion call when their scopes definitely differ:
    • the paths are both explicit nonempty literals and are not the same string, or
    • the domains are both explicit nonempty literals and still differ after lower-casing and dropping one leading dot.
  • Path and domain are read from the options array when the third argument is a literal array, otherwise from the fourth/fifth (or named path/domain) arguments. Option names are matched case-insensitively, as PHP does. The scalar form is proven when the third argument is absent or a known integer, or when a path, domain, secure or httponly argument is present (PHP refuses those next to an options array); the stored cookie's expiry may then be any expression such as time() + 3600.
  • Resolve builtin functions, classes, constants and methods; user-defined lookalikes are excluded. Follow only bounded local proof in one lexical scope.
  • Emit one finding per violating operation, not per supporting evidence statement. When the proof is inconclusive, nothing is reported.

Exceptions (no report) ​

  • Do not report unresolved or shadowed builtin names, unknown values, or incomplete receiver/type provenance. Unknown calls, aliases escaping, and intervening writes invalidate local proof. Similar code outside the stated detection contract is not a finding.
  • An omitted or empty path or domain is not a definite scope: the browser derives it from the request. A setting omitted or empty on either side never makes that setting differ, so setcookie("a", "v"); setcookie("a", "", 1, "/"); is not reported.
  • Domains differing only by letter case or by a leading dot are the same scope.
  • No report when a path or domain is not a literal string, when the third argument is neither a literal array nor a proven scalar expiry, when the options array has unknown keys, or when it spells one option name twice in different letter cases.
  • Both standard suppression forms suppress this native ID.

Fix ​

None. Choosing a repair requires intent or additional runtime information.

PHP versions ​

Available throughout supported PHP 5.3–8.5 where the referenced builtin/extension is available. Respect syntax/version-specific receiver contracts; unavailable APIs are not this rule’s concern.

Configure ​

In custos.json:

json
{
  "rules": {
    "CookieDeletionScopeMismatch": {
      "enabled": false
    }
  }
}

Suppress ​

Before the statement or declaration (or the first statement of the file):

php
// @custos-ignore CookieDeletionScopeMismatch

Released under the MIT License. Native rules and rules modeled on Php Inspections (EA Extended); independent clean-room implementation.