开发者社区> apachecn_飞龙> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

安卓应用安全指南 4.5.2 使用 SQLite 规则书

简介: 安卓应用安全指南 4.5.2 使用 SQLite 规则书 原书:Android Application Secure Design/Secure Coding Guidebook 译者:飞龙 协议:CC BY-NC-SA 4.0 使用 SQLite 时,遵循以下规则: 4.5.2.1 正确设置 DB 文件位置和访问权限(必需) 考虑到 DB 文件数据的保护,DB 文件位置和访问权限设置是需要一起考虑的非常重要的因素。
+关注继续查看

安卓应用安全指南 4.5.2 使用 SQLite 规则书

原书:Android Application Secure Design/Secure Coding Guidebook

译者:飞龙

协议:CC BY-NC-SA 4.0

使用 SQLite 时,遵循以下规则:

4.5.2.1 正确设置 DB 文件位置和访问权限(必需)

考虑到 DB 文件数据的保护,DB 文件位置和访问权限设置是需要一起考虑的非常重要的因素。 例如,即使正确设置了文件访问权,如果 DB 文件位于无法设置访问权的位置,则任何人可以访问 DB 文件,例如, SD 卡。 如果它位于应用目录中,如果访问权限设置不正确,它最终将允许意外访问。 以下是正确分配和访问权限设置的一些要点,以及实现它们的方法。 为了保护数据库文件(数据),对于位置和访问权限设置,需要执行以下两点。

1) 位置

位于可以由Context#getDatabasePath(String name)获取的文件路径,或者在某些情况下,可以由Context#getFilesDir11获取的目录。

2) 访问权限

设置为MODE_PRIVATE(只能由创建文件的应用访问)模式。

通过执行以下2点,即可
创建其他应用无法访问的 DB 文件。 以下是执行它们的一些方法。

  1. 使用SQLiteOpenHelper
  2. 使用Context#openOrCreateDatabase

创建 DB 文件时,可以使用SQLiteDatabase#openOrCreateDatabase。 但是,使用此方法时,可以在某些 Android 智能手机设备中创建可从其他应用读取的 DB 文件。 所以建议避免这种方法,并使用其他方法。 上述量种方法的每个特征如下 [11]

[11] 这两种方法都提供了(包)目录下的路径,只能由指定的应用读取和写入。

使用SQLiteOpenHelper

当使用SQLiteOpenHelper时,开发人员不需要担心很多事情。 创建一个从SQLiteOpenHelper派生的类,并为构造器的参数指定DB名称(用于文件名)[12],然后满足上述安全要求的 DB 文件会自动创建。

[12] (未在 Android 参考中记录)由于可以在SQLiteOpenHelper实现中,将完整文件路径指定为数据库名称,因此需要注意无意中指定不能控制访问权限的地方(路径)(例如 SD 卡)。

对于如何使用,请参阅“4.5.1.1 创建/操作数据库”的具体使用方法。

使用Context#openOrCreateDatabase

使用Context#openOrCreateDatabase方法创建数据库时,文件访问权应由选项指定,在这种情况下,请明确指定MODE_PRIVATE

对于文件安排,数据库名称(用于文件名)可以像SQLiteOpenHelper一样指定,文件将在满足上述安全要求的文件路径中自动创建。 但是,也可以指定完整路径,因此有必要注意指定 SD 卡时,即使指定MODE_PRIVATE,其他应用也可以访问。

MainActivity.java(显式设定 DB 访问权的示例)

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    //Construct database
    try {
        //Create DB by setting MODE_PRIVATE
        db = Context.openOrCreateDatabase("Sample.db", MODE_PRIVATE, null);
    } catch (SQLException e) {
        //In case failed to construct DB, log output
        Log.e(this.getClass().toString(), getString(R.string.DATABASE_OPEN_ERROR_MESSAGE));
        return;
    }
    //Omit other initial process
}

访问权限有三种可能的设置:MODE_PRIVATEMODE_WORLD_READABLEMODE_WORLD_WRITEABLE。 这些常量可以由或运算符一起指定。 但是,除API_PRIVATE之外的所有设置,都将在 API 级别 17 和更高版本中被弃用,并且会在 API 级别 24 和更高版本中导致安全异常。 即使对于 API 级别 15 及更早版本的应用,通常最好不要使用这些标志 [13]。

[13] MODE_WORLD_READABLEMODE_WORLD_WRITEABLE的更多信息,以及其使用的注意事项,请参见“4.6.3.2 访问目录的权限设置”。

  • MODE_PRIVATE只有创建者应用可以读写
  • MODE_WORLD_READABLE创建者应用可以读写,其他人只能读
  • MODE_WORLD_WRITEABLE创建者应用可以读写,其他人只能写

4.5.2.2 与其它应用共享 DB 数据时,将内容供应器用于访问控制(必需)

与其他应用共享 DB 数据的方法是,将 DB 文件创建为WORLD_READABLEWORLD_WRITEABLE,以便其他应用直接访问。 但是,此方法不能限制访问或操作数据库的应用,因此数据可以由非预期的一方(应用)读或写。 因此,可以认为数据的机密性或一致性方面可能会出现一些问题,或者可能成为恶意软件的攻击目标。

如上所述,在 Android 中与其他应用共享数据库数据时,强烈建议使用内容供应器。 内容供应器存在一些优点,不仅从安全的角度来实现对 DB 的访问控制,而且从设计角度来看, DB 纲要结构可以隐藏到内容中。

4.5.2.3 在 DB 操作期间处理变量参数时,必需使用占位符(必需)

在防止 SQL 注入的意义上,将任意输入值并入 SQL 语句时,应使用占位符。 下面有两个方法用占位符执行 SQL。

  1. 使用SQLiteDatabase#compileStatement(),获取SQLiteStatement,然后使用SQLiteStatement#bindString()bindLong()等,将参数放置到占位符之后。
  2. SQLiteDatabese类上调用execSQL()insert()update()delete()query()rawQuery()replace()时,使用具有占位符的 SQL 语句。

另外,通过使用SQLiteDatabase#compileStatement()执行SELECT命令时,存在“仅获取第一个元素作为SELECT命令的结果”的限制,所以用法是有限的。

在任何一种方法中,提供给占位符的数据内容最好根据应用要求事先检查。 以下是每种方法的进一步解释。

使用SQLiteDatabase#compileStatement()

数据以下列步骤提供给占位符:

  1. 使用SQLiteDatabase#compileStatement()获取包含占位符的 SQL 语句,如SQLiteStatement
  2. 使用bindLong()bindString()方法为创建的SQLiteStatement对象设置占位符。
  3. 通过ExecSQLiteStatement对象的execute()方法执行 SQL。

DataInsertTask.java(占位符的用例):

//Adding data task
public class DataInsertTask extends AsyncTask<String, Void, Void> {

    private MainActivity mActivity;
    private SQLiteDatabase mSampleDB;

    public DataInsertTask(SQLiteDatabase db, MainActivity activity) {
        mSampleDB = db;
        mActivity = activity;
    }

    @Override
    protected Void doInBackground(String... params) {
        String idno = params[0];
        String name = params[1];
        String info = params[2];
        //*** POINT 3 *** Validate the input value according the application requirements.
        if (!DataValidator.validateData(idno, name, info)) {
            return null;
        }
        // Adding data task
        //*** POINT 2 *** Use place holder
        String commandString = "INSERT INTO " + CommonData.TABLE_NAME + " (idno, name, info) VALUES (?, ?, ?)";
        SQLiteStatement sqlStmt = mSampleDB.compileStatement(commandString);
        sqlStmt.bindString(1, idno);
        sqlStmt.bindString(2, name);
        sqlStmt.bindString(3, info);
        try {
            sqlStmt.executeInsert();
        } catch (SQLException e) {
            Log.e(DataInsertTask.class.toString(), mActivity.getString(R.string.UPDATING_ERROR_MESSAGE));
        } finally {
            sqlStmt.close();
        }
        return null;
    }

    [...]
}

这是一种类型,它预先创建作为对象执行的 SQL 语句,并将参数分配给它。 执行的过程是固定的,所以没有发生 SQL 注入的可能。 另外,通过重用SQLiteStatement对象可以提高流程效率。

使用SQLiteDatabase提供的每个方法:

SQLiteDatabase提供了两种类型的数据库操作方法。 一种是使用 SQL 语句,另一种是不使用 SQL 语句。 使用 SQL 语句的方法是SQLiteDatabase#execSQL()/rawQuery(),它以以下步骤执行。

1) 准备包含占位符的 SQL 语句。

2) 创建要分配给占位符的数据。

3) 传递 SQL 语句和数据作为参数,并为每个过程执行一个方法。

另一方面,SQLiteDatabase#insert()/update()/delete()/query()/replace()是不使用 SQL 语句的方法。当使用它们时,数据应该按照以下步骤来准备。

1) 如果有数据要插入/更新到数据库,请注册到ContentValues

2) 传递ContentValues作为参数,并为每个过程执行一个方法(例如,SQLiteDatabase#insert()

SQLiteDatabase#insert()(每个过程的方法的用例):

private SQLiteDatabase mSampleDB;
private void addUserData(String idno, String name, String info) {
    //Validity check of the value(Type, range), escape process
    if (!validateInsertData(idno, name, info)) {
        //If failed to pass the validation, log output
        Log.e(this.getClass().toString(), getString(R.string.VALIDATION_ERROR_MESSAGE));
        return;
    }
    //Prepare data to insert
    ContentValues insertValues = new ContentValues();
    insertValues.put("idno", idno);
    insertValues.put("name", name);
    insertValues.put("info", info);
    //Execute Inser
    try {
        mSampleDb.insert("SampleTable", null, insertValues);
    } catch (SQLException e) {
        Log.e(this.getClass().toString(), getString(R.string.DB_INSERT_ERROR_MESSAGE));
        return;
    }
}

在这个例子中,SQL 命令不是直接写入,而是使用SQLiteDatabase提供的插入方法。 SQL 命令没有直接使用,所以在这种方法中也没有 SQL 注入的可能。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
安卓应用安全指南 5.2.3 权限和保护级别 高级话题
5.2.3 权限和保护级别 高级话题 原书:Android Application Secure Design/Secure Coding Guidebook 译者:飞龙 协议:CC BY-NC-SA 4.0 5.2.3.1 绕过自定义签名许可的 Android 操作系统特性及其对策 自定义签名权限是一种权限,实现使用相同开发人员密钥签名的应用之间的应用间通信。
944 0
安卓应用安全指南 4.4.2 创建/使用服务 规则书
安卓应用安全指南 4.4.2 创建/使用服务 规则书 原书:Android Application Secure Design/Secure Coding Guidebook 译者:飞龙 协议:CC BY-NC-SA 4.0 实现或使用服务时,遵循下列规则。
871 0
安卓应用安全指南 4.5.3 使用 SQLite 高级话题
安卓应用安全指南 4.5.3 使用 SQLite 高级话题 原书:Android Application Secure Design/Secure Coding Guidebook 译者:飞龙 协议:CC BY-NC-SA 4.0 4.5.3.1 在 SQL 语句的LIKE断言中使用通配符时,应该实现转义过程 当所使用的字符串包含LIKE断言的通配符(%,_),作为占位符的输入值时,除非处理正确,否则它将用作通配符,因此必须根据需要事先转义处理。
1305 0
安卓应用安全指南 4.6.2 处理文件 规则书
安卓应用安全指南 4.6.2 处理文件 规则书 原书:Android Application Secure Design/Secure Coding Guidebook 译者:飞龙 协议:CC BY-NC-SA 4.0 遵循以下规则: 4.6.2.1 文件原则上必须创建为私有(必需) 如“4.6 处理文件”和“4.6.1.3 使用公共读/写文件”所述,无论要存储的信息的内容如何,原则上都应该将文件设置为私有。
887 0
安卓应用安全指南 4.5.1 使用 SQLite 示例代码
安卓应用安全指南 4.5.1 使用 SQLite 示例代码 原书:Android Application Secure Design/Secure Coding Guidebook 译者:飞龙 协议:CC BY-NC-SA 4.0 4.5.1.1 创建/操作数据库 在 Android 应用中处理数据库时,可以通过使用SQLiteOpenHelper [10] 来实现数据库文件的适当安排和访问权限设置(拒绝其他应用访问的设置)。
918 0
安卓应用安全指南 4.3.2 创建/使用内容供应器 规则书
4.3.2 创建/使用内容供应器 规则书 原书:Android Application Secure Design/Secure Coding Guidebook 译者:飞龙 协议:CC BY-NC-SA 4.0 实现或使用内容供应器时,确保遵循以下规则。
720 0
安卓应用安全指南 4.4.1 创建/使用服务 示例代码
4.4.1 创建/使用服务 示例代码 原书:Android Application Secure Design/Secure Coding Guidebook 译者:飞龙 协议:CC BY-NC-SA 4.0 使用服务的风险和对策取决于服务的使用方式。
837 0
安卓应用安全指南 4.2.2 创建/使用广播接收器 规则书
4.2.2 创建/使用广播接收器 规则书 原书:Android Application Secure Design/Secure Coding Guidebook 译者:飞龙 协议:CC BY-NC-SA 4.0 遵循下列规则来发送或接受广播。
796 0
安卓应用安全指南 4.2.1 创建/使用广播接收器 示例代码
4.2.1 创建/使用广播接收器 示例代码 原书:Android Application Secure Design/Secure Coding Guidebook 译者:飞龙 协议:CC BY-NC-SA 4.0 接收广播需要创建广播接收器。
777 0
安卓应用安全指南 4.1.2 创建/使用活动 规则书
4.1.2 创建/使用活动 规则书 原书:Android Application Secure Design/Secure Coding Guidebook 译者:飞龙 协议:CC BY-NC-SA 4.0 创建或向活动发送意图时,请务必遵循以下规则。
1074 0
+关注
apachecn_飞龙
Github:@wizardforcel 简书:@ApacheCN_飞龙 微博:@龙雀 CSDN:@wizardforcel ApacheCN 官网:apachecn.org 机器学习交流群:629470233
文章
问答
文章排行榜
最热
最新
相关电子书
更多
荷鲁斯 移动端第三方库安全检查引擎介绍
立即下载
APP加固新方向阿里安卓加固技术介绍
立即下载
重保场景及API安全指南
立即下载