Home

Security

A browser's attack surface splits in two: the engine we did not write, and the shell we did. The two behave very differently, so we describe them separately. The known gaps in this release are at the end of the page.

The engine: Chromium, V8, Skia

Through 2026, dozens of memory-safety flaws were fixed in Chrome, six of them zero-days exploited in the wild. We do not write this code and we cannot fix it; the only defence here is keeping the engine current.

That is why our rule is blunt: Girginos Browser is not released on an end-of-life Electron version. Electron supports only its last three major versions, and the version pin is checked before every release. We currently ship Electron 44.2.0 with Chromium 152.0.7977.76.

The shell: the code we wrote

These are the architectural decisions on the shell side:

  • Every tab is a separate WebContentsView. Page content runs with sandbox: true, contextIsolation: true and nodeIntegration: false, and gets no preload.
  • The interface window is sandboxed as well and shares a session with the tabs, so the interface's own requests also pass through the blocker and carry the DNT headers.
  • IPC channels are accepted only from the main frame of the interface window. Settings writes go through key and type validation.
  • Downloads are addressed by identifier; a raw file path coming from the interface is never opened.
  • Page-initiated navigation is limited to http(s) and view-source:http(s). file: and chrome: open only when the user types them into the address bar.
  • Handing off to an external application is limited to a narrow scheme list: mailto:, tel:, sms:, magnet:, ftp(s):, webcal:. Only one confirmation dialog can be open at a time.
  • Opaque origins — those whose origin is null, such as data: and about: — are always denied on permission requests.
  • Spellchecking is disabled, because Chromium downloads its dictionary files from a Google server.
  • Data is written atomically, via a temporary file and a rename.

Attack vectors and countermeasures

ClassExampleCountermeasure
Address bar spoofingRLO/bidi, CR-LF, NUL, bank.com@evil.com, whitespace padding, IDN homographsInvisible characters and spaces stay percent-encoded, credentials are hidden, punycode is shown
Domain obfuscationaccounts.google.com.giris.evil.comThe registrable domain is drawn in full colour, the rest is dimmed
Internal page impersonationnewtab.html, a downloaded copyThe full address must match; no substring search is done
Full-screen interface spoofinga page goes full screen and paints a fake toolbarThe page view is never expanded over the shell
Scheme escapefile:, chrome:, blob:, view-source:file:Page-initiated navigation is http(s) only
External application invocationms-msdt:, search-ms:, ms-appinstaller:A narrow allowlist and a single confirmation dialog
Download name tricksevil.exe / evil.exe., trailing dot or space, extension hidden with RLONormalisation before the extension check; the decision follows the real name on disk
Blocker evasionizleyici.com., trailing dotHost normalisation

The signed update chain

The threat model assumes the update server may already be compromised. The sequence runs like this:

  1. The signed manifest and the signature file next to it are fetched.
  2. The signature is verified over the manifest's raw bytes with the Ed25519 public key embedded in the application. If it does not verify, not a single field is read.
  3. Version gates are applied: downgrades are refused; a manifest past its own expiry date is refused — this defends against an attacker serving an old manifest forever to freeze updates; an intermediate version is required where necessary; and the download address must be https.
  4. The version and package digest found by the downloader must match the signed manifest exactly.
  5. Once the download finishes, the package's sha512 digest is compared against the signed digest in constant time.
  6. Installation only starts once the user approves it.

If any step fails, no update happens. The private key is never kept on the server; even if the server were taken over, an attacker could not produce a valid manifest.

Tests

118 unit tests, 73 attack-vector regressions and 46 update-verification tests run against the code, and the IPC and DOM contract between the interface and the main process is tested separately. Alongside those, end-to-end verification scripts run before and after each release against real output and the live server.

Known gaps

The following are missing in 0.1.0. Hiding them would make the product look safer than it is, so we are stating them plainly.

No Mark-of-the-Web
No Zone.Identifier is written to downloaded files, so Windows SmartScreen does not engage for them. The browser shows its own warning, but the operating-system layer is absent.
No code signing certificate
The installer's code signature cannot be verified. The signed manifest closes this for updates, but the first installation remains exposed.
No Public Suffix List
On hosting domains such as github.io, site exceptions and address-bar highlighting cover more than they should.
Certificate errors use the Chromium default
No custom "proceed anyway" screen was written; on a bad certificate the page simply does not open.
Blocking is domain-level only
Trackers hidden behind CNAME records and ads served from the first party are not caught, and no cosmetic filtering is applied.

Related pages