Google Security Blog
Correctness of code in the Android platform is a top priority for the security, stability, and quality of each Android release. Memory safety bugs in C and C++ continue to be the most-difficult-to-address source of incorrectness. We invest a great deal of effort and resources into detecting, fixing, and mitigating this class of bugs, and these efforts are effective in preventing a large number of bugs from making it into Android releases. Yet in spite of these efforts, memory safety bugs continue to be a top contributor of stability issues, and consistently represent ~70% of Android’s high severity security vulnerabilities.
In addition to ongoing and upcoming efforts to improve detection of memory bugs, we are ramping up efforts to prevent them in the first place. Memory-safe languages are the most cost-effective means for preventing memory bugs. In addition to memory-safe languages like Kotlin and Java, we’re excited to announce that the Android Open Source Project (AOSP) now supports the Rust programming language for developing the OS itself.Systems programming
Managed languages like Java and Kotlin are the best option for Android app development. These languages are designed for ease of use, portability, and safety. The Android Runtime (ART) manages memory on behalf of the developer. The Android OS uses Java extensively, effectively protecting large portions of the Android platform from memory bugs. Unfortunately, for the lower layers of the OS, Java and Kotlin are not an option.
Lower levels of the OS require systems programming languages like C, C++, and Rust. These languages are designed with control and predictability as goals. They provide access to low level system resources and hardware. They are light on resources and have more predictable performance characteristics.
For C and C++, the developer is responsible for managing memory lifetime. Unfortunately, it's easy to make mistakes when doing this, especially in complex and multithreaded codebases.
The limits of sandboxing
Rust provides memory safety guarantees by using a combination of compile-time checks to enforce object lifetime/ownership and runtime checks to ensure that memory accesses are valid. This safety is achieved while providing equivalent performance to C and C++.
C and C++ languages don’t provide these same safety guarantees and require robust isolation. All Android processes are sandboxed and we follow the Rule of 2 to decide if functionality necessitates additional isolation and deprivileging. The Rule of 2 is simple: given three options, developers may only select two of the following three options.
For Android, this means that if code is written in C/C++ and parses untrustworthy input, it should be contained within a tightly constrained and unprivileged sandbox. While adherence to the Rule of 2 has been effective in reducing the severity and reachability of security vulnerabilities, it does come with limitations. Sandboxing is expensive: the new processes it requires consume additional overhead and introduce latency due to IPC and additional memory usage. Sandboxing doesn’t eliminate vulnerabilities from the code and its efficacy is reduced by high bug density, allowing attackers to chain multiple vulnerabilities together.
Memory-safe languages like Rust help us overcome these limitations in two ways:
- Lowers the density of bugs within our code, which increases the effectiveness of our current sandboxing.
- Reduces our sandboxing needs, allowing introduction of new features that are both safer and lighter on resources.
Of course, introducing a new programming language does nothing to address bugs in our existing C/C++ code. Even if we redirected the efforts of every software engineer on the Android team, rewriting tens of millions of lines of code is simply not feasible.
The above analysis of the age of memory safety bugs in Android (measured from when they were first introduced) demonstrates why our memory-safe language efforts are best focused on new development and not on rewriting mature C/C++ code. Most of our memory bugs occur in new or recently modified code, with about 50% being less than a year old.
The comparative rarity of older memory bugs may come as a surprise to some, but we’ve found that old code is not where we most urgently need improvement. Software bugs are found and fixed over time, so we would expect the number of bugs in code that is being maintained but not actively developed to go down over time. Just as reducing the number and density of bugs improves the effectiveness of sandboxing, it also improves the effectiveness of bug detection.Limitations of detection
Bug detection via robust testing, sanitization, and fuzzing is crucial for improving the quality and correctness of all software, including software written in Rust. A key limitation for the most effective memory safety detection techniques is that the erroneous state must actually be triggered in instrumented code in order to be detected. Even in code bases with excellent test/fuzz coverage, this results in a lot of bugs going undetected.
Another limitation is that bug detection is scaling faster than bug fixing. In some projects, bugs that are being detected are not always getting fixed. Bug fixing is a long and costly process.
Each of these steps is costly, and missing any one of them can result in the bug going unpatched for some or all users. For complex C/C++ code bases, often there are only a handful of people capable of developing and reviewing the fix, and even with a high amount of effort spent on fixing bugs, sometimes the fixes are incorrect.
Bug detection is most effective when bugs are relatively rare and dangerous bugs can be given the urgency and priority that they merit. Our ability to reap the benefits of improvements in bug detection require that we prioritize preventing the introduction of new bugs.Prioritizing prevention
Rust modernizes a range of other language aspects, which results in improved correctness of code:
- Memory safety - enforces memory safety through a combination of compiler and run-time checks.
- Data concurrency - prevents data races. The ease with which this allows users to write efficient, thread-safe code has given rise to Rust’s Fearless Concurrency slogan.
- More expressive type system - helps prevent logical programming bugs (e.g. newtype wrappers, enum variants with contents).
- References and variables are immutable by default - assist the developer in following the security principle of least privilege, marking a reference or variable mutable only when they actually intend it to be so. While C++ has const, it tends to be used infrequently and inconsistently. In comparison, the Rust compiler assists in avoiding stray mutability annotations by offering warnings for mutable values which are never mutated.
- Better error handling in standard libraries - wrap potentially failing calls in Result, which causes the compiler to require that users check for failures even for functions which do not return a needed value. This protects against bugs like the Rage Against the Cage vulnerability which resulted from an unhandled error. By making it easy to propagate errors via the ? operator and optimizing Result for low overhead, Rust encourages users to write their fallible functions in the same style and receive the same protection.
- Initialization - requires that all variables be initialized before use. Uninitialized memory vulnerabilities have historically been the root cause of 3-5% of security vulnerabilities on Android. In Android 11, we started auto initializing memory in C/C++ to reduce this problem. However, initializing to zero is not always safe, particularly for things like return values, where this could become a new source of faulty error handling. Rust requires every variable be initialized to a legal member of its type before use, avoiding the issue of unintentionally initializing to an unsafe value. Similar to Clang for C/C++, the Rust compiler is aware of the initialization requirement, and avoids any potential performance overhead of double initialization.
- Safer integer handling - Overflow sanitization is on for Rust debug builds by default, encouraging programmers to specify a wrapping_add if they truly intend a calculation to overflow or saturating_add if they don’t. We intend to enable overflow sanitization for all builds in Android. Further, all integer type conversions are explicit casts: developers can not accidentally cast during a function call when assigning to a variable or when attempting to do arithmetic with other types.
Adding a new language to the Android platform is a large undertaking. There are toolchains and dependencies that need to be maintained, test infrastructure and tooling that must be updated, and developers that need to be trained. For the past 18 months we have been adding Rust support to the Android Open Source Project, and we have a few early adopter projects that we will be sharing in the coming months. Scaling this to more of the OS is a multi-year project. Stay tuned, we will be posting more updates on this blog.
Java is a registered trademark of Oracle and/or its affiliates.
When the Pixel 3 launched in 2018, it had a new tamper-resistant hardware enclave called Titan M. In addition to being a root-of-trust for Pixel software and firmware, it also enabled tamper-resistant key storage for Android Apps using StrongBox. StrongBox is an implementation of the Keymaster HAL that resides in a hardware security module. It is an important security enhancement for Android devices and paved the way for us to consider features that were previously not possible.
StrongBox and tamper-resistant hardware are becoming important requirements for emerging user features, including:
- Digital keys (car, home, office)
- Mobile Driver’s License (mDL), National ID, ePassports
- eMoney solutions (for example, Wallet)
All these features need to run on tamper-resistant hardware to protect the integrity of the application executables and a user’s data, keys, wallet, and more. Most modern phones now include discrete tamper-resistant hardware called a Secure Element (SE). We believe this SE offers the best path for introducing these new consumer use cases in Android.
In order to accelerate adoption of these new Android use cases, we are announcing the formation of the Android Ready SE Alliance. SE vendors are joining hands with Google to create a set of open-source, validated, and ready-to-use SE Applets. Today, we are launching the General Availability (GA) version of StrongBox for SE. This applet is qualified and ready for use by our OEM partners. It is currently available from Giesecke+Devrient, Kigen, NXP, STMicroelectronics, and Thales.
It is important to note that these features are not just for phones and tablets. StrongBox is also applicable to WearOS, Android Auto Embedded, and Android TV.
Using Android Ready SE in a device requires the OEM to:
- Pick the appropriate, validated hardware part from their SE vendor
- Enable SE to be initialized from the bootloader and provision the root-of-trust (RoT) parameters through the SPI interface or cryptographic binding
- Work with Google to provision Attestation Keys/Certificates in the SE factory
- Use the GA version of the StrongBox for the SE applet, adapted to your SE
- Integrate HAL code
- Enable an SE upgrade mechanism
- Run CTS/VTS tests for StrongBox to verify that the integration is done correctly
We are working with our ecosystem to prioritize and deliver the following Applets in conjunction with corresponding Android feature releases:
- Mobile driver’s license and Identity Credentials
- Digital car keys
We already have several Android OEMs adopting Android Ready SE for their devices. We look forward to working with our OEM partners to bring these next generation features for our users.
Please visit our Android Security and Privacy developer site for more info.
Passwords help protect our online information, which is why it’s never been more important to keep them safe. But when we’re juggling dozens (if not hundreds!) of passwords across various websites—from shopping, to entertainment to personal finance—it feels like there’s always a new account to set up or manage. While it’s definitely a best practice to have a strong, unique password for each account, it can be really difficult to remember them all—that’s why we have a password manager in Chrome to back you up.
As you browse the web, on your phone, computer or tablet, Chrome can create, store and fill in your passwords with a single click. We'll warn you if your passwords have been compromised after logging in to sites, and you can always check for yourself in Chrome Settings. As we kick off the New Year, we’re excited to announce new updates that will give you even greater control over your passwords:
Easily fix weak passwords
We’ve all had moments where we’ve rushed to set up a new login, choosing a simple “name-of-your-pet” password to get set up quickly. However, weak passwords expose you to security risks and should be avoided. In Chrome 88, you can now complete a simple check to identify any weak passwords and take action easily.
To check your passwords, click on the key icon under your profile image, or type chrome://settings/passwords in your address bar.Edit your passwords in one place
Chrome can already prompt you to update your saved passwords when you log in to websites. However, you may want to update multiple usernames and passwords easily, in one convenient place. That’s why starting in Chrome 88, you can manage all of your passwords even faster and easier in Chrome Settings on desktop and iOS (Chrome’s Android app will be getting this feature soon, too).
Building on the 2020 improvements
These new updates come on top of many improvements from last year which have all contributed to your online safety and make browsing the web even easier:
- Password breaches remain a critical concern online. So we’re proud to share that Chrome’s Safety Check is used 14 million times every week! As a result of Safety Check and other improvements launched in 2020, we’ve seen a 37% reduction in compromised credentials stored in Chrome.
- Starting last September, iOS users were able to autofilll their saved passwords in other apps and browsers. Today, Chrome is streamlining 3 million sign-ins across iOS apps every week! We also made password filling more secure for Chrome on iOS users by adding biometric authentication (coming soon to Chrome on Android).
- We’re always looking for ways to improve the user experience, so we made the password manager easier to use on Android with features like Touch-to-fill.
The new features with Chrome 88 will be rolled out over the coming weeks, so take advantage of the new updates to keep your passwords secure. Stay tuned for more great password features throughout 2021.
We first announced the GCP VRP Prize in 2019 to encourage security researchers to focus on the security of Google Cloud Platform (GCP), in turn helping us make GCP more secure for our users, customers, and the internet at large. In the first iteration of the prize, we awarded $100,000 to the winning write-up about a security vulnerability in GCP. We also announced that we would reward the top 6 submissions in 2020 and increased the total prize money to $313,337.
2020 turned out to be an amazing year for the Google Vulnerability Reward Program. We received many high-quality vulnerability reports from our talented and prolific vulnerability researchers.
Vulnerability reports received year-over-year
This trend was reflected in the submissions we received for the GCP VRP Prize. After careful evaluation of the many innovative and high-impact vulnerability write-ups we received this year, we are excited to announce the winners of the 2020 GCP VRP Prize:
- First Prize, $133,337: Ezequiel Pereira for the report and write-up RCE in Google Cloud Deployment Manager. The bug discovered by Ezequiel allowed him to make requests to internal Google services, authenticated as a privileged service account. Here's a video that gives more details about the bug and the discovery process.
- Second Prize, $73,331: David Nechuta for the report and write-up 31k$ SSRF in Google Cloud Monitoring led to metadata exposure. David found a Server-side Request Forgery (SSRF) bug in Google Cloud Monitoring's uptime check feature. The bug could have been used to leak the authentication token of the service account used for these checks.
- Third Prize, $73,331: Dylan Ayrey and Allison Donovan for the report and write-up Fixing a Google Vulnerability. They pointed out issues in the default permissions associated with some of the service accounts used by GCP services.
- Fourth Prize, $31,337: Bastien Chatelard for the report and write-up Escaping GKE gVisor sandboxing using metadata. Bastien discovered a bug in the GKE gVisor sandbox's network policy implementation due to which the Google Compute Engine metadata API was accessible.
- Fifth Prize, $1,001: Brad Geesaman for the report and write-up CVE-2020-15157 "ContainerDrip" Write-up. The bug could allow an attacker to trick containerd into leaking instance metadata by supplying a malicious container image manifest.
- Sixth Prize, $1,000: Chris Moberly for the report and write-up Privilege Escalation in Google Cloud Platform's OS Login. The report demonstrates how an attacker can use DHCP poisoning to escalate their privileges on a Google Compute Engine VM.
- Find a vulnerability in a GCP product (check out Google Cloud Free Program to get started)
- Report it to the VRP (you might get rewarded for it on top of the GCP VRP Prize!)
- Create a public write-up
- Submit it here