Security
StatDataViewer is built for clinical trial data, so we treat security as part of the product, not a checkbox. This page is the plain-language result of a security review of StatDataViewer completed on 3 November 2026. It lists everything the application sends, listens for and stores, how each edition is protected, which third-party components it ships, and what the review found.
The review was done by Helper Software using static analysis (CodeQL and Semgrep) and a line-by-line manual review of the network, file-parsing, platform and licensing code, assisted by Claude Code. It is an internal review, not an independent third-party audit. Enterprise customers can have their own security team read the source under NDA (see Enterprise).
- Summary
- What leaves your machine
- What listens on your machine
- What is stored on your machine
- Editions and platform protections
- Third-party components
- Findings and status
- Hardening already in place
- Reporting a vulnerability
Summary
- No telemetry, no analytics, no crash reporting, no machine identifiers, no cloud service. Verified by searching the entire application source; there is no code path that could send them.
- Nothing is sent at startup. Every outbound connection is listed below and needs an explicit action from you.
- Licences are verified offline. A licence is an Ed25519-signed token checked against a key built into the app. There is no activation server and no phone-home.
- The review found issues, and they are being fixed. They are listed by category with their status in Findings and status. This page is updated when the fixing release ships.
What leaves your machine
The complete list of network connections the application can make. All of them are triggered by you; none carries dataset contents unless the row says so.
| When | Where | What is sent |
|---|---|---|
| Help > Check for Updates | https://statdataviewer.com/updates/update.json over HTTPS | A plain GET. No version, no licence, no identifiers. The App Store edition has no update check at all; the store updates it. |
| Opening a web link or buying a licence | statdataviewer.com, buy.stripe.com, apps.apple.com, github.com | Your system browser opens the page. The app itself sends nothing. |
| App Store edition, at launch | Apple StoreKit | Apple's own purchase and entitlement check for the in-app upgrade. |
| R Package Manager | CRAN (cloud.r-project.org) or r-universe, chosen by you | Package names, sent by your own R installation, which performs the download. |
| Connecting to your own servers: Rserve, SAS Enterprise Guide through SDVBridge, SAS Studio through the browser extension | The host you configure; the defaults are on your own machine | The programs you submit and the datasets you request. Rserve's protocol is plaintext, so use it on localhost or through an SSH tunnel. |
StatScript programs that name an http(s) URL or use FILENAME PIPE | Wherever the program says | Only when your program asks for it, exactly as SAS would. |
There is no other outbound connection. The app never disables TLS certificate checking.
What listens on your machine
Three small servers can run inside the application. All bind to 127.0.0.1 only, so they are never reachable from the network.
| Server | Port | Runs when | Protection |
|---|---|---|---|
| Page server for SAS Shiny apps (PROC APP) and data lineage | Random, chosen at start | You run an app or open a lineage tab | Every page needs a one-time token exchanged for a session cookie; Host and Origin headers are checked; pages can only reach their own app. |
RStudio bridge (for the sdv R package) | 53211 | At launch, unless turned off in Tools > Options | Optional token in 2026.10.11; mandatory in the next release, with browser-origin checks. |
| SAS Studio bridge (for the SAS Studio Helper extension) | 53210 | Only after File > Connect > SAS Studio | Optional token in 2026.10.11; mandatory in the next release, with browser-origin checks. |
Until that release: set a token for both bridges in Tools > Options, and turn the RStudio bridge off if you do not use it.
What is stored on your machine
| What | Where | Contents | Kept |
|---|---|---|---|
| Settings and sessions | statdataviewer.db in your home folder(App Store edition: ~/Library/Containers/com.statdataviewer/Data/) | Options, library paths, recent files, saved sessions (file paths, filters, hidden variables, the text of untitled programs), bridge tokens and your licence. No dataset contents. | Until you delete it |
| Datasets downloaded from SAS Studio | macOS: ~/Library/Caches/HelperSoftware/StatDataViewer/sasStudio/Windows: %LOCALAPPDATA%\HelperSoftware\StatDataViewer\cache\sasStudio\ | The datasets you opened from SAS Studio | Until you delete them (automatic cleanup is planned) |
| Datasets, logs and listings from SAS Enterprise Guide | Your temp folder, StatDataViewer/SASEG/ | The datasets you opened and the logs of programs you submitted | Until you delete them (automatic cleanup is planned) |
| StatScript WORK library and spill files | Your temp folder | Working datasets of running programs | Removed when the program finishes or the app exits |
| Logs and crash reports | — | None are written or sent. Save Log writes a file only when you ask. | — |
The application does not encrypt files at rest; it relies on your operating system's disk encryption and account permissions. The web edition keeps everything in the browser tab's memory and uploads nothing.
Editions and platform protections
| Edition | Code signing | Sandbox | Notes |
|---|---|---|---|
| Mac App Store | Apple-signed, hardened runtime | macOS App Sandbox: only files you pick, plus network | Updated through the store. |
| Direct download (DMG, pkg) | Developer ID, hardened runtime, notarized by Apple | Not sandboxed | Runs outside the sandbox so it can launch your local R and SAS, which the sandbox forbids. |
| Windows (zip) | Not code-signed in 2026.10.11; signing is planned | None (standard desktop app) | ASLR, DEP and high-entropy ASLR are on. Portable: runs from the folder you unzip it into. |
| Microsoft Store | Signed by the store | None | Same code as the Windows zip. |
| Web (statdataviewer.com/wasm) | — | Browser sandbox | Files stay in the tab's memory; nothing is uploaded. |
Third-party components
The libraries that parse the files you open, with the versions shipped in 2026.10.11.
| Component | Version | Used for |
|---|---|---|
| Qt | 6.8.9 | Application framework, XML, images |
| ReadStat | 1.1.9, with local fixes | sas7bdat, XPT, SPSS .sav, Stata .dta |
| libcsv | 3.0.3 | CSV |
| QXlsx | 1.5.0 | Excel |
| librdata | 2020 snapshot | R .rds and .rdata |
| zlib / xz / bzip2 | 1.3.1 / 5.4.5 / 1.0.8 | Compressed R files. xz 5.4.5 predates and is unaffected by the 5.6.x backdoor (CVE-2024-3094). |
| PDFium | Chromium 149 (April 2026) | PDF output pages |
| Monocypher | 4.0 | Ed25519 licence verification |
| Qt Advanced Docking System | 4.4.1 | Window layout |
| WebView2 SDK (Windows) | 1.0.4191.47 | HTML output and Define-XML |
JMP, RTF, DOCX, Dataset-JSON and Define-XML readers are our own code. A full component list with licences is in Help > About.
Findings and status
What the November 2026 review found, by category. Technical details are withheld until the fixing release ships; this table is then updated with the fixed version.
| Category | Severity | Status |
|---|---|---|
| Memory safety: a missing bounds check in one string-handling path reachable from imported CSV, SPSS and Stata files | Critical | Fix in progress |
| Local integration bridges (SAS Studio, RStudio): authentication token optional by default, browser origin not checked, incomplete path validation | High | Fix in progress; mitigation above |
| Windows build not code-signed | High | Planned for next release |
| Resource exhaustion on crafted files: oversized declared row counts, uncapped decompression | Medium | Fix in progress |
| Define-XML viewer on macOS renders a sponsor-supplied stylesheet with broad file access | Medium | Fix in progress |
| Data retention: SAS Studio and SAS Enterprise Guide downloads kept in cache indefinitely; settings database readable by other local accounts | Medium | Fix in progress |
| Third-party currency: PDF library and the vendored ReadStat reader behind upstream security fixes | Medium | Planned for next release |
| Hardening gaps: Control Flow Guard off on Windows, plaintext Rserve protocol, assorted low-severity items | Low | Scheduled |
Hardening already in place
- Every external program (R, SAS, Rserve) is started with an argument list, never through a shell, and never with elevated privileges.
- The licence verifier checks the signature before reading a single field of the token, uses only the key built into the app, and fails closed on anything malformed. 19 automated tests cover forged, expired, tampered and truncated tokens.
- The PROC APP page server pins the Host header, checks the Origin, issues a one-time token per page and an HttpOnly, SameSite=Strict cookie, and serves assets only from the app's own resources.
- No JavaScript-to-native bridge exists in any web view; links clicked in rendered output open in your system browser.
- The RTF, EMF and WMF readers are iterative and bounds-checked; ReadStat caps every allocation at 16 MiB and bounds its decompressors.
- macOS builds are Developer ID signed, use the hardened runtime, and are notarized and stapled by Apple.
Reporting a vulnerability
Email support@statdataviewer.com with "Security" in the subject. We reply within one business day, and we ask for the usual courtesy of time to ship a fix before details are published. We will credit you here if you wish.
Need to review the source yourself? Read-only access under NDA is part of the Enterprise edition.