Skip to content

Security: amiranmanesh/payvand

Security

SECURITY.md

Security policy

Supported versions

Version Supported
1.2.x
1.0.x – 1.1.x ❌ — upgrade
< 1.0

Releases before 1.2.0 verify payments without comparing the settled amount to the ordered one, which lets a payment token replayed onto another order verify cleanly; AsanPardakht and Sepehr additionally accept a settlement key chosen by the payer. See the 1.2.0 changelog for the full list.

Reporting a vulnerability

Please do not open a public issue.

Use GitHub's private reporting — Security → Report a vulnerability — and include:

  • the affected version and gateway,
  • what an attacker can achieve,
  • a reproduction, with all credentials, tokens, card numbers and IBANs redacted.

You can expect a first answer within a week and a fix or a plan within a month, depending on severity.

What counts as a vulnerability here

Payvand handles money and terminal credentials, so the interesting classes are:

  • a verification path that reports success when the provider did not settle the payment,
  • an amount that can be influenced by the payer (the callback is never trusted for amounts — a way around that is a bug),
  • credentials, tokens or PANs leaking into logs, errors or the Raw fields,
  • a flaw in the signing or envelope code under internal/cryptox,
  • a callback parser that can be made to attribute a payment to the wrong order.

What does not

  • A provider rejecting a request because its own API changed. Open a normal issue.
  • Weak algorithms mandated by an acquirer's protocol — 3DES-ECB for Sadad, RSA over SHA-1 for Pasargad. They are the providers' contracts; Payvand implements them and documents them as such.

Guidance for integrators

  • Never build the verification amount from the callback. Read it from your own order — Callback.VerifyRequest(amount) is shaped to make that the easy path.
  • Treat Callback.Succeeded as a hint. A payment is final only when Verify returns without error.
  • Store the payment token before redirecting the payer; it is the only handle on the transaction afterwards.
  • Keep terminal keys out of the repository. .gitignore already excludes *.pem, *.key, *.p12 and keys/.
  • The logger receives request and response bodies with the credential fields masked — Iranian gateways authenticate on the body, so Mellat's userPassword, Parsian's LoginAccount, Pay.ir's api, Zibal's merchant, TOP's Pin and the OAuth password grants never reach it. Raw and PurchaseResponse.Extra are not masked: they carry the provider's answer verbatim for support and auditing, so redact them yourself before they reach a log aggregator.
  • Leave WithSkipTLSVerify off unless a Shaparak host genuinely serves an incomplete chain, and scope it to that gateway only.

There aren't any published security advisories