Good evening TicketsCAD user community,
I am writing to let you know about two security problems in TicketsCAD.
Both are fixed if you are running the current version. The first fix
shipped in version 4.2.3; if you are on Windows with IIS specifically, a
follow-up correction that matters to you shipped in 4.2.4. Version 4.2.6
is current today and has everything below.
I would rather tell you about these plainly than have you find out some other
way.
THE FIRST: private folders were being served over the web
TicketsCAD is installed by pointing your web server at the folder you unpacked
it into. That means the web server publishes everything in that folder unless
you tell it not to - and until now, nothing that shipped with TicketsCAD told
it to. Several folders that were never meant to be reachable from a browser
were reachable from a browser.
The one that matters most is the backups folder. TicketsCAD writes its database
backups there, and a backup is a complete copy of your system: incidents,
addresses, phone numbers, your members' contact details, patient details if you
record them, and the password hash for every account.
This is not theoretical. On July 30th, from an ordinary internet connection
with no login and no password, I downloaded a complete 110 MB database backup
from a live TicketsCAD install over the public internet. The folder also
offered a browsable list of every archive in it, so there was nothing to guess.
Two other folders, sql and tools, were listed the same way, and one script in
the sql folder would actually run when requested over the web.
Who is affected: any install where the web server was not configured by hand to
block these folders. That is the default, so assume you are affected until you
have checked. If your site is on the open internet this is serious. If it is on
a closed network, the exposure is to anyone already on that network.
If you run TicketsCAD on Windows with IIS: the first fix, in 4.2.3, moved
backups to a location that turned out to still be served by IIS on a
standard install. That is corrected in 4.2.4. If you are on Windows and
have not updated past 4.2.3, please update again.
THE SECOND: the External API's "require TLS" setting was not being enforced
If you use the External API and you left "require TLS" on, TicketsCAD was
supposed to refuse any request that did not arrive encrypted. It did not. A
request over plain HTTP carrying a valid token was answered normally, with real
data, while the setting continued to report that TLS was required.
There are two separate ways this failed:
Every web server - Apache, nginx and IIS alike. The check trusted a header
that the caller supplies. Anyone who could reach the API could add one header
to their request and walk straight through the check. This one is not
specific to any platform, and it needed no misconfiguration on your part
beyond the API being reachable over plain HTTP.
IIS additionally. IIS reports an unencrypted request by setting a variable to
the word "off", where Apache and nginx leave it unset. The check asked
whether the variable was empty, and the word "off" is not empty - so on IIS
the check never fired at all, with no header needed.
Please do not skip this section because you are not on IIS. The first defect
reaches you.
What this does and does not mean. It is not a way in for a stranger - a caller
still needs a valid API token, and without one they get nothing. What it means
is that a protection you deliberately switched on was quietly not there, so
integrations were configured over plain HTTP and kept working, and nobody was
told. On plain HTTP your API token and every record it returns travel in the
clear, readable by anyone on the network path. A token captured that way can be
reused.
The same underlying mistake caused two other things you may have been chasing
without knowing the cause. On IIS over plain HTTP, mobile and PWA logins could
not hold a session - users were bounced back to the login screen over and over.
And OwnTracks device setup handed out web addresses beginning http:// on sites
that are actually running HTTPS. Both are fixed by the same change.
This was reported to me privately by Ron Jones, who found it, wrote it up
carefully with a working proof of concept, and sent it to me rather than
posting it publicly. Chasing his report is what uncovered the header problem,
which is the broader of the two and which nobody had reported. One careful
private report turned a platform-specific bug into a fix for nineteen
inconsistent places in the code. I am grateful, and I have credited him in the
advisory. If you ever find something like this in TicketsCAD, that is exactly
the right way to handle it - please see SECURITY.md in the repository.
CHECK YOUR OWN INSTALL - ABOUT A MINUTE
Replace your-site with your own address. You can paste these into a browser
instead of running them if you prefer.
curl -s -o /dev/null -w "backups %{http_code}\n"
https://www.google.com/url?q=https://your-site/backups/&source=gmail&ust=1786075378304000&sa=E curl -s -o /dev/null -w "sql %{http_code}\n"
https://www.google.com/url?q=https://your-site/sql/run_migrations.php&source=gmail&ust=1786075378304000&sa=E curl -s -o /dev/null -w "tools %{http_code}\n"
https://www.google.com/url?q=https://your-site/tools/&source=gmail&ust=1786075378304000&sa=EReading the result:
403 or 404 Good. That folder is blocked.
200 Affected. Act on this today.
301 or 302 Inconclusive - you are being redirected. Run it again against
the address you land on.
Do not stop at a 403 on the backups folder itself - ask for one real backup
file by name too (you can find a filename under Settings, Backup / Maintenance).
On some servers the folder listing is blocked while the file inside it still
downloads in full, which is the worst case dressed up as the good result.
If your site is http rather than https, use that instead.
From 4.2.3 onward TicketsCAD runs these same checks against itself and shows
the answer under Settings, System Health, in the "Web exposure" row. If that
row is green, you are covered - and it will turn red again if a future server
change ever re-opens one of these.
ONE REQUIRED STEP IF YOU RUN BEHIND A PROXY
This applies to you if something else terminates your HTTPS and passes the
request along to TicketsCAD - Cloudflare, Nginx Proxy Manager, IIS ARR, a load
balancer, or similar.
The fix works by no longer taking a request header's word for whether the
connection was encrypted. That header is exactly what your proxy uses to tell
TicketsCAD the original request was HTTPS. So after updating you must list your
proxy's address in the trusted_proxies setting, or legitimate API requests will
correctly be refused with a 426 error. The default covers only the case where
the proxy is on the same machine.
If it does refuse a request, the error now says plainly that a forwarded header
claimed HTTPS from an address that is not trusted, so you get a diagnosis
rather than a silent failure. But you do still have to make the change.
WHAT TO DO
Updating to the current version, 4.2.6, fixes both problems, including the
Windows/IIS correction described above. If you can update, do that, make the
trusted_proxies change above if it applies to you, and you are done.
If you cannot update right away, either of these closes the first problem now:
Move your backups out of the published folder. On Linux:
cd /path/to/your/ticketscad
mkdir -p ../backups
mv backups/ticketscad-* ../backups/
On Windows/IIS, the equivalent "one level up" move is NOT safe by default -
it can land inside another site's published folder. See the advisory link
below for the Windows-specific steps.
Or block the folders at your web server. The exact configuration differs by
server, and the advisory has a copy-and-paste block for Apache, nginx and
IIS - the IIS section was itself corrected on 2026-08-02, so if you looked at
it before that date, it is worth another look. Two things that catch people
out: nginx does not read .htaccess files at all, so an .htaccess fix does
nothing there, and on Apache an .htaccess file is ignored silently if
AllowOverride is set to None.
For the second problem, without updating:
Stop serving TicketsCAD over plain HTTP. Redirect all HTTP traffic to HTTPS
at the web server, or stop listening on port 80. That closes both variants
regardless of what the application code does, and it is the durable answer.
Or revoke any External API tokens you are not actively using, under Settings,
External API Tokens. Neither variant reaches your data without a valid token.
If your API has been reachable over plain HTTP, treat the tokens that were used
over it as disclosed, and rotate them.
IF YOUR BACKUPS FOLDER WAS EXPOSED
If the first check returned 200, work through this. None of it is urgent to the
minute, but none of it should wait a month.
First, find out whether anything was actually taken. If your web server keeps
access logs, search them for requests to those folders - the advisory has the
exact commands. A 200 response to a backup file from an address you do not
recognise means a copy of your database left your server. Search engine
crawlers count.
Then:
1. Have every TicketsCAD user set a new password. The archive contains
password hashes. They are bcrypt, which is slow to crack, but slow is not
impossible for a weak password.
2. Tell anyone who used their TicketsCAD password anywhere else to change it
there too. This is the most likely real harm to come out of this.
3. Rotate your database password, in config.php and in the database itself.
4. Rotate any integration credentials stored in settings - SMTP, SMS, Slack,
Zello, APRS-IS passcodes, webhook secrets, API tokens.
5. Review the audit log under Settings for logins or changes you cannot
account for.
6. Consider whether you have a duty to notify anyone. The archive may hold
personal information about your members and about the public, and in some
deployments patient details. Whether that has to be reported, and to whom,
depends on your jurisdiction and on what your agency handles. If you have
counsel, a privacy officer, or a parent agency, ask them - it is easier
early than late.
IF YOU HAVE SOMETHING RECEIVING TICKETSCAD WEBHOOKS
This is not one of the two problems above, but it affects the same people who
would act on this email, so it belongs here.
Our integrator guide described a signature scheme that the software did not
actually implement. A receiver written by following that guide computed the
wrong value and compared it against the wrong string, so it rejected every
genuine delivery as a forgery. The usual way people get past "signature
verification never works" is to switch verification off - and if that is what
happened at your end, your receiver is currently acting on any request that
reaches its address, from anyone who knows it.
The guide now matches what the software actually sends. Deliveries also now
carry a timestamp and a delivery identifier, so a receiver can reject a stale
or duplicated delivery, which it previously had no way to do.
Nothing breaks when you update. The new signature arrives in a new header and
the existing one keeps working exactly as before. But if you turned
verification off, please turn it back on once you have re-read the guide:
https://www.google.com/url?q=https://github.com/openises/TicketsCAD/blob/main/docs/WEBHOOKS-INTEGRATOR-GUIDE.md&source=gmail&ust=1786075378304000&sa=ETHE FULL DETAIL
Both problems are written up in full, including exactly what was tested, what
changed, and - for the first one - a correction covering Windows/IIS added
after the initial fix:
Private folders served over HTTP
https://www.google.com/url?q=https://github.com/openises/TicketsCAD/security/advisories/GHSA-rrp6-pqhj-w5wj&source=gmail&ust=1786075378304000&sa=E External API TLS enforcement bypass
https://www.google.com/url?q=https://github.com/openises/TicketsCAD/security/advisories/GHSA-984v-rw78-3223&source=gmail&ust=1786075378304000&sa=ERelease notes for the current version:
https://www.google.com/url?q=https://github.com/openises/TicketsCAD/releases/tag/v4.2.6&source=gmail&ust=1786075378304000&sa=EI am sorry these existed. The first one in particular was a default that should
never have shipped, and it was there for a long time. Both are closed now, and
TicketsCAD also checks itself for the first problem on every visit to the
System Health page, so it cannot quietly come back.
If you are not sure how to run the check above, or you run it and get a 200 and
want a hand, reply to this and I will walk you through it.
73,
Eric