Security considerations for Cascades apps

This section provides some security considerations as you develop an app using Cascades classes and features.

Strings

Cascades supports two safe string classes: QString for Unicode strings and  QByteArray for ASCII strings. These classes avoid memory corruption by incorporating length and null-termination checks into all of their functions, so you should always use them for string manipulation in apps.

You should never use C strings to manipulate strings in a Cascades app.

Here's a safe way to create a string in QML:

property string str : "String text"

Here's a safe way to create a string in C++:

QString str = "String text";

Not applicable

Password fields

Any TextField that accepts password data from a user should use the password input mode from TextFieldInputMode.

By using the password input mode, characters are obscured while the user is typing and are not shared if the device is using screen-sharing functionality.

Screen showing the password field.

Here's how to create a password field in QML:

TextField {
    id: password
    inputMode: TextFieldInputMode.Password
}

Here's how to create a password field in C++:

textField->setInputMode(bb::cascades::TextFieldInputMode::Password);

Not applicable

For more information about text input modes, see Text input modes.

File paths

When handling file paths that come from an untrusted source, it's important to always validate the paths before you use them in an app. Without validation, directory traversal bugs can occur that potentially provide access to files or other apps that shouldn't be accessed.

If a file name is provided to your app from an untrusted source, your app should check to make sure that it doesn't contain characters that could change the file's location (such as ".." or "/") or any characters that could make the file path invalid. If a file path is provided, ensure that it's in the expected location on the file system.

Calling QString::startsWith() or other string comparison functions is usually not adequate for validating paths. Paths that contain ".." (for example, "/accounts/expected_path/../bad_path") or symbolic links can bypass these checks. To avoid these concerns, you should use the  canonicalPath() and canonicalFilePath() functions to resolve all symbolic links, extra slash (/) characters, and references to /./ and /../.

Not applicable

Here's an example that follows the best practices for file paths:

#include <QFileInfo>

QString path = "/accounts/1000/shared/downloads/../documents"; 
QFileInfo info(path);
path = info.canonicalFilePath();

Not applicable

Because canonicalPath() and canonicalFilePath() return a path instead of a reference to an open file, there's the possibility that while resolving symbolic links, the file system configuration might change between the call to canonicalPath() or canonicalFilePath() and the subsequent open() call used to open the returned path. To avoid race conditions in resolving symbolic links, a subsequent open() call should pass the O_NOSYMLINK option to avoid the insertion of symbolic links.

Not applicable

path = info.canonicalFilePath();
int fd = open( path.data(), O_NOSYMLINK | O_RDONLY );

In the example above, the path would resolve to /accounts/1000/shared/documents.

Not applicable

Script injection

If a Cascades app executes QScript or JavaScript code that's controlled by an attacker, it can allow the attacker to access app data or control the behavior of the app. For this reason, it's important that apps avoid executing untrusted data as a part of scripts.

When the QScriptEngine class is used to execute scripts, it's important that untrusted values are never appended to the string of the script that's being executed. All scripts that are executed by a QScriptEngine should be predefined when developing the app and should never be altered dynamically when the app is running.

You should never use importLoader, or XMLHttpRequest to load JavaScript code that you don't control into QML. Running untrusted JavaScript code in QML can be similar to downloading and running a malicious app. Unlike a browser on a computer, the JavaScript execution environment doesn't restrict certain activities, such as accessing the local file system. For more information about QML and security, see QML Security.

Script injection with WebView

The WebView class, if it's not configured correctly, can allow script injection when rendering HTML content. By default, JavaScript is enabled on a WebView, so you should always disable it if the WebView isn't intended to handle JavaScript content. You can disable JavaScript by setting the appropriate flag in the  WebSettings object.

Here's how to disable JavaScript in QML:

WebView {
    settings: WebSettings {
        javaScriptEnabled: false
    }
}

Here's how to disable JavaScript in C++:

WebView *webView = new WebView();
webView->settings()->setJavaScriptEnabled(false);

Not applicable

If a WebView object does need to support JavaScript, the source of its content should be limited to known and trusted sources (for example, files on the file system or specific webpages that are loaded over HTTPS). In addition, WebView features that aren't being used should be disabled to reduce the security impact of potential script injection issues. The WebView settings that have a potential risk of script injection vulnerabilities include the following:

imageDownloadingEnabled: This setting allows remote images in HTML to be loaded.

Not applicable

This setting can be disabled using:

webView->settings()->setImageDownloadingEnabled(false);

Not applicable

binaryFontDownloadingEnabled: This setting allows remote fonts in HTML to be loaded.

Not applicable

This setting can be disabled using:

webView->settings()->setbinaryFontDownloadingEnabled(false);

Not applicable

cookiesEnabled: This setting allows loaded content to create and use cookies.

Not applicable

This setting can be disabled using:

webView->settings()->setCookiesEnabled(false);

Not applicable

You must also be careful when using evaluateJavaScript() to execute JavaScript in a WebView. Similar to QScriptEngine, it's important to never execute untrusted scripts or data using this function. The evaluateJavaScript() function supports two modes: normal mode and isolated mode. Normal mode allows the script to interact with web content in the WebView, while isolated mode does not. It's recommended that isolated mode be used to execute a script, unless interaction with the content of a WebView is absolutely necessary.

For more information about using WebView, see Web content.

HTML text formatting

By default, most Cascades text controls, including Label TextField, and  TextArea, support HTML text styling. This formatting allows you to use certain HTML elements to apply styles to the text in your controls.

If the text that's displayed in a control contains untrusted data, an attacker could change the format of the field, possibly including HTML links that are opened within the context of the app. To protect against this risk, text controls that contain untrusted data should disable HTML formatting by setting the format of the field to plain text.

Here's how to disable HTML formatting in QML:

TextField {
    textFormat: TextFormat.Plain;
}

Here's how to disable HTML formatting in C++:

textfield->setTextFormat(bb::cascades::TextFormat::Plain);

Not applicable

Makefiles

The makefile in a Cascades project contains a set of instructions that specify how to build an app. When you use the Momentics IDE for BlackBerry to build and package your app, you don't usually need to modify any of these instructions. However, depending on the version of the BlackBerry 10 Native SDK that you're running, you might need to update some security settings.

For more information about makefile security, see Makefile security settings for Cascades apps.

Sensitive data in the work space 10.3.1

BlackBerry Balance technology allows users to use BlackBerry 10 devices for both work and personal use. Devices classify data as work or personal based on the source of the data. The classifications determine how devices store, protect, and manage data. If data comes from a work account, it's stored in the work space on the device. If data comes from a personal account, it's stored in the personal space. For more information, see Security for enterprise.

Advanced data at rest protection (ADARP) helps to secure sensitive data by restricting access to files in the device's work space when the work space is in a data lock state. When the work space is data locked, only apps that are data lock aware are allowed to continue to run in the work space. These apps are restricted to access only certain parts of the file system in the work space.

To create an app that is data lock aware, you can use the AdarpDomain and DataLockState classes. For more information, see Creating apps that are data lock aware.

To use the AdarpDomain class to manage the data lock state in your app, you might need to add permissions to your bar-descriptor.xml file. The following permissions can be used to request a data lock, extend the data lock timeout period, access the operational data and startup data domains, and run when the app is in a data lock state:

For more information about permissions, see App permissions.

Last modified: 2015-07-24



Got questions about leaving a comment? Get answers from our Disqus FAQ.

comments powered by Disqus