hakurei.app/static/features.html

1465 lines
104 KiB
HTML

<!DOCTYPE html>
<html lang="en" prefix="og: https://ogp.me/ns#">
<head>
<meta charset="utf-8"/>
<title>Features overview | GrapheneOS</title>
<meta name="description" content="Overview of GrapheneOS features differentiating it from the Android Open Source Project (AOSP)."/>
<meta name="theme-color" content="#212121"/>
<meta name="color-scheme" content="dark light"/>
<meta name="msapplication-TileColor" content="#ffffff"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="twitter:site" content="@GrapheneOS"/>
<meta name="twitter:creator" content="@GrapheneOS"/>
<meta property="og:title" content="GrapheneOS features overview"/>
<meta property="og:description" content="Overview of GrapheneOS features differentiating it from the Android Open Source Project (AOSP)."/>
<meta property="og:type" content="website"/>
<meta property="og:image" content="https://grapheneos.org/opengraph.png"/>
<meta property="og:image:width" content="512"/>
<meta property="og:image:height" content="512"/>
<meta property="og:image:alt" content="GrapheneOS logo"/>
<meta property="og:site_name" content="GrapheneOS"/>
<meta property="og:url" content="https://grapheneos.org/features"/>
<link rel="canonical" href="https://grapheneos.org/features"/>
<link rel="icon" href="/favicon.ico"/>
<link rel="icon" sizes="any" type="image/svg+xml" href="/favicon.svg"/>
<link rel="mask-icon" href="[[path|/mask-icon.svg]]" color="#1a1a1a"/>
<link rel="apple-touch-icon" href="/apple-touch-icon.png"/>
[[css|/main.css]]
<link rel="manifest" href="/manifest.webmanifest"/>
<link rel="license" href="/LICENSE.txt"/>
<link rel="me" href="https://grapheneos.social/@GrapheneOS"/>
[[js|/js/redirect.js]]
</head>
<body>
{% with current_page="features" %}
{% include "header.html" %}
{% endwith %}
<main id="features">
<h1><a href="#features">Features overview</a></h1>
<p>GrapheneOS is a private and secure mobile operating system with great functionality
and usability. It starts from the strong baseline of the
<a href="https://source.android.com/">Android Open Source Project (AOSP)</a> and
takes great care to avoid increasing attack surface or hurting the strong security
model. GrapheneOS makes substantial improvements to both privacy and security through
many carefully designed features built to function against real adversaries. The
project cares a lot about usability and app compatibility so those are taken into
account for all of our features.</p>
<p>GrapheneOS is focused on substance rather than branding and marketing. It doesn't
take the typical approach of piling on a bunch of insecure features depending on the
adversaries not knowing about them and regressing actual privacy/security. It's a very
technical project building privacy and security into the OS rather than including
assorted unhelpful frills or bundling subjective third party apps choices.</p>
<p>GrapheneOS is also hard at work on filling in gaps from not bundling Google apps
and services into the OS. We aren't against users using Google services but it doesn't
belong integrated into the OS in an invasive way. GrapheneOS won't take the shortcut
of simply bundling a very incomplete and poorly secured third party reimplementation
of Google services into the OS. That wouldn't ever be something users could rely upon.
It will also always be chasing a moving target while offering poorer security than the
real thing if the focus is on simply getting things working without great care for
doing it robustly and securely.</p>
<p>This page provides an overview of currently implemented features differentiating
GrapheneOS from AOSP. It doesn't document our many historical features that are no
longer included for one reason or another. Many of our features were implemented in
AOSP, Linux, <a href="https://llvm.org/">LLVM</a> and other projects GrapheneOS is
based on and those aren't listed here. In many cases, we've been involved in getting
those features implemented in core infrastructure projects.</p>
<nav id="table-of-contents">
<h2><a href="#table-of-contents">Table of contents</a></h2>
<ul>
<li>
<a href="#grapheneos">GrapheneOS</a>
<ul>
<li>
<a href="#exploit-protection">Defending against exploitation of
unknown vulnerabilities</a>
<ul>
<li><a href="#attack-surface-reduction">Attack surface
reduction</a>
<ul>
<li><a href="#usb-c-port-and-pogo-pins-control">USB-C port and pogo pins control</a></li>
</ul>
</li>
<li><a href="#exploit-mitigations">Exploit
mitigations</a></li>
<li><a href="#improved-sandboxing">Improved
sandboxing</a></li>
<li><a href="#anti-persistence">Anti-persistence /
detection</a></li>
</ul>
</li>
<li><a href="#more-complete-patching">More complete patching</a></li>
<li><a href="#sandboxed-google-play">Sandboxed Google Play</a></li>
<li><a href="#android-auto">Android Auto</a></li>
<li><a href="#network-permission-toggle">Network permission toggle</a></li>
<li><a href="#sensors-permission-toggle">Sensors permission toggle</a></li>
<li><a href="#storage-scopes">Storage Scopes</a></li>
<li><a href="#contact-scopes">Contact Scopes</a></li>
<li><a href="#broad-carrier-support">Broad carrier support without invasive carrier access</a></li>
<li><a href="#lte-only-mode">LTE-only mode</a></li>
<li><a href="#wifi-privacy">Wi-Fi privacy</a></li>
<li><a href="#private-screenshots">Private screenshots</a></li>
<li><a href="#closed-device-identifier-leaks">Closed device identifier leaks</a></li>
<li><a href="#privacy-by-default">Privacy by default</a></li>
<li><a href="#pin-scrambling">PIN scrambling</a></li>
<li><a href="#two-factor-fingerprint-unlock">two-factor fingerprint unlock</a></li>
<li><a href="#supports-longer-passwords">Supports longer
passwords</a></li>
<li><a href="#auto-reboot">Auto reboot</a></li>
<li><a href="#clearing-sensitive-data-from-memory">Clearing sensitive data from memory</a></li>
<li><a href="#duress">Duress PIN/Password</a></li>
<li><a href="#more-secure-fingerprint-unlock">More secure fingerprint
unlock</a></li>
<li>
<a href="#improved-user-profiles">Improved user profiles</a>
<ul>
<li><a href="#more-user-profiles">More user profiles</a></li>
<li><a href="#end-session">End session</a></li>
<li><a href="#disabling-app-installation">Disabling app installation</a></li>
<li><a href="#install-available-apps">Install available apps</a></li>
<li><a href="#notification-forwarding">Notification forwarding</a></li>
</ul>
</li>
<li><a href="#grapheneos-app-repository">GrapheneOS app
repository</a></li>
<li><a href="#vanadium">Vanadium: hardened WebView and default
browser</a></li>
<li><a href="#auditor">Auditor app and attestation service</a></li>
<li><a href="#grapheneos-camera">GrapheneOS Camera</a></li>
<li><a href="#grapheneos-pdf-viewer">GrapheneOS PDF Viewer</a></li>
<li><a href="#setup-wizard">GrapheneOS Setup Wizard</a></li>
<li><a href="#encrypted-backups">Encrypted backups</a></li>
<li><a href="#location-data-access-indicator">Location data access
indicator</a></li>
<li><a href="#user-installed-apps-can-be-disabled">User installed apps
can be disabled</a></li>
<li><a href="#improved-vpn-leak-blocking">Improved VPN leak blocking</a></li>
<li><a href="#log-viewer-and-crash-reporting">Log viewer and user-facing crash reporting</a></li>
<li><a href="#other-features">Other features</a></li>
</ul>
</li>
<li><a href="#services">Services</a></li>
<li><a href="#project">Project</a></li>
</ul>
</nav>
<section id="grapheneos">
<h2><a href="#grapheneos">GrapheneOS</a></h2>
<p>These are the features of GrapheneOS beyond what's provided by version 15 of
the Android Open Source Project. It only covers our improvements to AOSP and not
baseline features. This section doesn't list features like the standard app
sandbox, verified boot, exploit mitigations (ASLR, SSP, Shadow Call Stack, Control
Flow Integrity, etc.), permission system (foreground-only and one-time permission
grants, scoped file access control, etc.) and so on but rather only our
improvements to modern Android. We plan on providing a separate page listing the
improvements we've contributed to Android since those features aren't listed here
despite being a substantial portion of our overall historical work.</p>
<section id="exploit-protection">
<h3><a href="#exploit-protection">Defending against exploitation of unknown
vulnerabilities</a></h3>
<p>GrapheneOS is heavily focused on protecting users against attackers
exploiting unknown (0 day) vulnerabilities. Patching vulnerabilities doesn't
protect users before the vulnerability is known to the vendor and has a patch
developed and shipped.</p>
<p>Unknown (0 day) vulnerabilities are much more widely used than most realize
to exploit users not just in targeted attacks but in broad deployments.
Project Zero maintains
<a href="https://docs.google.com/spreadsheets/d/1lkNJ0uQwbeC1ZTRrxdtuPLCIl7mlUreoKfSIgajnSyY/view#gid=0">a
spreadsheet</a> tracking zero day exploitation detected in the wild. This is
only a peek into what's happening since it only documents cases where the
attackers were caught exploiting users, often because the attacks are not
targeted but rather deployed on public websites, etc.</p>
<p>The first line of defense is attack surface reduction. Removing unnecessary
code or exposed attack surface eliminates many vulnerabilities completely.
GrapheneOS avoids removing any useful functionality for end users, but we can
still disable lots of functionality by default and require that users opt-in
to using it to eliminate it for most of them. An example we landed upstream in
Android is disallowing using the kernel's profiling support by default, since
it was and still is a major source of Linux kernel vulnerabilities. Profiling
is now only exposed to apps for developers who enable developer tools, enable
the Android Debug Bridge (ADB) and then use profiling tools via ADB. It's also
only enabled until the next boot. This isn't listed below since it's one of
the features we got implemented in Android itself.</p>
<p>The next line of defense is preventing an attacker from exploiting a
vulnerability, either by making it impossible, unreliable or at least
meaningfully harder to develop. The vast majority of vulnerabilities are well
understood classes of bugs and exploitation can be prevented by avoiding the
bugs via languages/tooling or preventing exploitation with strong exploit
mitigations. In many cases, vulnerability classes can be completely wiped out
while in many others they can at least be made meaningfully harder to exploit.
Android does a lot of work in this area, and GrapheneOS has helped to advance
this in Android and the Linux kernel. It takes an enormous amount of resources
to develop fundamental fixes for these problems and there's often a high
performance, memory or compatibility cost to deploying them. Mainstream
operating systems usually don't prioritize security over other areas.
GrapheneOS is willing to go further, thus we offer toggles for users to choose
the compromises they prefer instead of forcing it on them. In the meantime,
weaker less complete exploit mitigations can still provide meaningful barriers
against attacks as long as they're developed with a clear threat model.
GrapheneOS is heavily invested in many areas of developing these protections:
developing/deploying memory safe languages/libraries, static/dynamic
analysis tooling and many kinds of mitigations.</p>
<p>The final line of defense is containment through sandboxing at various
levels: fine-grained sandboxes around a specific context like per site browser
renderers, sandboxes around a specific component like Android's media codec
sandbox and app/workspace sandboxes like the Android app sandbox used to
sandbox each app which is also the basis for user/work profiles. GrapheneOS
improves all of these sandboxes through fortifying the kernel and other base
OS components along with improving the sandboxing policies.</p>
<p>Preventing an attacker from persisting their control of a component or the
OS/firmware through verified boot and avoiding trust in persistent state
also helps to mitigate the damage after a compromise has occurred.</p>
<p>Remote code execution vulnerabilities are the most serious and allow an
attacker to gain a foothold on the device or even substantial control over it
remotely. Local code execution vulnerabilities allow breaking out of a sandbox
including the app sandbox or browser renderer sandbox after either
compromising an app/browser renderer remotely, compromising an app's supply
chain or getting the user to install a malicious app. Many other kinds of
vulnerabilities exist but most of what we're protecting against falls into
these two broad categories.</p>
<p>The vast majority of local and remote code execution vulnerabilities are
memory corruption bugs caused by memory unsafe languages or rare low-level
unsafe code in an otherwise memory safe language. Most of the remaining issues
are caused by dynamic code execution/loading features. Our main focus is on
preventing or raising the difficulty of exploiting memory corruption bugs
followed by restricting dynamic code execution both to make escalation from a
memory corruption bug harder and to directly mitigate bugs caused by dynamic
code loading/generation/execution such as a JIT compiler bug or a plugin
loading vulnerability.</p>
<section id="attack-surface-reduction">
<h4><a href="#attack-surface-reduction">Attack surface reduction</a></h4>
<ul>
<li>Greatly reduced remote, local and proximity-based attack surface by
stripping out unnecessary code, making more features optional and
disabling optional features by default (NFC, Bluetooth, UWB, etc.), when
the screen is locked (USB, USB-C, pogo pins, camera access) and optionally
after a timeout (Bluetooth, Wi-Fi).</li>
<li>Native debugging (ptrace) access is blocked for all bundled apps to
reduce local attack surface. ptrace access is allowed by default for user
installed apps for compatibility, with an option to block it by default. In
both cases, ptrace access can be blocked or allowed manually on a per-app
basis. When an app that is blocked from accessing ptrace tries to use it,
GrapheneOS shows a notification that links the per-app native debugging
settings screen.</li>
</ul>
<h5 id="usb-c-port-and-pogo-pins-control"><a href="#usb-c-port-and-pogo-pins-control">USB-C port and pogo pins control</a></h5>
<p>Our <b>USB-C port and pogo pins</b> setting protects against attacks
through USB-C or pogo pins while the OS is booted. For the majority of
devices without pogo pins, the setting is labelled <b>USB-C port</b></p>
<p>The feature has five modes:</p>
<ul>
<li>Off</li>
<li>Charging-only</li>
<li>Charging-only when locked</li>
<li>Charging-only when locked, except before first unlock</li>
<li>On</li>
</ul>
<p>The default is <b>Charging-only when locked</b>, which significantly
reduces attack surface when the device is locked. After locking, it blocks
any new USB connections immediately through either USB-C and pogo pins at
both the hardware level via configuring the USB controller and also at the
OS level in the kernel to provide a second layer of defense. It disables the
data lines at a hardware level as soon as the existing connections end which
happens right away if there were no USB connections. It also disables USB-C
alternate modes including DisplayPort at both the OS and hardware level.</p>
<p>Our implementation is far more secure than Android's standard USB HAL
toggle available to device admin apps. The standard feature only disables
high level USB handling in the OS. It doesn't block new USB connections or
disable the data lines at a hardware level. It also leaves the handling of
the USB-C and pogo pins protocols enabled in the OS, and it doesn't disable
the USB-C alternate modes. The standard feature is also either blocking or
not blocking USB at a high level, without the ability to block new
connections and disable USB only once the existing connections end. Other
operating systems trying to implement a similar feature via the standard
toggle end up continuing to allow new USB connections in the OS until all
connections end instead of the two-phase approach we use for our two
Charging-only when locked modes.</p>
</section>
<section id="exploit-mitigations">
<h4><a href="#exploit-mitigations">Exploit mitigations</a></h4>
<ul>
<li>Hardened app runtime</li>
<li><a href="/usage#exec-spawning">Secure application spawning
system</a> avoiding sharing address space layout and other secrets
across applications</li>
<li><a href="https://github.com/GrapheneOS/platform_bionic">Hardened libc</a>
providing defenses against the most common classes of vulnerabilities (memory
corruption)</li>
<li>
Our own <a href="https://github.com/GrapheneOS/hardened_malloc">hardened
malloc (memory allocator)</a> leveraging modern hardware capabilities
to provide substantial defenses against the most common classes of
vulnerabilities (heap memory corruption) along with reducing the lifetime
of sensitive data in memory. The <a
href="https://github.com/GrapheneOS/hardened_malloc/blob/main/README.md">hardened_malloc
README</a> has extensive documentation on it. The hardened_malloc
project is portable to other Linux-based operating systems and is being
adopted by other security-focused operating systems like secureblue. Our
allocator also heavily influenced the design of the <a
href="https://www.openwall.com/lists/musl/2020/05/13/1">next-generation
musl malloc implementation</a> which offers substantially better security than
musl's previous malloc while still having minimal memory usage and code size.
<ul>
<li>Fully out-of-line metadata with protection from corruption, ruling
out traditional allocator exploitation</li>
<li>Separate memory regions for metadata, large allocations and each
slab allocation size class with high entropy random bases and no
address space reuse between the different regions</li>
<li>Deterministic detection of any invalid free</li>
<li>Zero-on-free with detection of write-after-free via checking that
memory is still zeroed before handing it out again</li>
<li>Delayed reuse of address space and memory allocations through the
combination of deterministic and randomized quarantines to mitigate
use-after-free vulnerabilities</li>
<li>Fine-grained randomization</li>
<li>Aggressive consistency checks</li>
<li>Memory protected guard regions around allocations larger than 16k
with randomization of guard region sizes for 128k and above</li>
<li>Allocations smaller than 16k have guard regions around each of the
slabs containing allocations (for example, 16 byte allocations are in
4096 byte slabs with 4096 byte guard regions before and after)</li>
<li>Random canaries with a leading zero are added to these smaller
allocations to block C string overflows, absorb small overflows
and detect linear overflows or other heap corruption when the
canary value is checked (primarily on free)</li>
<li>Hardware memory tagging for slab allocations (128k and
below) providing probabilistic detection of all use-after-free
and inter-object overflows along with deterministic detection
of all small/linear overflows and use-after-free until it has
been reused once and gone through the quarantines twice</li>
</ul>
</li>
<li>On ARMv9, Branch Target Identification (BTI) and Pointer
Authentication Code (PAC) return address protection are enabled for
userspace OS code we build instead of only specific apps</li>
<li>Signed integer overflow is made well defined in C and C++ for code
where automatic overflow checking is disabled</li>
<li>
Hardened kernel
<ul>
<li>4-level page tables are enabled on arm64 to provide a much
larger address space (48-bit instead of 39-bit) with
significantly higher entropy Address Space Layout
Randomization (33-bit instead of 24-bit).</li>
<li>Basic hardware memory tagging is used in the main kernel
memory allocators (slab, page_alloc, non-executable vmalloc) to
provide probabilistic detection of all use-after-free and
inter-object overflows along with deterministic detection of
use-after-free until the memory is allocated again (we plan to
add deterministic detection of small/linear overflows like
hardened_malloc)</li>
<li>Random canaries with a leading zero are added to the
kernel heap (slub) to block C string overflows, absorb small
overflows and detect linear overflows or other heap corruption
when the canary value is checked (on free, copies to/from
userspace, etc.).</li>
<li>Memory is wiped (zeroed) as soon as it's released in both
the low-level kernel page allocator and higher level kernel
heap allocator (slub). This substantially reduces the lifetime
of sensitive data in memory, mitigates use-after-free
vulnerabilities and makes most uninitialized data usage
vulnerabilities harmless. Without our changes, memory that's
released retains data indefinitely until the memory is handed
out for other uses and gets partially or fully overwritten by
new data.</li>
<li>Kernel stack allocations are zeroed to make most
uninitialized data usage vulnerabilities harmless.</li>
<li>Assorted attack surface reduction through disabling
features or setting up infrastructure to dynamically
enable/disable them only as needed (perf, ptrace).</li>
<li>Assorted upstream hardening features are enabled,
including many which we played a part in developing and
landing upstream as part of our linux-hardened project (which
we intend to revive as a more active project again).</li>
<li>Forced kernel module signing with per-build RSA 4096 /
SHA256 keys and lockdown mode set to forced confidentiality
mode help to enforce a low-level boundary between the kernel
and userspace even if mistakes are made in SELinux policy or
there's a deep userspace compromise.</li>
<li>Additional consistency/integrity checks are enabled for
frequently targeted kernel data structures.</li>
<li>On ARMv9, Branch Target Identification (BTI) is enabled in
addition to Clang type-based Control Flow Integrity (CFI) to
cover functions excluded from type-based CFI</li>
<li>On ARMv9, ShadowCallStack (SCS) is enabled in addition to
Pointer Authentication Code (PAC) return address protection
instead of only enabling SCS when PAC is unavailable</li>
</ul>
</li>
<li>Android Runtime Just-In-Time (JIT) compilation/profiling is fully
disabled and replaced with full ahead-of-time (AOT) compilation. The
only JIT compilation in the base OS is the V8 JavaScript JIT which is
disabled by default for the Vanadium browser with per-site exception
support.</li>
<li>Dynamic code loading for both native code or Java/Kotlin classes is
blocked for nearly the entire base OS to prevent base OS processes. This
works alongside verified boot to prevent base OS processes from running
attacker controlled native code or Java/Kotlin code. The only exceptions
from the policy for the base OS are in-memory code loading for the media
DRM sandbox and the Vanadium JIT compiler being permitted. Vanadium has
JIT compilation disabled by default for every site and for apps using
the WebView with the exception of our PDF Viewer app. Vanadium disables
the JIT compiler by default with a per-site and per-app toggle for it
and per-process enforcement of blocking dynamic code loading implemented
with seccomp-bpf based on the per-site/per-app JIT compiler toggle.</li>
<li>Dynamic code loading for both native code or Java/Kotlin classes can
be disabled for user installed apps via 3 exploit protection toggles:
Dynamic code loading from memory, Dynamic code loading from storage and
WebView JIT. This can also be used to opt-out of the WebView JIT for our
PDF Viewer and dynamic code loading from memory for the Vanadium browser
to disable support for the per-site opt-in to JIT compilation. In order
to make the dynamic code loading toggles more usable, we show a user
facing notification when an app has dynamic code loading from memory or
storage blocked, including a file path being shown when it's blocked
from storage. This allows users to disable it for all their apps and
then enable them for the ones requiring it.</li>
<li>Filesystem access hardening</li>
</ul>
</section>
<section id="improved-sandboxing">
<h4><a href="#improved-sandboxing">Improved sandboxing</a></h4>
<p>GrapheneOS improves the app sandbox through hardening SELinux policy
and seccomp-bpf policy along with all the hardening to components like
kernel implementing the app sandbox and providing a path for the attacker
to escape it if they can exploit those components. We primarily focus on
the app sandbox, but we also improve the other sandboxes including making
direct improvements to the web browser renderer sandbox used for both the
default browser and WebView rendering engine provided by the OS and used
by a huge number of other apps from dedicated browsers to messaging
apps.</p>
</section>
<section id="anti-persistence">
<h4><a href="#anti-persistence">Anti-persistence / detection</a></h4>
<ul>
<li>Enhanced <a href="https://source.android.com/docs/security/features/verifiedboot">verified boot</a>
with better security properties and reduced attack surface</li>
<li>GrapheneOS finishes the incomplete implementation of verified boot
for out-of-band updates to packages (APKs) in the OS. We enforce this
by requiring fs-verity metadata signed with a trusted key for system
app updates both at install time and boot time. This provides
continuous verification where every read from an out-of-band APK
update is verified similarly to every read from a firmware, OS image
or APEX update being verified. The signing key and version are
enforced to prevent downgrades or other attacks such as replacing a
package with a variant of the same one from a different GrapheneOS
supported device. We disable the persistent package parsing cache to
prevent bypassing the metadata checks through this otherwise highly
persistent state, which only has a very small negative impact on boot
time from the data not being available from previous boots (typically
less than 1 second).</li>
<li>GrapheneOS closes a loophole where app-based system components
built as part of the OS can be downgraded to an older version due to
versionCode not being incremented when system components get updated
as part of changes to the OS. We enforce this both at package install
time and boot time.</li>
<li>Enhanced hardware-based attestation with more precise version information</li>
<li>Hardware-based security verification and monitoring via our
<a href="#auditor">Auditor app and attestation service</a></li>
<li>Compressed APEX module support is disabled as it's not useful for GrapheneOS,
uses extra unnecessary storage space and adds more verified boot attack surface.</li>
</ul>
</section>
</section>
<section id="more-complete-patching">
<h3><a href="#more-complete-patching">More complete patching</a></h3>
<p>GrapheneOS includes fixes for a large number of vulnerabilities not yet
fixed in Android.</p>
<p>We're able to quickly and safely ship the latest Linux kernel LTS point
releases on devices with GKI (Generic Kernel Image) support including the 6th
and 7th generation Pixel phones. At the time of writing on 2023-11-06,
GrapheneOS is using the latest Linux 5.10 GKI LTS release (5.10.199) for 6th
and 7th generation Pixel phones. The stock Pixel OS is on Linux 5.10.157 from
2022-12-02 with a small number of additional patches backported. This means
GrapheneOS provides hundreds of relevant kernel patches including many
security patches not yet included in the stock OS. It's possible for us to
stay several months ahead due to their approach of moving to new LTS releases
only in quarterly releases after a long freeze and testing process.</p>
<p>We often find new vulnerabilities ourselves and report them upstream. We've
reported dozens of vulnerabilities for both the generic Android codebase and
also for Pixels specifically. We also often find missed patches which were
supposed to be included but were missed, especially when there are device
specific components with partially shared but separate codebases for different
devices.</p>
<p>Our overall approach is to focus on systemic privacy and security
improvements but fixing individual vulnerabilities is still very
important.</p>
</section>
<section id="sandboxed-google-play">
<h3><a href="#sandboxed-google-play">Sandboxed Google Play</a></h3>
<p>GrapheneOS has a compatibility layer providing the option to install and use
the official releases of Google Play in the standard app sandbox. Google Play
receives absolutely no special access or privileges on GrapheneOS as opposed to
bypassing the app sandbox and receiving a massive amount of highly privileged
access. Instead, the compatibility layer teaches it how to work within the full
app sandbox. It also isn't used as a backend for the OS services as it would be
elsewhere since GrapheneOS doesn't use Google Play even when it's installed.</p>
<p>Since the Google Play apps are simply regular apps on GrapheneOS, you install
them within a specific user or work profile and they're only available within that
profile. Only apps within the same profile can use it, and they need to explicitly
choose to use it. It works the same way as any other app and has no special
capabilities. As with any other app, it can't access data of other apps and
requires explicit user consent to gain access to profile data or the standard
permissions. Apps within the same profile can communicate with mutual consent and
it's no different for sandboxed Google Play.</p>
<p>Sandboxed Google Play is close to being fully functional and provides near
complete compatibility with the app ecosystem depending on Google Play. Only a
small subset of privileged functionality which we haven't yet ported to
different approaches with our compatibility layer is unavailable. Some
functionality is inherently privileged and can't be provided as part of the
compatibility layer.</p>
<p>The vast majority of Play services functionality works perfectly including
dynamically downloaded/updated modules (dynamite modules) and functionality
provided by modular app components such as Google Play Games. By default,
location requests are rerouted to a reimplementation of the Play geolocation
service provided by GrapheneOS. You can disable rerouting and use the standard
Play services geolocation service instead if you want the Google network
location service and related features.</p>
<p>Our compatibility layer includes full support for the Play Store. Play
Store services are fully available including in-app purchases, Play Asset
Delivery, Play Feature Delivery and app/content license checks. It can
install, update and uninstall apps with the standard approach requiring that
the user authorizes it as an app source and consents to each action. It will
use the standard Android 12+ unattended update feature to do automatic updates
for apps where it was the last installer.</p>
<p>See the <a href="/usage#sandboxed-google-play-installation">usage guide
section on sandboxed Google Play</a> for instructions.</p>
</section>
<section id="android-auto">
<h3><a href="#android-auto">Android Auto</a></h3>
<p>GrapheneOS provides an option to install and use the official releases of
Android Auto.</p>
<p>Android Auto requires privileged access in order to work. GrapheneOS uses
an extension of the sandboxed Google Play compatibility layer to make Android
Auto work with a reduced level of privileges.</p>
<p>For more details, see the <a href="/usage#android-auto">usage guide section
on Android Auto</a>.</p>
</section>
<section id="network-permission-toggle">
<h3><a href="#network-permission-toggle">Network permission toggle</a></h3>
<p>GrapheneOS adds a Network permission toggle for disallowing both direct and
indirect access to any of the available networks. The device-local network
(localhost) is also guarded by this permission, which is important for
preventing apps from using it to communicate between profiles. Unlike a
firewall-based implementation, the Network permission toggle prevents apps
from using the network via APIs provided by the OS or other apps in the same
profile as long as they're marked appropriately.</p>
<p>The standard INTERNET permission used as the basis for the Network
permission toggle is enhanced with a second layer of enforcement and proper
support for granting/revoking it on a per-profile basis.</p>
<p>To avoid breaking compatibility with Android apps, the added permission
toggle is enabled by default. However, the OS app installation UI has been
extended to show the toggle as part of the installation confirmation page so
users can disable it when installing an app.</p>
<p>When the Network permission is disabled, GrapheneOS pretends the network is
down. It shows the network as down in various APIs, returns errors showing a
network connectivity issue rather than a revoked permission and avoids running
scheduled jobs depending on the network. This results in apps handling it as
if the network is down rather than crashing or showing errors from trying to
use the network and being unable to do it.</p>
</section>
<section id="sensors-permission-toggle">
<h3><a href="#sensors-permission-toggle">Sensors permission toggle</a></h3>
<p>Sensors permission toggle: disallow access to all other sensors not covered
by existing Android permissions (Camera, Microphone, Body Sensors, Activity
Recognition) including an accelerometer, gyroscope, compass, barometer,
thermometer and any other sensors present on a given device. When access is
disabled, apps receive zeroed data when they check for sensor values and don't
receive events. GrapheneOS creates an easy-to-disable notification when apps
try to access sensors blocked by the permission being denied. This makes the
feature more usable since users can tell if the app is trying to access this
functionality.</p>
<p>To avoid breaking compatibility with Android apps, the added permission is
enabled by default. When an app attempts to access sensors and receives zeroed
data due to being denied, GrapheneOS creates a notification that can be
easily disabled. The Sensors permission can be set to be disabled by default
for user installed apps in <b>Settings&#160;<span aria-label="and then">></span>
Security &amp; privacy&#160;<span aria-label="and then">></span>
More security &amp; privacy</b>.</p>
</section>
<section id="storage-scopes">
<h3><a href="#storage-scopes">Storage Scopes</a></h3>
<p>GrapheneOS provides Storage Scopes as a fully compatible alternative to the
standard Android storage permissions. Instead of granting storage permissions,
users can enable Storage Scopes to make the app assume that it has all storage
permissions that it asked for. On Android, an app that doesn't have any storage
permissions is still allowed to create files and directories, and is allowed to
access the files that it created. Users can optionally add files and directories
as storage scopes to permit the app to access files created by other apps.</p>
<p>For more details, see the <a href="/usage#storage-access">usage guide
section on storage access</a>.</p>
</section>
<section id="contact-scopes">
<h3><a href="#contact-scopes">Contact Scopes</a></h3>
<p>GrapheneOS provides Contact Scopes as an alternative to granting the
Contacts permission. By default, it acts as if the contacts list is empty and
users can grant different kinds of access to specific contacts or groups of
contacts.</p>
<p>For more details, see the <a href="/usage#contact-scopes">usage guide section
on Contact Scopes</a>.</p>
</section>
<section id="broad-carrier-support">
<h3><a href="#broad-carrier-support">Broad carrier support without invasive carrier access</a></h3>
<p>GrapheneOS has much broader carrier support than AOSP and mostly matches
the stock OS on Pixels without making the same sacrifices. We convert their
APN, carrier configuration, MMS and visual voicemail databases to the formats
used by AOSP with our CarrierConfig2 project and scripts. We strip out
anti-user configuration requiring provisioning for tethering, forbidding
disabling 2G, etc. We don't include the invasive carrier-specific apps and
support for Open Mobile Alliance Device Management (OMA DM) so we also strip
out configuration depending on those.</p>
<p>See our <a href="/usage#carrier-functionality">usage guide section on
carrier functionality</a> for more details.</p>
</section>
<section id="lte-only-mode">
<h3><a href="#lte-only-mode">LTE-only mode</a></h3>
<p><a href="/usage#lte-only-mode">LTE-only mode</a> to reduce cellular radio
attack surface by disabling enormous amounts of both legacy code (2G, 3G) and
bleeding edge code (5G).</p>
</section>
<section id="wifi-privacy">
<h3><a href="#wifi-privacy">Wi-Fi privacy</a></h3>
<p>GrapheneOS supports per-connection MAC randomization and enables it by
default. This is a more private approach than the standard persistent
per-network random MAC used by modern Android.</p>
<p>When the per-connection MAC randomization added by GrapheneOS is being
used, DHCP client state is flushed before reconnecting to a network to avoid
revealing that it's likely the same device as before.</p>
<p>GrapheneOS also applies fixes for serious flaws with the Linux kernel IPv6
privacy address implementation which allow using it as an identifier not just
for connections to the same network but also across different networks. We
don't need to apply these changes for the Pixel 6 and later since this was
fixed in the Linux kernel upstream, but hasn't been backported to earlier
kernel LTS branches so we still need to take care of it there.</p>
<p>See our <a href="/usage#wifi-privacy">usage guide section on Wi-Fi privacy
for more general information</a> rather than only our improvements to the
standard Wi-Fi privacy approach.</p>
</section>
<section id="private-screenshots">
<h3><a href="#private-screenshots">Private screenshots</a></h3>
<p>GrapheneOS disables the inclusion of sensitive metadata in screenshots.</p>
<p>On Android, each screenshot includes an EXIF Software tag with detailed OS
build/version information (<code>android.os.Build.DISPLAY</code>). It's the
same value shown at <b>Settings&#160;<span aria-label="and then">></span>
About device&#160;<span aria-label="and then">></span> Build number</b>. This
leaks the OS, OS version and also usually the device family/model since builds are
specific to a family of devices. GrapheneOS completely disables this
tag.</p>
<p>On Android, each screenshot also includes EXIF tags with the local date,
time and timezone offset. GrapheneOS disables this by default to
avoid leaking the time and quasi-location information through metadata that
isn't visible to the user. The date and time are already included in the file
name of the screenshot which is fully visible to the user and can be easily
modified by them without a third-party tool. GrapheneOS includes a toggle for
turning this metadata back on in <b>Settings&#160;<span aria-label="and then">></span>
Security &amp; privacy&#160;<span aria-label="and then">></span>
More security &amp; privacy</b> since some users may find it to be useful.</p>
</section>
<section id="closed-device-identifier-leaks">
<h3><a href="#closed-device-identifier-leaks">Closed device identifier leaks</a></h3>
<p>GrapheneOS fixes several prominent device identifier leaks bypassing
Android's intention of apps not being able to uniquely identify a device. See
our FAQ sections on <a href="/faq#hardware-identifiers">hardware
identifiers</a> and <a href="/faq#non-hardware-identifiers">non-hardware
identifiers</a> for more general information.</p>
<p>Our <a href="/usage#exec-spawning">secure application spawning system</a>
primarily exists to significantly improve protection against exploitation.
However, it also improves privacy. On a device without our secure application
spawning system, the secrets used for probabilistic exploit mitigations such
as ASLR are usable as device identifiers persisting until reboot. This is an
easy way to identify the device from apps in different profiles. It's a minor
bonus of the feature and there are still plenty of side channels to identify
devices across apps, but it fixes most of the known direct identifier
leaks.</p>
<p>We also eliminate several holes in preventing apps from accessing hardware
identifiers including tightening up the restrictions for apps targeting legacy
Android platform versions.</p>
</section>
<section id="privacy-by-default">
<h3><a href="#privacy-by-default">Privacy by default</a></h3>
<p>GrapheneOS doesn't include or use Google apps and services by default and
avoids including any other apps/services not aligned with our privacy and
security focus. Google apps and services can be used on GrapheneOS as regular
sandboxed apps without any special access or privileges through our <a
href="#sandboxed-google-play">sandboxed Google Play</a> feature, but we don't
include those apps by default to give users an explicit choice on whether they
want to use those apps and which profiles they want to use it in.</p>
<p>We change the default settings to prefer privacy over small conveniences:
personalized keyboard suggestions based on gathering input history are
disabled by default, sensitive notifications are hidden on the lockscreen by
default and passwords are hidden during entry by default.</p>
<p>Some of our changes for <a href="#attack-surface-reduction">attack surface
reduction</a> can also improve privacy by default by not exposing unnecessary
radios, etc. by default and avoiding the impact of potential privacy bugs with
the hardware.</p>
<p>By default, we also use GrapheneOS servers for the following services
instead of Google servers:</p>
<ul>
<li>Connectivity checks</li>
<li>Attestation key provisioning</li>
<li>GNSS almanac downloads (PSDS) for Broadcom and Qualcomm (XTRA)</li>
<li>Secure User Plane Location (SUPL)</li>
<li>Network time</li>
<li>Vanadium (Chromium) component updates</li>
</ul>
<p>We provide a toggle to switch back to Google's servers for connectivity
checks, attestation key provisioning and GNSS almanac downloads along with
adding proper support for disabling network time connections. This combines
with other toggles to allow making a GrapheneOS device appear to be an AOSP
device. This is only particularly important for connectivity checks since the
other connections get routed through a VPN which is needed to blend in on a
local network in practice.</p>
<p>In addition to our SUPL privacy improvements, we override the SUPL server
to our proxy by default. We also add a toggle for users to switch to the
standard SUPL server for their carrier (usually supl.google.com) or disable it
entirely.</p>
<p>See our <a href="/faq#default-connections">default connections FAQ entry
for much more detailed information</a>.</p>
</section>
<section id="pin-scrambling">
<h3><a href="#pin-scrambling">PIN scrambling</a></h3>
<p>GrapheneOS adds a toggle for enabling PIN scrambling to raise the
difficulty of figuring out the PIN being entered by a user either due to
physical proximity or a side channel. PIN scrambling is applied to both the
lock screen and SIM PIN/PUK.</p>
</section>
<section id="Two-factor-fingerprint-unlock">
<h3><a href="#Two-factor-fingerprint-unlock">Two-factor fingerprint unlock</a></h3>
<p>GrapheneOS adds the option to require entering a 2nd factor PIN after
successfully authenticating with a fingerprint on the lockscreen in order to
complete unlocking the device. Since Android/iOS use biometric unlock as a
secondary unlock mechanism for convenience, this allows users to make use of a
strong passphrase as their primary unlock method with the convenience of a
fingerprint and short PIN for secondary unlock. Failure to enter the correct PIN
counts towards the standard attempt limit.</p>
</section>
<section id="supports-longer-passwords">
<h3><a href="#supports-longer-passwords">Supports longer passwords</a></h3>
<p>GrapheneOS supports setting longer passwords by default: 128 characters
instead of 16 characters. This avoids the need to use a device manager to
enable this functionality.</p>
<p>This feature allows users to make use of diceware passwords if they don't
want to depend on the security of the secure element which provides very
aggressive throttling and offers a high level of security even for a random 6
digit PIN.</p>
</section>
<section id="auto-reboot">
<h3><a href="#auto-reboot">Auto reboot</a></h3>
<p>GrapheneOS provides an auto-reboot feature which reboots locked devices after
a set period of time to put data at rest. A countdown timer is started each time
the device is locked, and the device will reboot if a successful unlock doesn't
occur before the timer reaches zero. Unlocking any profile cancels the timer,
not just the Owner profile.</p>
<p>The timer is set to 18 hours by default, but can be set to values between 10
minutes and 72 hours, or turned off.</p>
<p>This feature doesn't apply when the device is in "Before First Unlock" state,
meaning that it will not lead to the device continuously rebooting, as data is
already at rest.</p>
<p>The feature is implemented in the init process, preventing it from being
bypassed through system process crashes since an init crash causes a kernel
panic which leads to a reboot.</p>
</section>
<section id="clearing-sensitive-data-from-memory">
<h3><a href="#clearing-sensitive-data-from-memory">Clearing sensitive data from memory</a></h3>
<p>As documented in our section on <a href="#exploit-mitigations">our added
exploit mitigations</a>, GrapheneOS adds zeroing of freed memory to both the
standard userspace and kernel allocators. These features have the secondary
benefit of clearing sensitive data from memory as soon as possible in addition
to defending against exploits. Android implements regular compaction of frozen
cached apps and apps currently running in the background based on triggering a
full compacting garbage collection (GC) and then requesting that malloc frees as
much memory as it can back to the OS. This pairs well with zeroing features and
results in freed data getting cleared faster for Java/Kotlin and also the C, C++
and Rust libraries used by them where low-level allocators get held onto until
the high level objects are freed.</p>
<p>When the device is locked, we trigger full compacting garbage collection (GC)
for the SystemUI and system_server processes to release all of the memory that's
no longer used back to the OS. Due to GrapheneOS enabling kernel page allocator
zeroing, this results in all the no longer referenced data in objects being
cleared. We based our approach on Android's standard approach to running a full
compacting GC for these two processes after the device is unlocked to clear
remnants of the user's PIN/password and keys derived from it. This is a nice way
to clear some data immediately after locking prior to our
<a href="#auto-reboot">auto-reboot</a> feature kicking in to clear all of the OS
memory.</p>
<p>GrapheneOS modifies some of the ways the device can be rebooted to proceed
with the normal reboot process where memory gets freed and cleared by the kernel
page and slab allocator zeroing features enabled by GrapheneOS.</p>
</section>
<section id="duress">
<h3><a href="#duress">Duress PIN/Password</a></h3>
<p>GrapheneOS provides users with the ability to set a duress PIN/Password that
will irreversibly wipe the device (along with any installed eSIMs) once entered
anywhere where the device credentials are requested (on the lockscreen, along
with any such prompt in the OS).</p>
<p>The wipe does not require a reboot and cannot be interrupted. It can be set
up at <b>Settings&#160;<span aria-label="and then">></span> Security &amp; privacy&#160;<span
aria-label="and then">></span> Device unlock&#160;<span
aria-label="and then">></span> Duress Password</b> in the owner profile. Both a
duress PIN and password will need to be set to account for different profiles
that may have different unlock methods.</p>
<p>Note that if the duress PIN/Password is the same as the actual unlock method,
the actual unlock method always takes precedence, and therefore no wipe will
occur.</p>
</section>
<section id="more-secure-fingerprint-unlock">
<h3><a href="#more-secure-fingerprint-unlock">More secure fingerprint unlock</a></h3>
<p>GrapheneOS improves the security of the fingerprint unlock feature by only
permitting 5 total attempts rather than implementing a 30 second delay between
every 5 failed attempts with a total of 20 attempts. This doesn't just reduce
the number of potential attempts but also makes it easy to disable fingerprint
unlock by intentionally failing to unlock 5 times with a different finger.</p>
<p>GrapheneOS also adds support for using the fingerprint scanner only for
authentication in apps and unlocking hardware keystore keys by toggling off
support for unlocking. This feature already existed for the standard Android
face unlock feature.</p>
</section>
<section id="improved-user-profiles">
<h3><a href="#improved-user-profiles">Improved user profiles</a></h3>
<p>Android's user profiles are isolated workspaces with their own instances of
apps, app data and profile data (contacts, media store, home directory, etc.).
Apps can't see the apps in other user profiles and can only communicate with
apps within the same user profile (with mutual consent with the other app).
Each user profile has their own encryption keys based on their lock method.
They're a great fit for GrapheneOS with a lot of room for improvement.</p>
<p>GrapheneOS provides improvements to user profile functionality and is
working on further improvements to make switching between them and monitoring
other profiles much more convenient.</p>
<section id="more-user-profiles">
<h4><a href="#more-user-profiles">More user profiles</a></h4>
<p>GrapheneOS raises the limit on the number of secondary user profiles to 32
(31 + guest) instead of only 4 (3 + guest) to make this feature much more
flexible.</p>
</section>
<section id="end-session">
<h4><a href="#end-session">End session</a></h4>
<p>GrapheneOS also enables support for logging out of user profiles without
needing a device manager controlling the device to use this feature. Logging
out makes profiles inactive so none of the apps installed in them can run. It
also purges the disk encryption keys from memory and hardware registers,
putting the user profile back at rest.</p>
</section>
<section id="disabling-app-installation">
<h4><a href="#disabling-app-installation">Disabling app installation</a></h4>
<p>GrapheneOS adds a toggle to the user management settings for disabling
secondary user app installation. You can install the apps you want to be
usable in a secondary user and then disable the ability to install more apps
as that user in the Owner profile. Android supports this as a standard device
management feature but doesn't make it available to a user who owns their own
device.</p>
</section>
<section id="install-available-apps">
<h4><a href="#install-available-apps">Improved install available apps</a></h4>
<p>GrapheneOS enables the standard install available apps feature that's
still not enabled in AOSP or the stock Pixel OS to allow the Owner user to
install packages that are available in other users. This allows installing
an app in a secondary user that's already installed in the Owner user
without needing to download it again. This helps a lot with using the
toggles added for disabling app installation by secondary users.</p>
</section>
<section id="notification-forwarding">
<h4><a href="#notification-forwarding">Notification forwarding</a></h4>
<p>GrapheneOS supports forwarding notifications from users running in the
background to the currently active user. Forwarding notifications to other
users is disabled by default and can be enabled within each user profile
where forwarding to the active profile is wanted. Notifications forwarded
from other profiles are displayed by default in a standard local
notification channel.</p>
</section>
</section>
<section id="grapheneos-app-repository">
<h3><a href="#grapheneos-app-repository">GrapheneOS app repository</a></h3>
<p>GrapheneOS includes our own security, minimalism and usability-focused app
repository client for using our first-party app repository. Our app repository
is currently used to distribute our own apps and a mirror of Google Play for
the sandboxed Google Play feature. In the future, it will be used to
distribute first-party GrapheneOS builds of externally developed open source
apps with hardening applied.</p>
</section>
<section id="vanadium">
<h3><a href="#vanadium">Vanadium: hardened WebView and default browser</a></h3>
<p>GrapheneOS includes our Vanadium browser as WebView implementation provided
by the OS and our default browser. Vanadium is a hardened variant of Chromium
providing enhanced privacy and security, similar to how GrapheneOS compares to
AOSP. The Vanadium browser currently doesn't add many features but there are a
lot of enhancements planned in the long term.</p>
<p>Some of the features added compared to standard mobile Chromium:</p>
<ul>
<li>Hardware memory tagging (MTE) enabled for the main allocator</li>
<li>Type-based Control Flow Integrity (CFI)</li>
<li>Strong stack protector</li>
<li>Automatic zero-initialized variables</li>
<li>Well-defined signed overflow</li>
<li>Strict site isolation and sandboxed iframes</li>
<li>JavaScript JIT disabled by default with per-site toggle via drop-down
permission menu</li>
<li>Dynamic code execution is blocked for processes without the JavaScript
JIT enabled as an extension to the seccomp-bpf sandbox</li>
<li>Native Android autofill implementation to avoid needing sandboxed Google
Play for autofill support</li>
<li>WebGPU disabled for attack surface reduction</li>
<li>WebRTC IP handling policy toggle to control peer-to-peer WebRTC mode</li>
<li>High performance content filtering engine using EasyList + EasyPrivacy
with per-site toggle via drop-down permission menu</li>
<li>More complete state partitioning without origin trial opt-out</li>
<li>Standard Android 16 user agent reduction is enabled early for the
WebView to replace the major OS version, device model and browser
minor/build/patch version with standard placeholder values</li>
<li>High entropy client hints are replaced with the standard placeholder
values used in Chromium's reduced user agent for both the browser and
WebView to close a loophole where Chromium is still sharing the major OS
version, device model and browser minor/build/patch version with any server
requesting it via client hints</li>
<li>Battery API always shows the battery as charging and at 100% capacity</li>
<li>Trivial subdomain hiding disabled</li>
<li>Consistent browser behavior across users without usage of feature flags
and seed-based trials</li>
<li>Nearly all remote services disabled by default or removed. Only connects
to GrapheneOS servers by default. There are only 2 default services:
component updates such as certificate authority and certificate revocation
updates and DNS-over-HTTPS connectivity checks when enabled</li>
<li>Web search and global search intents to replace the need for an OS
search app</li>
<li>Option to always open links from other apps, custom tabs, search intents
and share intents in Incognito mode</li>
<li>Option to reduce or disable sending cross-origin referrer information
sharing where a link was opened</li>
<li>Hybrid post-quantum cryptography enabled by default to match the
behavior of Chromium on desktop since the devices we support are more
than fast enough</li>
</ul>
<p>Better default settings, including non-user-facing flags:</p>
<ul>
<li>Reduce Accept-Language header by default (only available via
chrome://flags)</li>
<li>Third party cookies disabled by default</li>
<li>Payment support disabled by default</li>
<li>Website background sync disabled by default</li>
<li>Sensors access disabled by default</li>
<li>Protected media (DRM) disabled by default</li>
<li>Hyperlink auditing disabled by default</li>
<li>Do Not Track enabled by default mainly to avoid users differentiating
themselves from others by enabling it since it has no real value</li>
<li>WebRTC IP handling policy set to the most private value by default
instead of the least private value (turned into a user-facing option by
Vanadium)</li>
</ul>
<p>Configurable features such as JS JIT disabling and content filtering are
currently exclusive to the Vanadium browser. Vanadium WebView is currently
excluded from these changes until it has an app setting configuration menu
similar to the standard site setting configuration menu.</p>
<p>Extension support isn't planned due to being at odds with site isolation and
anti-fingerprinting. We plan to implement more features as part of the browser
with a focus on privacy and security improvements which can be active by default
rather than opt-in niche features. Improvements will generally be opt-out on a
per-site basis rather than opt-in to provide privacy and security by default and
to avoid users making themselves more identifiable by opting into privacy and
security features. Default-disabled JS JIT and default-enabled content filtering
are early examples of this approach we plan to expand upon.</p>
<p>We plan to add more site settings toggles related to attack surface reduction
such as site setting toggles for WebGL, WebGPU, WebRTC and other features which
are normally always enabled. This will help with both security and improving the
defenses against fingerprinting.</p>
<p>Anti-fingerprinting depends on having a large userbase with the same browser,
extensions, content filters and other web-facing configuration. Once Vanadium
has more features, it will be made available outside GrapheneOS to expand the
userbase. Our approach to attack surface reduction eliminates fingerprinting
methods in addition to attack surface for exploits and this will be a key part
of how we approach preventing fingerprinting by not having features like WebGL,
WebGPU and WebRTC exposed in the first place. Good defaults and avoiding having
users changing web-facing configuration is an important part of this. Content
filters will remain standard across users and updated together as part of the
Vanadium configuration app. We'll address the need for language-focused filters
by enabling them based on browser language configuration. Fingerprinting based
on hardware differences will become more relevant once Vanadium is available
outside of GrapheneOS which will always support a small set of highly secure
devices.</p>
<p>State partitioning still needs to be fully completed. The main remaining
hurdle is providing full cookie partitioning. Mainstream browsers with this
feature rely on heuristics bypassing cookie partitioning which can be easily
abused to bypass the feature. We tried deploying full cookie partitioning by
default but had to roll it back and will need to consider how to approach this
particularly with our goal of having most Vanadium users using nearly the same
configuration.</p>
<p>We plan to move to a better content engine with support for more advanced
filter rules and cosmetic filtering in the future. Expanding the standard
filters will depend on having support for the extensions used by uBlock Origin,
AdGuard and other filters.</p>
<p>Most browser data is currently excluded from OS backups, which will likely be
changed once GrapheneOS has a better backup service included. Export/import for
bookmarks and similar data export/import features are also planned. Sync beyond
OS backup service support which will eventually provide per-app backup and
restore including across devices and via sync services is not planned.</p>
<p>More information is available in the <a href="/usage#web-browsing">web
browsing section of our usage guide</a>.</p>
</section>
<section id="auditor">
<h3><a href="#auditor">Auditor app and attestation service</a></h3>
<p>Our <a href="https://github.com/GrapheneOS/Auditor/releases">Auditor
app</a> and <a href="https://attestation.app/">attestation service</a>
provide strong hardware-based verification of the authenticity and integrity
of the firmware/software on the device. A strong pairing-based approach is
used which also verifies the device's identity based on the
hardware-backed key generated for each pairing. Software-based checks are
layered on top with trust securely chained from the hardware. For more
details, see the <a href="https://attestation.app/about">About</a> and
<a href="https://attestation.app/tutorial">Tutorial</a> pages.</p>
</section>
<section id="grapheneos-camera">
<h3><a href="#grapheneos-camera">GrapheneOS Camera</a></h3>
<p><a href="/usage#grapheneos-camera-app">GrapheneOS Camera</a> is a modern
camera app with a great user interface and a focus on privacy and
security. More details are available in the <a href="/usage#camera">camera
section of our usage guide</a>.</p>
</section>
<section id="grapheneos-pdf-viewer">
<h3><a href="#grapheneos-pdf-viewer">GrapheneOS PDF Viewer</a></h3>
<p><a href="https://github.com/GrapheneOS/PdfViewer">GrapheneOS PDF Viewer</a>
is a sandboxed, hardened PDF viewer using HiDPI rendering with features like
pinch to zoom, text selection, viewing encrypted PDFs, etc.</p>
</section>
<section id="setup-wizard">
<h3><a href="#setup-wizard">Setup Wizard</a></h3>
<p>We have our own Setup Wizard for the initial setup of the device and for user
profiles. It's very similar to the Setup Wizard in the stock Pixel OS but has
more emphasis on security. It detects an unlocked bootloader at the start and
warns the user about it with a button for rebooting to fastboot mode in order to
lock the device. Skipping the warning requires waiting for a timer to prevent
quickly skipping through it and missing the important information. Our setup
wizard also disables OEM unlocking by default at the end of the process with a
toggle to opt-out of it being disabled, which is a small but useful reduction in
attack surface. We plan to include our improvements to lock method options in
our Setup Wizard including 2-factor fingerprint authentication along with
generating random diceware passphrases and PINs automatically.</p>
</section>
<section id="encrypted-backups">
<h3><a href="#encrypted-backups">Encrypted backups</a></h3>
<p>Encrypted backups via integration of the
<a href="https://github.com/GrapheneOS/platform_external_seedvault">Seedvault
app</a> with support for local backups and any cloud storage provider with a
storage provider app.</p>
<p>Seedvault was created by a GrapheneOS community member for inclusion in our
operating system. We plan on replacing it with a new implementation since the
project has been taken over by another group of people not sharing our goals
or approach. For now, this is the best available option, so we're including it
to give people encrypted backup support. We've made several security fixes to
work around upstream issues with the project.</p>
</section>
<section id="location-data-access-indicator">
<h3><a href="#location-data-access-indicator">Location data access indicator</a></h3>
<p>GrapheneOS enables the privacy indicator for location data access in
addition to the standard Android camera and microphone indicators. This shows
an indicator when an app the user has granted permission to access location
requests location data. We also resolve various UX issues with this feature as
it currently exists in AOSP to get it into a highly usable state.</p>
<p>Android 13 has the location privacy indicator as a developer option but it
doesn't work the same way as it does in GrapheneOS. GrapheneOS shows it for
all location data accesses through any APIs. Normally, the stock OS only shows
it for GNSS location requests, also known as high power location requests, and
doesn't normally show it for network location and other APIs gated by the
Location permission / global block toggle.</p>
<p>The indicator works the same way as the Camera and Microphone ones, showing
a bright green icon when location access occurs which then gets minimized to a
small bright green dot when the quick settings tray isn't currently opened.
Android 12 already includes Location with the other standard runtime
permissions in the privacy dashboard for viewing the history.</p>
</section>
<section id="user-installed-apps-can-be-disabled">
<h3><a href="#user-installed-apps-can-be-disabled">User installed apps can be disabled</a></h3>
<p>GrapheneOS adds support for disabling user installed apps instead of only
being able to disable system apps. This allows users to completely prevent one
of the apps they've installed from being able to run without being forced to
uninstall it and lose their app data. This is much stricter than the standard
force stop feature which only prevents an app from starting itself and the app
will start running again as soon as another app tries to open an activity or
service it provides.</p>
</section>
<section id="improved-vpn-leak-blocking">
<h3><a href="#improved-vpn-leak-blocking">Improved VPN leak blocking</a></h3>
<p>GrapheneOS greatly improves Android's protection against VPN leaks for both
the built-in VPN support and VPN apps with the standard "Block connections
without VPN" toggle enabled.</p>
<p>Android allows DNS queries from the system resolver to leak to the network
provided DNS servers when a VPN app goes down due to a race condition. It also
similarly allows connections to the VPN DNS servers to happen outside of the VPN
tunnel. Both of these are fully prevented by GrapheneOS through extending the
leak blocking to this part of the system resolver, fully preventing unicast DNS
leaks.</p>
<p>Android allows processes including apps to bypass the VPN entirely whether
it's up or down by sending multicast packets either directly or by causing the
kernel to send the packets on their behalf through the standard multicast group
management system calls. GrapheneOS extends Android's standard eBPF filtering
with full support for blocking all forms of multicast packet bypasses.</p>
<p>Android VPN configuration is split up for each profile which means work
profiles, Private Spaces and secondary users have their own VPN configuration
which is a fantastic privacy feature. Android has a standard restriction
preventing processes from using a network which the current profile isn't
allowed to access. However, this doesn't take multicast packets into account and
it's possible to send multicast packets via VPN tunnels belonging to a different
profile. GrapheneOS addresses this by extending the standard netfilter
configuration with a multicast firewall preventing sending packets through a VPN
tunnel which a process isn't supposed to be able to access.</p>
<p>Finding and resolving all forms of VPN leaks is one of our top priorities at
the moment and we don't currently consider this to be a complete feature due to
less severe additional issues we've discovered.</p>
</section>
<section id="log-viewer-and-crash-reporting">
<h3><a href="#log-viewer-and-crash-reporting">Log viewer and user-facing crash reporting</a></h3>
<p>GrapheneOS adds a user-facing log viewer to the Settings app for Android's
standard in-memory logging system. The feature acts as a substitute for
automated crash reporting which is not implemented by GrapheneOS for privacy
reasons. Instead, users are in control of what's captured and shared. Our log
viewer supports filtering the output based on log level, log buffers and text
search. Users can copy, share or save the currently shown logs to a file. A
description can be added to document why the logs were captured.</p>
<p>Overall system logs can be accessed at <b>Settings&#160;<span aria-label="and then">></span>
System&#160;<span aria-label="and then">></span> View logs</b>. Per-app logs can
be accessed at <b>Settings&#160;<span aria-label="and then">></span>
Apps&#160;<span aria-label="and then">></span> App name&#160;<span
aria-label="and then">></span> View logs</b>.</p>
<p>We implement user-facing crash reporting tied to our log viewer for OS and
app crashes, greatly improving upon the very limited user-facing crash reporting
available in Android. This helps users report crashes to the OS or app
developers without requiring invasive automated crash reporting where users
don't control the data that's sent to developers.</p>
<p>Our user-facing crash reporting has special support for memory corruption
caught by hardened_malloc and hardware memory tagging informing users that
memory corruption was detected. Users choose how to proceed and whether it makes
sense to enable our compatibility toggles for the app if they don't believe it
was an exploit but rather an app bug they need to work around. It's a careful
balance between not encouraging users to disable security features protecting
user installed apps from exploits and making it easy to work around app bugs. We
don't allow disabling these exploit protection features for the base OS
including base OS apps, but too many user installed apps have latent memory
corruption bugs and we need to provide the option to work around them.</p>
<p>Users can enable more system crash reporting via <b>Settings&#160;<span aria-label="and then">></span>
Security &amp; privacy&#160;<span aria-label="and then">></span>
More security &amp; privacy&#160;<span aria-label="and then">></span>
Notify about system process crashes</b>. We don't enable reporting all kernel or
system process crashes by default since we can't manage triaging and
investigating every single Android OS bug causing a crash. We're focused on the
memory corruption crashes caught by hardware memory tagging so those are always
reported. Fixing every Android bug ourselves is not something we can hope to
accomplish so we focus our resources on the ones found by our improvements which
also have a higher chance of being security bugs.</p>
</section>
<section id="other-features">
<h3><a href="#other-features">Other features</a></h3>
<p>This is an incomplete list of other GrapheneOS features.</p>
<ul>
<li>Per-profile encrypted file name padding increased from 16 bytes to 32
bytes to reduce the information leaked through file name lengths. See the
FAQ section on <a href="/faq#encryption">the filesystem-based full disk
encryption</a> used by modern Android and GrapheneOS for more information.</li>
<li>Improved user visibility into persistent firmware security through version
and configuration verification with reporting of inconsistencies and debug
features being enabled.</li>
<li>Authenticated encryption for network time updates via a first-party server to
prevent attackers from changing the time and enabling attacks based on bypassing
certificate / key expiry, etc.</li>
<li>Proper support for disabling network time updates rather than just not using
the results</li>
<li>Hardened local build / signing infrastructure</li>
<li><a href="/usage#updates">Seamless automatic OS update system</a> that just
works and stays out of the way in the background without disrupting device
usage, with full support for the standard automatic rollback if the first boot
of the updated OS fails</li>
<li>Require unlocking to access sensitive functionality via quick tiles</li>
<li><a href="/faq#bundled-apps">Minimal bundled apps and services</a>. Only
essential apps are integrated into the OS. We don't make partnerships with
apps and services to bundle them into the OS. An app may be the best choice
today but a poor choice in the future, and vice-versa. Our approach will be recommending certain
apps during the initial setup, not hard-wiring them into the OS.</li>
<li>Wireless alerts are completely optional since GrapheneOS adds a toggle for
the otherwise mandatory presidential alert type. This is particularly
useful in Canada where the government abuses the system and sends every
type of alert as a presidential alert to stop users from being able to opt
out of weather and amber alerts.</li>
<li>Removal of TrustCor root certificate authority as a trusted system CA.</li>
<li>Secure-by-default Android 12 PendingIntent security check (FLAG_IMMUTABLE)
instead of crash-by-default improving older app compatibility and security.</li>
<li>Fixed UART debugging enabled warning on official release builds.</li>
<li>Engineering / Prototype ("EVT", "PVT" or "DVT") device warning as these
devices typically have relaxed security controls for development, mainly
the secure boot state property <code>ro.boot.secure_boot</code> not set
to <code>PRODUCTION</code>.</li>
<li>Enable bootloader, radio, and boot partition version / fingerprint
checks.</li>
<li>Remove code automatically granting the location permission to system
browsers.</li>
<li>Apps that don't have any storage permission aren't allowed to read the
list of all user-created directories (this is allowed on Android). The list of
files is hidden from such apps on both Android and GrapheneOS.</li>
<li>Screenshot shutter sound is toggleable using the <b>Tap &amp; click
sounds</b> option in <b>Settings&#160;<span aria-label="and then">></span>
Sound &amp; vibration</b> while still following the standard method of
putting the device on vibration/silent mode to turn off the screenshot shutter
sound.</li>
<li>More precise system clock via lowering the system clock time update
threshold from 2000ms to 50ms and lowering the system clock drift warning
from 2000ms to 250ms. This can be helpful for time-based protocols such as
TOTP.</li>
<li>Call recording functionality within the Dialer app using modern Android
storage with recordings stored in Recordings/Call Recordings and no restrictions based
on region or special cases like playing a recording tone (users are still responsible
for complying with their local laws).</li>
<li>Change standard Android package installer behavior to preserving
packages being disabled after updating them instead of them being
re-enabled.</li>
<li>Enable the "Always-on VPN" and "Block connections without VPN" toggles
for VPNs by default.</li>
<li>Permission prompts and the Android Debug Bridge USB authorization prompt
have the allow action disabled by default with a 1 second delay before it
becomes active. This protects against accidental presses, especially since
an app can trick the user into doing it by having them push a button where
the system dialog will be displayed.</li>
</ul>
</section>
</section>
<section id="services">
<h2><a href="#services">Services</a></h2>
<p>Service infrastructure features:</p>
<ul>
<li>Strict privacy and security practices for our infrastructure</li>
<li>Unnecessary logging is avoided, and logs are automatically purged after 4
days (network services used by the OS) to 10 days</li>
<li>Services are hosted entirely via our own dedicated servers and virtual
machines from OVH (and BuyVM for mirrors) without involving any additional
parties for CDNs, SaaS platforms, mirrors or other services</li>
<li>Our services are built with open technology stacks to avoid being locked into
any particular hosting provider or vendor</li>
<li>Open documentation on our infrastructure including listing out all of our
services, guides on making similar setups, published configurations for each
of our web services, etc.</li>
<li>No proprietary services</li>
<li>Authenticated encryption for all of our services</li>
<li>Strong cipher configurations for all of our services (SSH, TLS, etc.) with
only modern AEAD ciphers providing forward secrecy</li>
<li>Our web sites do not include any third party content and entirely forbid
it via strict Content Security Policy rules</li>
<li>Our web sites disable referrer headers to maximize privacy</li>
<li>Our web sites fully enable cross origin isolation and disable embedding in
other content</li>
<li><a href="https://internet.nl/faqs/dnssec/">DNSSEC</a> implemented for all
of our domains to provide a root of trust for encryption and authentication
for domain/server configuration</li>
<li>DNS Certification Authority Authorization (CAA) records for all of our
domains permitting only Let's Encrypt to issue certificates with fully
integrated support for the <code>accounturi</code> and
<code>validationmethods</code> pinning our Let's Encrypt accounts as the only
ones allowed to issue certificates</li>
<li>DANE TLSA records for pinning keys for all our TLS services</li>
<li>Our mail server enforces DNSSEC/DANE to provide authenticated encryption
when sending mail including alert messages from the attestation service</li>
<li>SSHFP across all domains for pinning SSH keys</li>
<li>Static key pinning for our services in apps like Auditor</li>
<li>Our web services use robust OCSP stapling with Must-Staple</li>
<li>No persistent cookies or similar client-side state for anything other than
login sessions, which are set up securely using <code>SameSite=Strict</code>,
<code>Secure</code>, <code>HttpOnly</code>, and <code>Path=/</code> flags, prefixed with
<code>__Host</code> and have server-side session tracking with the ability to log out
of other sessions</li>
<li>scrypt-based password hashing (likely Argon2 when the available implementations
are more mature)</li>
</ul>
</section>
<section id="project">
<h2><a href="#project">Project</a></h2>
<p>Beyond the technical features of the OS:</p>
<ul>
<li>Collaborative, <a href="/source">open source project</a> with a
<a href="/contact#community">very active community</a> and contributors</li>
<li>You can make your own builds and make desired changes, so you aren't stuck with
the decisions made by the upstream project</li>
<li>Non-profit project avoiding conflicts of interest by keeping commercialization
at a distance. Companies support the project
<a href="/faq#company">rather than the project serving the needs of any
particular company</a></li>
<li><a href="/faq#privacy-policy">Strong privacy policies</a> across all our
software and services</li>
<li><a href="/history/">Proven track record</a> of the team standing up
against attempts to compromise the integrity of the project and placing it
above personal gain</li>
</ul>
</section>
</main>
{% include "footer.html" %}
</body>
</html>