DrawingSecurity
Sheet12 / 12
Rev0.3.94
Date10-2026
Scale1:1
MaterialC99

Scanned and clean

A terminal sees everything you type and everything a remote host sends back, so it has to be trustworthy. rbterm’s C source runs through SonarCloud’s static analysis and taint tracking, and the result is a passed quality gate with zero open vulnerabilities, bugs, code smells or security hotspots and an A on every rating.

Quality gate: passed 0 vulnerabilities A ratings Signed updates
SEC 01

The scan results

The latest SonarCloud analysis of rbterm’s main branch.

0
Vulnerabilities

Security rating A. Taint analysis follows untrusted input through the code.

0
Bugs

Reliability rating A: no open null dereferences, overflows or leaks.

0
Hotspots open

100% of security hotspots reviewed. Security review rating A.

0
Code smells

Maintainability rating A, with 1.5% duplicated lines.

Quality gate
Passed. SonarCloud’s pass/fail bar for the whole project.
Analyzed
40,000+ lines of C across the terminal, its shell daemon, SSH, remote control and the updater, scanned from a fresh clone of main so nothing comes from a stale cache.
SEC 02

Protections that ship

What the code does to keep a terminal’s input and output from being turned against you.

Link scheme gate

Cmd+click only opens http, https and mailto. A hyperlink’s text can differ from its target, so output from a remote host could otherwise have aimed a link at a local app.

No shell in the middle

The updater, link opener, log editor and SSH key fingerprinting run programs directly, not through a shell command line. A strange file name can never be read as a command.

Private temp files

The remote-control socket, logs and previews live in a per-user private directory instead of the shared /tmp, and rbterm @ only connects to sockets you own.

Memory safety

Out-of-memory paths, unchecked allocations, a divide-by-zero and atlas bounds are all guarded, and helper processes are reaped instead of left as zombies.

SEC 03

Secure by design

Static analysis checks the code. These are the choices behind it.

Signed updates

The update manifest carries an ed25519 signature, verified against a key built into the app before any URL or hash in it is trusted. The download must then match its pinned SHA-256.

Notarized macOS app

Signed with a Developer ID, notarized by Apple and stapled, so Gatekeeper can check it offline. Every download lists its SHA-256 on the download page.

Remote control you can see

Off by default. While it’s on, an amber RC ON badge sits in the tab bar. Click it for what that means and a one-click Turn off, which takes effect at once.

Authenticated scripting

With a password set, every remote-control command must arrive encrypted: X25519 key exchange, AES-256-GCM, and a 5-minute replay window. Where that crypto isn’t available, rbterm refuses to start remote control rather than run it unauthenticated.

SSH done carefully

Host keys are trusted on first use and checked against known_hosts, and a changed key aborts the connection. Encrypted keys never fall back to a hidden passphrase prompt.

No leaked descriptors

Every socket and pty the shell daemon holds is close-on-exec, so programs started in a pane can’t inherit them.

Private by default

Session logging is opt-in. The daily update check sends only a version and an anonymous install id, and both the check and the id can be switched off in Settings → Updates.

Tested, not just scanned

~270 automated checks drive the real binary on macOS, Linux and Windows for every release. How the self-test works →

SEC 04

What we tell you straight

A clean report is only worth something if you know what’s behind it.

Remote control
With remote control on and no password, text printed in a pane can drive rbterm. We accept that risk in exchange for tools like the Claude Code image skill. It’s documented in the manual, flagged by the RC ON badge, and one click turns it off.
Rule tuning
A set of style-only rules and one very noisy check (“log injection” on rbterm’s own stderr messages, about 200 hits) are switched off in the project’s Sonar configuration, each with a reason. Everything else runs with the default rules.
Your own input
Where an analyzer calls data “untrusted” but it is your own shell, config file or command line, rbterm treats it as yours, and says so in the code. You can’t attack yourself through your own $SHELL.