Security and Privacy on KaiOS

Posted by Tom Barrasso on (updated on )

Security and Privacy considerations for KaiOS smart feature phones

KaiOS is based on Firefox OS, and as a result, many of the same technologies apply to Security & Privacy within KaiOS apps.

Content Security Policy (CSP)

The Content Security Policy (CSP) prevents attacks like Cross-Site Scripting (XSS) by limiting the origins that specific resources like scripts, objects, and stylesheets can be loaded from. KaiOS imposes default CSPs on Privileged & Certified packaged apps. It’s possible to override this using the csp manifest property, but the provided value can only be more strict than KaiOS’ default.

Privileged (security.apps.privileged.CSP.default)

1default-src * data: blob:; script-src 'self' http://127.0.0.1:8081 http://local-device.kaiostech.com:8081; object-src 'none'; style-src 'self' 'unsafe-inline'

Note: local addresses like http://127.0.0.1:8081 serve KaiAds scripts, and packages like app://shared.gaiamobile.org are made accessible to provide a set of shared resources across system apps. Although it’s possible, they are not intended to be accessed by third-party apps.

Certified (security.apps.certified.CSP.default)

1default-src * data: blob:; script-src 'self' http://127.0.0.1:8081 http://local-device.kaiostech.com:8081 app://theme.gaiamobile.org; object-src 'none'; style-src 'self' 'unsafe-inline' app://theme.gaiamobile.org app://shared.gaiamobile.org

Warning: the behavior for the CSP of Certified apps is actually hard-coded in nsCSPService.cpp.

Same Origin Policy

The Same-Origin Policy is a security mechanism in web browsers that restricts resources (document or script) loaded by one origin interact with resources from another origin. An origin is defined by:

  • scheme (aka protocol, i.e. HTTP & HTTPS),
  • port (typically 80 for HTTP and 443 for HTTPS)
  • host

What this means in practice is that there are restrictions in place on accessing content (iframes, CSS, JavaScript, forms, images, and audio/ video) served from different domains.

Cross-Origin Resource Sharing (CORS)

CORS is what allows the sharing of certain resources that would have otherwise been blocked by the Same Origin Policy. With the use of certain HTTP headers like Access-Control-Allow-Origin, a website can allow resource sharing to any and all origins. This is why it’s possible to load scripts hosted by CDNs like CDNJS.

When making certain requests using XMLHttpRequest or fetch, the browser might first initaite an OPTIONS request known as a CORS preflight request. OPTIONS is basically a HEAD request with no body and specific CORS headers included.

Within a Privileged app on KaiOS it is possible to use XMLHttpRequest without CORS, making APIs from external websites accessible similar to a native app on Android or iOS. What’s considered cross-origin on KaiOS? For packaged apps, it is anything that doesn’t match the origin property in manifest.webapp (KaiOS 2.5) or manifest.webmanifest (KaiOS 3.0). For hosted apps, it is anything that doesn’t match the origin serving the app.

Note: packaged apps without an explicit origin in their manifest will be assigned a UUID, i.e. app://b750bc47-2c33-0b4e-9d32-c7ef92463424/ on KaiOS 2.5 or https://b750bc47-2c33-0b4e-9d32-c7ef92463424.localhost/ on KaiOS 3.0.

Transport Layer Security (TLS)

TLS is a security protocol commonly used on the web and the successor of Secure Sockets Layer (SSL). It provides encryption, authentication, and integrity, identifying an origin server via an SSL Certificate issued by a Certificate Authority for a specific domain. Thanks to public key cryptography, someone can visit https://KaiOS.dev (notice the HTTPS), and even if an attacker could read the messages being exchanged, their contents would be unreadable as they are encrypted. This is especially important for websites that offer logins or involve the collection of sensitive data, like banks or messaging services.

Note: due to the expired IdenTrust DST Root CA X3 root certificate, do not use Let’s Encrypt SSL Certificates for services accessed by KaiOS apps.

HyperText Transfer Protocol Secure (HTTPS)

HTTPS is the successor of HTTP–HTTP with TLS (SSL) encryptions–and collectively these protocols make up the web. Why use HTTPS? Well in 2023, HTTPS is important to safeguard user privacy. Moreover, it is effectively required to avoid “Secure Site Not Available” warnings and for your website to be indexed by search engines like Google. KaiOS apps should only access secure services from websites hosted over HTTPS.

Note: HTTPS is required for hosted web and progressive web apps.

Secure Context

A secure context is a Window or Worker scope that meets standards for authentication and confidentiality. Certain Web APIs and features are only accessible in a secure context. The following features require a secure context:

  • Push
  • Geolocation
  • Notifications
  • Service Workers
  • Storage

To be considered a secure context, the following criteria must be met:

  • served over https:// or wss:// URLs
    • or served locally via http://localhost, http://*.localhost, http://127.0.0.1
  • must not use deprecated network security

This can be checked at runtime via the boolean window.isSecureContext property. Note: window.isSecureContext is available on KaiOS 3.0 but not KaiOS 2.5. It’s best to check this property when available because on Firefox, attempting to access certain APIs outside of a secure context will throw a DOMException with the message The Operation is insecure.

Mixed Content

An HTTPS website that also includes content served over cleartext HTTP is considered mixed content. This means that the pages is only partially encrypted, making unencrypted content vulnerable to sniffers and man-in-the-middle (MITM) attacks. That effectively leaves the page unsafe. What browsers do varies depending on whether the mixed content is passive content or active content.

Passive content includes multimedia like <img>, <video>, and <audio>. Active content includes fetch and XMLHttpRequest, <script>, <link>, <iframe>, navigator.sendBeacon, and CSS url() values. Browser behavior with mixed content varies, with the most strict being Safari which does not allow any mixed content. On WebIDE, you will see console statements when attempting to load mixed content. Requests for active content will be blocked, while requests for passive content may generate warnings.

HTTP Strict-Transport-Security (HSTS)

The Strict-Transport-Security, referred to as HSTS, is an HTTP header tells a browser that a site should only be accessible using HTTPS. Depending on it’s configuration, future attempts to access the site will automatically be upgraded from HTTP to HTTPS.

Cookies

Like any web browser, KaiOS supports Cookies, with KaiOS 2.5 placing fewer restrictions than KaiOS 3.0. Cookies are useful for many purposes, including session management, personalization, and tracking. The sandboxed-cookies permission on KaiOS 2.5 will replicate the default behavior on KaiOS 3.0, forcing the reading/ writing of cookies to apps individually. On KaiOS 2.5, cookies can be set client side using document.cookie including in packaged apps with a defined origin, despite the app:// procotol. On KaiOS 3.0, this behavior is changed: packaged apps are served from an origin like https://myapp.localhost, rendering client-side cookie setting useless since they are scoped to a local loopback address.

Note: cookies can be marked as HttpOnly, making them inaccessible via document.cookie. It’s best practice to limit cookie access as much as possible.

Subresource Integrity (SRI)

Subresource Integrity (SRI) is an optional security feature browsers use to verify that resources fetched, like those from Content Delivery Networks (CDNs), are delivered untampered. You specify a cryptographic algorithm and hash using the integrity attribute, and the browser will check that the downloaded resource matches the hash provided. If the hash does not match, the resource will not be loaded.

1<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" integrity="sha384-8gBf6Y4YYq7Jx97PIqmTwLPin4hxIzQw5aDmUg/DDhul9fFpbbLcLh3nTIIDJKhx" crossorigin="anonymous"></script>

This attribute only applies to <script> or <link> elements. Because of KaiOS’ default CSP, SRIs are primarily useful when serving a hosted or progressive web app (PWA) that references resources served by CDNs. Additionally, since the SRI is static, you will need to used pinned-version dependencies like jQuery 2.1.4, instead of @latest. Otherwise, when the resource content changes, it would no longer match the hash and it would fail to load.

KaiOS Web Apps vs Android & iOS Native Apps

Permissions

KaiOS apps declare permissions in their manifest.webapp or manifest.webmanifest files. This is similar to how iOS applications request permissions in Info.plist and Android in AndroidManifest.xml. Available permissions depend on app type (web, privileged, or certified). While some permissions are granted transparently, other permissions trigger a dialog at runtime requiring the user to explicitly grant permission (which can later be revoked in Settings). This means it’s important to check the availability of certain features and catch SecurityError at runtime to build an effective user experience.

Source Disclosure

Android apps run on the Dalvik Virtual Machine or Android RunTime (ART) using Java/ Kotlin source code compiled into Dex bytecode. iOS apps use LLVM to compile Objective-C/ Swift source code into machine code. Although there are numerous Java decompilers, in practice this means that raw source code is not easily available for native Android or iOS.

In contrast, KaiOS apps are basically web apps. Since JavaScript on the web is an interpretted, not compiled, language, source code is readily available. Of course it’s possible (and recommended) to bundle & minify source before shipping. Additionally, it’s also possible to use an obfuscator to make it difficult to reverse-engineer your app’s functionality. That said, either method provide real safeguard against source disclosure.

Data Security

Android provides a Keystore to easily store encrypted data locally while making it difficult to extract. While KaiOS does not provide a similar, convenient service, it does support the Web Crypto API. It is generally possible to encrypt data in localStorage or indexedDB using custom secret keys. Of course the challenge then is storage of the secret key itself. For most use cases this isn’t necesaary, and for highly sensitive data, the best approach is simply to not store it on the client at all!

Code Signing

KaiOS automatically provides code signing via the KaiStore. This is similar to Android, which provides code signing via the Google Play Store, and iOS which provides code signing via the App Store. KaiOS applications packaged as ZIP files from the KaiStore include the following contents:

  • application.zip
    • /META-INF
      • id.json
      • manifest.mf
      • zigbert.rsa
      • zigbert.sf

Applications are signed with KaiOS’ root certificate, and cryptographic digests (MD5 and SHA1) are provided for each file within application.zip. Certificates are validated client-side at the point of installation, and invalid signatures will cause the installation to fail. This effectively places a digital signature on the packaged application, ensuring it’s authenticity and integrity against modification or tampering.

Note: code signing happens transparently and automatically for developers. That said, code signatures come with expiration dates (typically one year). On multiple occassions I have seen had my applications become uninstallable due to expired signatures. In these cases, I have had to wait for KaiStore or JioStore support to upload new, re-signed builds.

Cross-Site Request Forgery

Because KaiOS apps can be launched just like websites using Web Activities, window.open, or both, it’s important to require user confirmation and restrict sensitive operations using secure tokens. For instance, on KaiOS 3.0 an application could open another like this:

1window.open('https://bankapp.localhost/transfer.html?to=Attacker&amount=500')

A very bad Bank App might load the user from a session cookie and initiate the transfer immediately. A more secure Bank App would require user confirmation and passcode re-entry for this action, use the HTTP POST protocol, and issue CSRF Tokens to prevent form submission from third-parties. It may still be a good user experience for services like PayPal or Venmo to pull up a pre-populated transfer page as part of a Transfer activity that allows users to easily request money from friends. However, it’s important to do so securely! Even though Android’s Intent doesn’t allow arbitrary pages to be opened, these are still important considerations for native apps as well.

Referrer

Unlike native apps, web apps might send a Referrer header disclosing the website (or even web page) initiating the request. In the context of KaiOS, the Referrer is your app’s origin. This can be disabled via several methods, including the Referrer-Policy header or rel attribute for HTML tags like anchor links, i.e. <a rel="noreferrer">.

Conclusion

Although KaiOS functions much like a web browser, there are some special considerations when distributing a web application across smart feature phones. As always, it’s easy to misuse security constructs so it is best to include security specialists when securing critical sensitive data. If you need an experienced partner to audit and secure your KaiOS application, contact the author from the About page.