Designing for Security
為安全而設計
Android was designed so that most developers will be able to build applications using the default settings and not be confronted with difficult decisions about security.
Android also has a number of security features built into the operating system that significantly reduce the frequency and impact of application security issues.
Android被設計成大多數開發者有能力建立應用使用默認設置並且不用面對關於安全的困難的決定。
Android也有大量的安全特征構建到操作系統中,極大的減少應用安全問題的頻率和影響。
Some of the security features that help developers build secure applications include:
一些安全特征幫助開發者建立安全的應用,包括:
1.The Android Application Sandbox that isolates data and code execution on a per-application basis.
2.Android application framework with robust implementations of common security functionality such as cryptography, permissions, and secure IPC.
3.Technologies like ASLR, NX, ProPolice, safe_iop, OpenBSD dlmalloc, OpenBSD calloc, and Linux mmap_min_addr to mitigate risks associated with common memory management errors
4.An encrypted filesystem that can be enabled to protect data on lost or stolen devices.
1.Android應用沙箱隔離數據和代碼基於每一個應用執行。
2.Android應用框架擁有強壯的常見的安全功能,比如加密,權限和安全的IPC
3.ASLR, NX, ProPolice, safe_iop, OpenBSD dlmalloc, OpenBSD calloc和Linux mmap_min_addr技術用來減輕與常見的內存管理錯誤相關的風險
4.加密文件系統能夠在丟失的或者被偷的設備上面保護數據
Nevertheless, it is important for developers to be familiar with Android security best practices to make sure they take advantage of these capabilities and to reduce the likelihood of inadvertently introducing security issues that can affect their applications.
對開發者來說熟悉Android安全最好的練習是保證他們利用這些能力來減少可能無意中引入的能影響他們的應用的安全問題
This document is organized around common APIs and development techniques that can have security implications for your application and its users.
As these best practices are constantly evolving, we recommend you check back occasionally throughout your application development process.
這個文檔是圍繞牽連你的應用和它的用戶的安全的常見API和開發技術。
由於這些最佳練習是不斷地發展,我們推薦你在你的應用開發進程中,偶爾的回頭檢查。
Using Dalvik Code
使用Dalvik代碼
Writing secure code that runs in virtual machines is a well-studied topic and many of the issues are not specific to Android.
Rather than attempting to rehash these topics, we’d recommend that you familiarize yourself with the existing literature.
Two of the more popular resources are:
編寫運行在虛擬機的安全代碼是一個精心研究的話題,很多問題並不特指在Android上。
相比嘗試重新講解這些話題,我們推薦你熟悉已經存在的文獻。
1.http://www.securingjava.com/toc.html
2.https://www.owasp.org/index.php/Java_Security_Resources
This document is focused on the areas which are Android specific and/or different from other environments.
For developers experienced with VM programming in other environments, there are two broad issues that may be different about writing apps for Android:
這個文檔集中於Android專有的並/或者與其他環境不同地方。
對於有在其他環境上的VM編程經驗開發者,這有這有兩個普遍的問題也許對於編寫Android應用來說有些不同
Some virtual machines, such as the JVM or .net runtime, act as a security boundary, isolating code from the underlying operating system capabilities.
On Android, the Dalvik VM is not a security boundary -- the application sandbox is implemented at the OS level, so Dalvik can interoperate with native code in the same application without any security constraints.
一些虛擬機,比如JVM或者.net,擔任一個安全的邊界作用,代碼與底層操作系統能力相隔離。
在Android上,Dalvik VM不是一個安全邊界-- 應用沙箱是在系統級別實現的,所以Dalvik可以在同一個應用與native代碼相互操作沒有任何約束。
Given the limited storage on mobile devices, it’s common for developers to want to build modular applications and use dynamic class loading.
When doing this consider both the source where you retrieve your application logic and where you store it locally.
Do not use dynamic class loading from sources that are not verified, such as unsecured network sources or external storage, since that code can be modified to include malicious behavior.
已知的手機上的存儲限制,對來發者來說,想要建立模塊化應用和使用動態類加載是很常見的。
當這麼做的時候,要考慮兩個資源一個是 你在哪裡恢復你的應用邏輯 另一個是你在哪裡存儲它們
不要從未驗證的資源使用動態類加載器,比如不安全的網絡資源或者外部存儲,因為那些代碼可能被修改為包含惡意的行為。
Using Native Code
使用Native代碼
In general, we encourage developers to use the Android SDK for most application development, rather than using native code.
Applications built with native code are more complex, less portable, and more like to include common memory corruption errors such as buffer overflows.
一般來說,對於大多數應用開發,我們鼓勵開發者使用Android SDK而不是使用native代碼
編譯native代碼的應用更為復雜,移植性差,更容易包含常見的內存崩潰錯誤,比如緩沖區溢出。
Android is built using the Linux kernel and being familiar with Linux development security best practices is especially useful if you are going to use native code.
This document is too short to discuss all of those best practices, but one of the most popular resources is “Secure Programming for Linux and Unix HOWTO”, available at http://www.dwheeler.com/secure-programs.
Android使用Linux內核編譯並且與Linux開發相似,如果你打算使用native代碼,安全最佳實踐尤其有用。
這篇文檔討論這些所有的最佳實踐實在太短了,但是最受歡迎的資源之一是“Secure Programming for Linux and Unix HOWTO”,在這裡可以找到http://www.dwheeler.com/secure-programs
An important difference between Android and most Linux environments is the Application Sandbox.
On Android, all applications run in the Application Sandbox, including those written with native code.
At the most basic level, a good way to think about it for developers familiar with Linux is to know that every application is given a unique UID with very limited permissions.
This is discussed in more detail in the Android Security Overview and you should be familiar with application permissions even if you are using native code.
Android和大多數Linux環境之前的一個重要區別是應用沙箱。
在Android中,所有的應用運行在應用沙箱中,包括那些用native代碼編寫的應用。
在最基本的級別中,對於開發者來說,一種考慮它的好的辦法與Linux相似,知道每一個應用被分配一個具有非常有限權限的唯一UID。
這裡討論的比Android Security Overview中更細節化,你應該熟悉應用許可,即使你使用的是native代碼
Storing Data
數據存儲
Using internal files
使用內部文件
By default, files created on internal storage are only accessible to the application that created the file.
This protection is implemented by Android and is sufficient for most applications.
默認的,建立在內部存儲中的文件只對建立此文件的應用可訪問。
這種保護是由Android執行的,對大多數應用來說足矣。
Use of world writable or world readable files for IPC is discouraged because it does not provide the ability to limit data access to particular applications, nor does it provide any control on data format.
As an alternative, you might consider using a ContentProvider which provides read and write permissions, and can make dynamic permission grants on a case-by-case basis.
IPC(進程間通信)使用world writable或者world readable文件是令人沮喪的,因為它不提供對特定應用限制數據訪問的能力,也不提供任何數據格式化控制。
作為替代方案,你應該考慮使用一個ContentProvider提供讀寫許可,並且能建立基於具體問題具體分析的動態許可保證
To provide additional protection for sensitive data, some applications choose to encrypt local files using a key that is not accessible to the application. (For example, a key can be placed in a KeyStore and protected with a user password that is not stored on the device).
While this does not protect data from a root compromise that can monitor the user inputting the password, it can provide protection for a lost device without file system encryption.
為了提供對附加的敏感數據保護,一些應用選擇使用一個應用不可訪問的key加密本地文件(比如:一個key可能存放在KeyStore並且受一個存儲在設備之外的密碼保護)
這並不會保護數據以防可以監聽用戶輸入密碼的根權限入侵,它可以為丟失的沒有文件系統加密的設備提供保護。
Using external storage
使用外部存儲
Files created on external storage, such as SD Cards, are globally readable and writable.
Since external storage can be removed by the user and also modified by any application, applications should not store sensitive information using external storage.
建立在外部存儲的文件,比如sd卡,是全局可讀寫的。
因為外部存儲可以被用戶移除並且可被任何應用修改,應用不應該使用外部存儲存儲敏感信息。
As with data from any untrusted source, applications should perform input validation when handling data from external storage (see Input Validation section).
We strongly recommend that applications not store executables or class files on external storage prior to dynamic loading.
If an application does retrieve executable files from external storage they should be signed and cryptographically verified prior to dynamic loading.
當處理從外部存儲來的數據時應用應該執行輸入驗證(參看輸入驗證章節)
我們強烈建議應用在動態加載之前不把可執行或者是class文件存儲到外部存儲中。
如果一個應用從外部存儲檢索可執行文件,在動態加載之前,他們應該被簽名和加密驗證。
Using content providers
使用content providers
ContentProviders provide a structured storage mechanism that can be limited to your own application, or exported to allow access by other applications.
By default, a ContentProvider is exported for use by other applications.
If you do not intend to provide other applications with access to your ContentProvider, mark them as android:exported=false in the application manifest.
ContentProviders提供一個結構存儲機制,可以限制你自己的應用,或者導出給其他應用程序允許訪問
默認的,一個ContentProvider由其他應用為使用而導出。(for using?)
如果你不打算為其他應用提供訪問你的ContentProvider功能,在manifest中標記他們為android:exported=false即可。
When creating a ContentProvider that will be exported for use by other applications, you can specify a single permission for reading and writing, or distinct permissions for reading and writing within the manifest.
We recommend that you limit your permissions to those required to accomplish the task at hand.
Keep in mind that it’s usually easier to add permissions later to expose new functionality than it is to take them away and break existing users.
當建立一個由其他應用為使用而導出的ContentProvider,你可以為讀寫指定一個單一的許可,或者在manifest中為讀寫指定確切的許可
我們強烈建議你把你的許可限制在那些必要的事情上來完成臨近的任務。
記住,通常顯示新功能稍後加入許可要比把許可拿開並且打斷已經存在的用戶要容易。
If you are using a ContentProvider for sharing data between applications built by the same developer, it is preferable to use signature level permissions.
Signature permissions do not require user confirmation, so they provide a better user experience and more controlled access to the ContentProvider.
如果你正在使用ContentProvider在相同開發者的應用間來分享數據,使用簽名級別的許可是更可取的。
簽名許可不需要用戶確認,所以這提供一個更好的用戶體驗並且更能控制ContentProvider訪問。
ContentProviders can also provide more granular access by declaring the grantUriPermissions element and using the FLAG_GRANT_READ_URI_PERMISSION and FLAG_GRANT_WRITE_URI_PERMISSION flags in the Intent object that activates the component.
The scope of these permissions can be further limited by the grant-uri-permission element.
ContentProviders也可以通過聲明grantUriPermissions元素並且在觸發組件的Intent對象中使用FLAG_GRANT_READ_URI_PERMISSION和FLAG_GRANT_WRITE_URI_PERMISSION標志提供更顆粒狀的訪問。
這些許可的作用域可以通過grant-uri-permission元素進一步的限制
When accessing a ContentProvider, use parameterized query methods such as query(), update(), and delete() to avoid potential SQL Injection from untrusted data.
Note that using parameterized methods is not sufficient if the selection is built by concatenating user data prior to submitting it to the method.
當訪問一個ContentProvider時,使用參數化的查詢方法,比如query(), update(),和delete()來避免來自不被新人的數據潛在的SQL注入。
注意,如果提交到方法之前的選擇是通過連接用戶數據建立的,使用參數化的方法是不夠的。
Do not have a false sense of security about the write permission.
Consider that the write permission allows SQL statements which make it possible for some data to be confirmed using creative WHERE clauses and parsing the results.
For example, an attacker might probe for presence of a specific phone number in a call-log by modifying a row only if that phone number already exists.
If the content provider data has predictable structure, the write permission may be equivalent to providing both reading and writing.
不要對“寫”的許可安全有一個錯誤的觀念
考慮“寫”的許可允許sql語句使得一些數據被確認使用創造性的WHERE從句並且分析結果變為可能。
例如:一個入侵者可能在通話記錄中通過修改一條記錄來偵察一個存在的特定的電話號碼,只要那個電話號碼已經存在。
如果content provider數據有可預見的結構,“寫”許可也許與提供了“讀寫”等效了。