Security & trust
You are running our script on production machines. Here is exactly what it does.
The scanner reads, it doesn't write or connect. The report runs in your browser. The only server we operate sees a Stripe checkout reference, never scan data.
What the scanner reads
Two scripts, one per platform, each a single readable file under the MIT license: runtimeclear.sh for Linux and macOS (bash 3.2+) and runtimeclear.ps1 for Windows (PowerShell 5.1+). Each starts with a header listing everything it reads.
| Platform | Where it looks for Java homes |
|---|---|
| Linux | Package databases (rpm, dpkg, recording the package vendor), /usr/lib/jvm, /usr/java, /opt (4 levels), /usr/local (3 levels), update-alternatives |
| macOS | /Library/Java/JavaVirtualMachines, the user equivalent, the legacy applet plugin, /usr/libexec/java_home -V, Homebrew openjdk* formulae and JDK casks, Oracle's Java-Updater LaunchAgent |
| Windows | HKLM\SOFTWARE\JavaSoft (and WOW6432Node), Uninstall registry keys, common Program Files vendor folders, where.exe java, scoop, Java Update policy values, jusched.exe and scheduled tasks named like Java Update |
| All | java on PATH, JAVA_HOME, SDKMAN, jenv, asdf, Gradle and Maven JDK folders, IntelliJ ~/.jdks, running java processes (executable path only) |
For each Java home it reads the plain-text release file (JAVA_VERSION, JAVA_RUNTIME_VERSION, IMPLEMENTOR, BUILD_TYPE). Only when a home has no release file does it run <home>/bin/java -version, with a 5-second timeout; --no-exec (-NoExec) turns that off.
With --repo, it reads Dockerfiles, Compose and Kubernetes YAML, CI files, .sdkmanrc, .tool-versions, Gradle and Maven files line by line, skipping binaries and files over 1 MB, and stores only the matching line, cut at 300 characters. The full list of patterns is in the scanner README.
What it never does
- No network access. The scripts never open a socket. The scanner's test suite runs a full scan under
straceand fails if anyAF_INETorAF_INET6socket is opened. The PowerShell script avoidsGet-Packagebecause that cmdlet can try to download a provider. - No changes. Nothing is installed, updated, moved or deleted. The only file written is the JSON output.
- No extra data. No process arguments, no environment variables other than
PATHandJAVA_HOME, no file contents beyond a single matched line. - No sudo required. Unreadable locations are listed under
warningsin the JSON. Running as root or Administrator only adds other users' homes and processes.
Prove it yourself, in about two minutes
Everything above is a claim. Here is how to check it on your own machine before you let the script near anything that matters. The first method is the shortest; the second is the strongest, because it removes the network instead of watching it.
$ strace -f -e trace=socket,connect -o /tmp/rc-syscalls.txt \ bash runtimeclear.sh --quiet --out /tmp/rc.json $ grep -E 'AF_INET|connect\(' /tmp/rc-syscalls.txt # no output = no network syscall was attempted
# Linux: run it in a namespace with no network interface at all. $ unshare -rn bash runtimeclear.sh --quiet --out /tmp/rc.json # Or in a container with networking switched off: $ docker run --rm --network none -v "$PWD:/w" -w /w \ debian:stable-slim bash runtimeclear.sh --quiet --out /w/rc.json # The scan completes normally. Anything that needed the network could not.
On Windows, run Process Monitor with a filter of Process Name is powershell.exe and Operation begins with TCP or UDP, then run the scanner: the list stays empty. On macOS, run it inside a VM or container with networking disabled, as above — dtrace is restricted by System Integrity Protection and is not a reliable check.
Or skip the tools entirely and read the source for anything capable of opening a connection:
$ grep -nEi 'curl|wget|nc |netcat|/dev/tcp|Invoke-WebRequest|Invoke-RestMethod|System.Net' \
runtimeclear.sh runtimeclear.ps1
# no match = the source contains no way to open a connection
The same check runs on every commit: the test suite executes a full scan under strace and fails the build if a single AF_INET or AF_INET6 socket is opened.
Review the JSON before you share it
--anonymize replaces the hostname with the first 12 hex characters of its SHA-256. Paths such as /home/alice/.sdkman/… and repository folder names stay in the file. It is plain text; read it.
Verify the download
Every GitHub release attaches runtimeclear.sh, runtimeclear.ps1 and a SHA256SUMS file generated from those exact files. Check the hash, then read the script, then run it.
What this check does and does not cover. The script and its checksum come from the same release, so a matching hash proves the file reached you intact — it does not prove the release itself was not tampered with, because anyone who could replace the script could replace the checksum beside it. The build provenance attestation below is the check that covers that case, because it is signed by GitHub's infrastructure rather than published by us.
$ curl -fsSLO https://github.com/techbuilddreams/runtimeclear/releases/download/v1.0.1/runtimeclear.sh $ curl -fsSLO https://github.com/techbuilddreams/runtimeclear/releases/download/v1.0.1/SHA256SUMS $ sha256sum -c SHA256SUMS --ignore-missing # macOS: shasum -a 256 runtimeclear.sh and compare with SHA256SUMS
PS> Invoke-WebRequest https://github.com/techbuilddreams/runtimeclear/releases/download/v1.0.1/runtimeclear.ps1 -OutFile runtimeclear.ps1 PS> (Get-FileHash .\runtimeclear.ps1 -Algorithm SHA256).Hash.ToLower() # compare with the runtimeclear.ps1 line in SHA256SUMS
Build provenance attestations
The release workflow is being moved to GitHub Actions with signed build provenance attestations, which link each released file to the workflow run and commit that produced it. Releases up to v1.0.1 were published before that and carry checksums only. Once a release includes attestations, its release notes will say so and this command will succeed:
$ gh attestation verify runtimeclear.sh --repo techbuilddreams/runtimeclear
How the report handles scan files
- The report page reads files with the browser's File API and classifies them with
rules.js, a versioned rules file you can read, on your machine. Every rule in it is documented with its Oracle source on the methodology page. - So loaded scans survive the trip through checkout, they are kept in the tab's
sessionStorage, which the browser deletes when the tab closes. Clear all removes them immediately. - The organization name and employee count you type are kept in
localStorageon your computer. - The site's Content Security Policy restricts the page to its own origin (
connect-src 'self'), so the page itself cannot send data to a third party. You can confirm in your browser's network panel: loading scans makes no requests.
How payment verification works
- You pay on Stripe's hosted checkout. We never see your card details.
- Stripe redirects back to
/report/?session_id=cs_…. - The page sends only that checkout session ID to
/api/verify.php. - The server asks Stripe's API for that session using a restricted key that can only read Checkout Sessions, checks that it is complete and paid, recent, and for a RuntimeClear price.
- It returns an unlock token: your plan, the session ID and an expiry, signed with HMAC-SHA256. The browser stores it in
localStorage. - On later visits the page sends only the token; the server checks the signature and expiry without calling Stripe.
The endpoint accepts only same-origin JSON POSTs, rate-limits by a one-way hash of the client IP (about 30 requests per 10 minutes), never logs Stripe's response body or the key, and reads its secrets from a file outside the web root.
Data we hold
- Scan files
- None. They never reach our server.
- Payments
- Stripe's records of your purchase: name, email, plan, amount, date, country and payment status.
- Server logs
- Standard web server logs kept by our host (IP, time, URL, referrer, user agent), plus a short-lived rate-limit counter keyed by a hashed IP.
- Messages you send to support@runtimeclear.com, kept to answer you and handle refunds or access.
- Analytics, ads, cookies
- None.
Full details in the privacy policy.
Website hardening
- HTTPS only, with
X-Content-Type-Options,X-Frame-Options: DENY, a strictReferrer-Policy,Permissions-PolicyandCross-Origin-Opener-Policy. - Content Security Policy
default-src 'self'with no inline scripts and no third-party scripts, styles or fonts. Fonts are self-hosted. - The only third-party destination is Stripe Checkout, reached by a normal link when you choose to buy.
Report a vulnerability
Email support@runtimeclear.com with steps to reproduce. Please don't open a public issue for anything that could be abused before a fix ships. For the scanner, we treat any of these as a security bug: a network connection of any kind, a write to any file other than the JSON output, running anything other than <java home>/bin/java -version, recording data we say is not collected, or output that stops being valid JSON because of a crafted path.
We aim to acknowledge reports within one business day, and we credit reporters in the release notes unless you ask us not to. Machine-readable contact: /.well-known/security.txt. Non-sensitive scanner bugs can go to GitHub issues.