PitchDesk

Security

What we do, in specifics rather than adjectives, and what we have not built yet. Both halves matter if you are deciding whether to trust us with your bookings.

Last updated 21 August 2026.

The short version

  • Guest money is a direct charge on your own Stripe account. We never hold it, so there is nothing of yours for anyone to take from us.
  • Card numbers never touch our servers. Payment happens in Stripe Checkout.
  • Passwords are hashed with PBKDF2-HMAC-SHA512 at 210,000 iterations.
  • Sessions are HttpOnly, Secure, SameSite=Lax cookies, revocable server side. Every form carries a CSRF token.
  • Every Stripe webhook signature is verified and every event is deduplicated.
  • We keep the exact words, amount and date a guest agreed to when they authorised the balance payment, which is what protects the campsite in a chargeback.
  • Data sits in Cloudflare D1 in Western Europe, over TLS, backed up with point in time restore.
  • We have no two-factor authentication, no penetration test and no SOC 2 yet. That list is below, in full.

This box is the headline. The sections below are the detail, including the uncomfortable one.

Your money does not pass through us

This is a security property, not just a commercial one. Guest payments are Stripe direct charges on your own connected account, with no application fee. We never hold a balance for you, so there is no PitchDesk float to steal and no PitchDesk account for someone to redirect a payout from. If we were compromised tomorrow, the money already in your Stripe account would still be in your Stripe account.

Card numbers never reach our servers. Payment happens in Stripe Checkout, on Stripe's own pages, so the card details go from the guest's browser to Stripe. We store Stripe's identifiers and the amount, nothing more. That keeps the whole product out of PCI DSS scope beyond the simplest self assessment.

Passwords and logins

  • Passwords are hashed with PBKDF2-HMAC-SHA512 at 210,000 iterations, which is the OWASP figure for that algorithm, with a fresh 16 byte random salt for every password. We cannot read your password and neither can anyone who steals the database.
  • Password comparison is constant time, so the response cannot be timed to guess a hash.
  • Password reset links are single use, random, and expire.
  • We do not email you your password, because we do not have it.

Sessions and forms

  • Your login session is an opaque random identifier in an HttpOnly, Secure, SameSite=Lax cookie. HttpOnly means a script cannot read it. SameSite=Lax means another website cannot ride on it.
  • Sessions are stored server side, so logging out really does end them, and we can revoke one.
  • Every form that changes something carries a double submit CSRF token, compared in constant time.
  • Output is escaped by default by the templating layer. Somebody has to deliberately opt out to inject raw HTML, which makes cross site scripting a decision rather than an accident.
  • Owner written text, such as your arrival instructions, is escaped and turned into paragraphs rather than trusted as HTML.
  • Every database query is parameterised. No SQL is built by joining strings.

Webhooks and payment integrity

  • Every Stripe webhook signature is verified with HMAC-SHA256 against the endpoint secret before we act on it, using a constant time comparison.
  • Signatures older than five minutes are rejected, so a captured webhook cannot be replayed later.
  • Webhook event identifiers are recorded and deduplicated, so a retry cannot confirm a booking twice or take a payment twice.
  • Payment requests carry idempotency keys, so a network retry does not become a second charge.
  • Prices are always recalculated on the server from your own rates. The browser never tells the server what something costs.

What we store to protect the campsite

Two records exist purely so that a campsite can prove what happened. They are worth describing on a security page because they are the difference between winning and losing a dispute months later.

  • The mandate. When a guest agrees that the balance can be taken from their card, we store the exact words they were shown, the exact amount, the exact date and the moment they agreed. Not a tick in a box. A tick proves that a box existed. The wording, the amount and the date are what make the later charge an authorised merchant-initiated transaction, and under regulation 79 of the Payment Services Regulations 2017 a payer can reclaim a payment from their own bank where the authorisation did not state the exact amount. If it did, that route is simply closed. This is the single most useful thing on the page for an owner facing a chargeback.
  • The terms snapshot, including the cancellation ladder. We store the campsite's terms as they read at the moment of booking, together with the structured ladder that was in force then. A campsite changing its policy next season cannot change what an existing guest agreed to, and the refund a guest receives is computed from the same ladder they were shown in pounds and dates at the checkout. What was displayed and what is enforced are the same object.

Both records are written once and not edited afterwards.

Where the data lives

  • Everything runs on Cloudflare Workers, with the database in Cloudflare D1 in the Western European region.
  • TLS everywhere, with HTTPS enforced.
  • Encryption at rest is provided by the platform.
  • Backups are automatic, with point in time restore.
  • Every query is scoped to the campsite that owns the row, so one account cannot read another's bookings.
  • Booking management links use a long random token, not a guessable booking number.
  • The calendar feed a campsite can publish carries guest surnames, so it has its own private key, sixteen random bytes per site, appearing on no public page. It is deliberately not the public key that identifies the booking widget, because that one is visible in the code an owner pastes into their own website. Asking for a feed with the widget key returns nothing. The residual risk, stated rather than glossed: the URL is an address and not a login, so anyone an owner gives it to can read it until the key is rotated.
  • Responses carry X-Content-Type-Options: nosniff and a strict referrer policy.
  • The dashboard, the API and embedded booking pages are excluded from search engine indexing.

How it is built

  • Almost no third party runtime dependencies. There is no npm supply chain of any size to compromise, because the application code is the application.
  • No analytics script, no advertising pixel, no tag manager, no font CDN. Fonts are served from our own domain. Nothing third party executes in your browser on our pages.
  • The booking widget you embed in your own website is a small script that we serve, and it sets no cookies.
  • Secrets are held in the platform's secret store, never in the repository.

What we have not done yet

A security page that only lists strengths is marketing. Here is the honest other half, current at 21 August 2026.

  • No two-factor authentication on owner logins yet. It is the next security feature we will build. Today, a strong unique password is your protection.
  • No independent penetration test yet. The application has been reviewed internally and built to a checklist, which is not the same thing as somebody being paid to break it.
  • No ISO 27001 and no SOC 2 report. Those cost more than this product makes at the moment. If your own compliance process requires one, PitchDesk is not the right choice for you today, and we would rather tell you now than at renewal.
  • No bug bounty programme. We will still thank you properly and credit you if you want it.
  • Rate limiting is basic. We rely on the platform's protection at the edge rather than fine grained per account limits on login attempts. Improving that is on the list.
  • No audit log you can read. We record booking events internally, but there is not yet a screen where you can see who changed what and when.
  • Restores are tested, but not on a published schedule. We have restored from backup and know that it works. We do not yet run drills to a documented calendar.
  • Small team. There is no 24 hour on-call rota. Out of hours, a serious problem gets attention when it is seen.

When one of these changes, this list changes with it and the date at the top of the page moves.

Reporting a vulnerability

Email hello@pitchdesk.co.uk with the subject line "security". Tell us what you found and how to reproduce it. You will get a human reply within one working day and we will tell you what we are doing about it.

Please do not run automated scanners against the live service, do not access or change data that is not yours, and do not degrade the service for the campsites using it. Test against your own trial account. If you report something in good faith and stay within those lines, we will not take legal action against you.


The rest of the small print

Questions about any of this go to hello@pitchdesk.co.uk and a person will answer.