App Locksmith
Sample

This is a sample. Bramble isn't a real company and none of this describes a real client's app. I wrote it to show exactly what a buyer receives, down to the wording.

Pre-sale security review: Bramble

An independent review prepared for disclosure to prospective purchasers and their advisers. All findings were remediated and retested before this report was issued.

Prepared for
Bramble Software Ltd, for disclosure to prospective purchasers
Subject
Bramble, a scheduling product for veterinary practices
Built with
Cursor, Rails 7 and Postgres, hosted on Render
Review dates
9 to 18 February 2026
Report dated
20 February 2026
Version
Final, version 1.0
Reference
AL-2026-007

Statement

I reviewed the security of Bramble between 9 and 18 February 2026, at the request of its owner, for the purpose of disclosure to prospective purchasers.

I examined the application's source code, its production configuration, its database and its hosting, and I tested the running application as both an authenticated user and an unauthenticated stranger. The scope, and the limits of that scope, are set out below.

I identified five issues. All five were remediated by the seller's engineer or by me, and all five were retested by me after remediation. As at the date of this report there are no outstanding security findings from this review.

This report describes the application as it stood on 19 February 2026. It is not a certification, and it is not a warranty as to the absence of security defects. Its value is that it states plainly what was examined, what was found, what was done, and by whom.

Summary of findings

Five issues were identified: two rated High, two Medium and one Low. None were rated Critical.

Two of the five concerned access control between customer accounts, which is the category a purchaser should weight most heavily in a multi-tenant product, because it bears directly on whether one customer can reach another customer's data. Both were remediated and retested.

The remaining three concerned operational practice rather than the code: administrative actions were not logged, backups had never been restored to verify they worked, and the application disclosed its framework version. All three were addressed, and the backup restoration was timed and recorded.

5issues identified
5remediated and retested
0outstanding

What was examined

  • The application source code at commit a71c3e9, the commit deployed to production on 18 February 2026.
  • The production environment on Render: configuration, environment variables, network exposure and deployment process.
  • The production database: schema, access rules, roles and what each role can reach.
  • The running application, tested as an authenticated user of two separate customer accounts and as an unauthenticated visitor.
  • Third-party integrations and the data passed to each of them.
  • The seller's own access: who holds credentials to what, and how those would transfer on a sale.

What was not examined

  • The security of Render, Postgres, Stripe or any other supplier. How Bramble uses them was examined; how they are built was not.
  • The seller's own devices, email accounts and identity providers, other than to record who holds which credentials.
  • Bramble's customers, their systems, or any data they hold outside the application.
  • Financial, legal, tax and commercial matters of every kind. Nothing in this report speaks to the value of the business.
  • Any code or configuration changed after 19 February 2026.

Findings

Each finding is described as it stood at the time of the review, followed by the remediation and the date it was retested.

1

Reporting endpoint returned data across customer accounts

HighRemediated 17 Feb, retested 18 Feb

What it means
The practice reporting endpoint filtered results by date and practice name, but not by the account making the request. A user of one veterinary practice could retrieve appointment data belonging to another practice by supplying that practice's name.
What could have happened
A customer, or anyone with a customer's credentials, could have read appointment records including animal names, owner names and contact details for practices other than their own. In a product sold to competing practices in the same town, this is the finding most likely to end a customer relationship.
What I did about it
The endpoint now derives the account from the authenticated session and ignores any account identifier supplied by the caller. An equivalent check was added at the database level so the rule holds independently of the application code. A test covering cross-account access was added to the build.
Whether anyone used it
Application logs retained for 90 days were reviewed. All requests to this endpoint in that period supplied the caller's own practice name. Records before that period are not retained and cannot be checked.

What I sawGET /api/reports?practice=<other account> returned 214 appointment records belonging to a different account

2

Password reset tokens did not expire

HighRemediated 16 Feb, retested 18 Feb

What it means
Password reset links remained valid indefinitely and remained valid after use. A link issued in 2024 was still able to set a new password in February 2026.
What could have happened
Anyone with access to a historic reset email, including through a compromised or recycled mailbox, could take over the associated account at any time.
What I did about it
Reset tokens now expire one hour after issue and are invalidated on first use. Existing outstanding tokens were invalidated at the time of the fix.
Whether anyone used it
No indication of use was found. Reset events are logged only from February 2026, so earlier use could not be ruled out.

What I sawA reset token issued 11 months previously successfully set a new password

3

Administrative actions were not logged

MediumRemediated 18 Feb, retested 19 Feb

What it means
Actions taken through the administrative interface, including changes to customer records and manual adjustments to billing, were not recorded. There was no record of who did what, or when.
What could have happened
No direct security impact. The consequence is evidential: neither the seller nor a purchaser could demonstrate what administrative access had been used for, which is a question a purchaser's advisers routinely ask and a customer may ask after any incident.
What I did about it
Administrative actions are now written to an append-only log recording the actor, the action, the affected record and the time. The log is retained for 400 days.
Whether anyone used it
Not applicable. Historic administrative activity cannot be reconstructed, and a purchaser should treat the period before 18 February 2026 as unlogged.

What I sawNo audit table, and no administrative events in the application log

4

Backups were taken but had never been restored

MediumRemediated 13 Feb, retested 19 Feb

What it means
Nightly database backups had run without failure for two years. None had ever been restored, so it was not known whether they could be. An untested backup is a plan, not a control.
What could have happened
In the event of data loss, the recovery time and the completeness of recovery would both have been unknown at the worst possible moment.
What I did about it
A backup was restored to an isolated database on 13 February 2026 and verified against production row counts. The restoration took 22 minutes and was complete. The procedure is documented, and a quarterly restoration test is now scheduled.

What I sawNo restoration recorded in the provider's history since the account was created

5

Server responses disclosed the framework and version

LowRemediated 18 Feb, retested 19 Feb

What it means
HTTP responses named the web framework and its exact version.
What could have happened
No direct impact. It shortens the work of anyone scanning for known weaknesses in that version, which matters chiefly during the window between a vulnerability being published and the application being updated.
What I did about it
The header was removed.

What I sawServer header naming the framework and point release on every response

Matters outstanding

None. All five findings were remediated and retested before this report was issued, and the report describes the application after those changes.

A purchaser should note that this is a statement about the findings of this review on these dates. It is not a statement that no other security defects exist, and no review can support that claim.

Points for a purchaser to note

These are not security defects, and none of them is a criticism of how the business has been run. They are the operational matters a purchaser would otherwise discover after completion, and each is cheap to resolve at the point of transfer.

  • All credentials are held by one personThe seller holds sole access to the hosting account, the domain registrar, the payment processor and the database. There is no second administrator and no documented recovery route. This is normal for a business of this size and should be a completion item.
  • The domain is registered to a personal accountBramble's domain sits in the seller's personal registrar account, not a company one. Transferring it is straightforward but must be done deliberately, and the product stops working if it lapses.
  • Backups are held with the same provider as productionRestoration is verified, but a failure of the hosting provider's account, including a billing or suspension failure, would affect production and backups together. An offsite copy is inexpensive.
  • One engineer holds all the operational knowledgeDeployment, database and third-party integrations are understood by one person. The code is clear and the README is current, but a purchaser should budget for a handover period.
  • No formal incident process existsNothing has gone wrong to date. A purchaser inheriting a customer base should expect to write one.

Statement of independence

I was engaged and paid by the seller. A purchaser is entitled to weigh that, and should.

What it does not mean is that the findings were negotiated. My engagement terms, which the seller has agreed may be disclosed, provide that the seller may decline to publish this report in full but may not alter its content, remove a finding or change a rating. This report is published in full.

I hold no interest in Bramble, no interest in the outcome of any sale, and my fee was fixed before the review began and does not depend on what was found or on whether a sale completes.

I am not an accounting firm and this is not an audit in the accounting sense. It is the work of one named engineer, and it stands or falls on that.

Limitations

  • This report describes the application as at 19 February 2026 and says nothing about its state at any later date. Code changes after that date were not examined.
  • A security review examines a defined scope over a defined period. It cannot demonstrate the absence of defects, and any report claiming otherwise should be treated with suspicion.
  • Findings are described after remediation. The pre-remediation state is described in each finding so that a purchaser can judge the original exposure.
  • Where a finding could not be ruled out historically, because logs were not retained, that is stated in the finding rather than omitted.
  • This report is to be read in full. Individual findings quoted in isolation will misrepresent both the application and this review.

Nate Parker

App Locksmith, applocksmith.com

Signed 20 February 2026. To confirm this report is genuine and unaltered, email nate@applocksmith.com quoting reference AL-2026-007. Questions from a purchaser's technical adviser are answered for 30 days from the date above.

Selling your app?

This is the document a buyer's technical adviser reads. It is written to be handed over, and it says who paid for it on its own front page, because that is the first thing a careful buyer checks.