Security considerations

When building a Cascades application, it's important to protect your application and your users from attackers. If you don't take the necessary precautions, attackers can steal personal information from apps, access personal files on a device, or even control an app's behavior in unexpected ways. If your app uses or collects your customers' personal information, you must publish a privacy policy to inform your customers how their information is handled. For more information, see the BlackBerry Development Guidelines for Personally Identifiable Information.

In addition to these concepts, there are some general C/C++ security considerations that you should be familiar with. For more information about C/C++ security, see Security Considerations for Native Application Development.

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 applications.

You should never use C strings to manipulate strings in a Cascades application, though.

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

property string str : "String text"

And here's how to create one in C++:

QString str = "String text";

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
}

And here's how to do the same in C++:

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

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 application. Without validation, directory traversal bugs can occur that potentially provide access to files or other applications 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 "/"), as well as 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. Path names that contain ".." in their paths (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 /../, like in the following:

#include <QFileInfo>

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

Because canonicalPath() and canonicalFilePath() return a path name 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.

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

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

Script injection

If a Cascades application executes QScript or JavaScript that's controlled by an attacker, it can allow the attacker to access application data or control the behavior of the application. For this reason, it's important that applications 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 application and should never be altered dynamically when the application is running.

Also, 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 equivalent to downloading and running a malicious application. Unlike a desktop browser, 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. Disabling JavaScript is done by setting the appropriate flag in the  WebSettings object.

Here's how to disable JavaScript in QML:

WebView {
    settings: WebSettings {
        javaScriptEnabled: false
    }
}

And here's how to do the same in C++:

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

If a WebView 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 web pages 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. This setting can be disabled using:

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

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

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

cookiesEnabled: This setting allows loaded content to create and use cookies. This setting can be disabled using:

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

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 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 displayed in a control contains untrusted data, this can allow an attacker to change the format of the field, possibly including HTML links that are launched within the context of the application. 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;
}

And here's how to do the same in C++:

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

Makefiles

The makefile in a Cascades project contains a set of instructions that specify how to build an application. When you use the Momentics IDE to build and package your application, you don't typically 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 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: 2014-11-17



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

comments powered by Disqus