CHAPTER 13
Writing Secure Windows Phone Applications

Having covered the security assessment of Windows Phone applications in some detail, this chapter discusses important coding practices for writing secure apps in the first place. Where appropriate, we’ve given code examples for use in apps that generally need to be “secure.”

General Security Design Considerations

You should consider several points when designing and analyzing the security of an app. These can be summarized as follows:

  • Entry point analysis—What are the various ways, such as Interprocess Communications (IPC) endpoints (file handlers, protocol handlers), web communications, and downloading and parsing files, an attacker could push data into your app?
  • Data validation—Does your app validate data before using it in potentially dangerous ways, or does it simply trust it? Try to make as few assumptions about data integrity and safety as possible.
  • Data storage and handling—Does your app handle sensitive data? Does it store it? Sensitive data should not be stored in the clear, but should instead be encrypted using a sensible crypto algorithm choice, secure key generation, and cryptographic APIs.

Considering these general questions should make analyzing your app’s security and identifying areas that may require attention or further analysis easier to do.

Storing and Encrypting Data Securely

When applications deal with sensitive data and need to store it for later use (or transmit it across a network), storing this data securely, using tried-and-tested crypto algorithms that are widely accepted as being secure, is important. The following subsections cover secure file storage and secure database storage, and we give examples of how we recommend applying encryption to data being stored in databases and flat files.

Safe Encryption Ciphers and Modes

For storing data (or transmitting it), we recommend the use of AES-128 (Advanced Encryption Standard) at minimum (though preferably AES-256), not in ECB mode. CBC mode is a sensible choice.

We also advise against using ciphers such as Data Encryption Standard (DES); sticking to the (at the time of writing) industry-standard AES algorithm is sensible and recommended, and being required to use anything else is rare.

Hard-coded IVs should not be used with CBC; IVs are not supposed to be secret, but they should be a unique, per-app instance.

Key Generation and Management

Cryptographic keys must be generated securely. This means that non- cryptographically secure APIs such as System.Random should not be used. For generating securely random keys, see the later section in this chapter, “Secure Random Number Generation.”

To generate keys based on a user-supplied secret, that is, a password, a recommendable choice is Password-Based Key Derivation Function 2 (PBKDF2). Basically, PBKDF2 generates a key from a password, which may be considered secure as long as the password is of sufficient length and the iteration count used is sufficiently high (10,000, for example).

.NET provides an API for PBKDF2; namely Rfc2898DeriveBytes, for which you can find the full documentation at the following URL: http://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes%28v=vs.110%29.aspx.

After keys have been generated, they should not be stored to the app’s local storage, because the compromise of a device (with or without full disk encryption) could result in disclosure of the crypto key. If the crypto keys are generated randomly and stored to the device, they should be “wrapped” (that is, encrypted) with a PBKDF2-generated key derived from a user-known secret. If keys are generated directly from PBKDF2, no need exists to store them.

Encrypting Files

As we said in “Safe Encryption Ciphers and Modes”, above, when applications need to store sensitive data to the device as files, such data should be stored in encrypted form; we recommend using AES-256 in CBC mode.

The following code shows sample code for AES-256 CBC encrypt() and decrypt() functions, using the AesManaged API:

public byte[] encrypt(byte[] dataIn, byte[] cryptoKey, byte[] iv) 
{ 
    AesManaged aes = null; 
    MemoryStream memoryStream = null; 
    CryptoStream cryptoStream = null; 
 
try 
    { 
 
        aes = new AesManaged(); 
        aes.Key = cryptoKey; 
        aes.IV = iv; 
       aes.KeySize = 256; 
       aes.Mode = CipherMode.CBC; 
 
        memoryStream = new MemoryStream(); 
        cryptoStream = new CryptoStream(memoryStream, 
aes.CreateEncryptor(), CryptoStreamMode.Write); 
 
        byte[] data = Encoding.UTF8.GetBytes(dataToEncrypt); 
        cryptoStream.Write(dataIn, 0, dataIn.Length); 
        cryptoStream.FlushFinalBlock(); 
 
        // return encrypted data 
        return memoryStream.ToArray(); 
    } 
    finally 
    { 
        if (cryptoStream != null) 
            cryptoStream.Close(); 
 
        if (memoryStream != null) 
            memoryStream.Close(); 
 
        if (aes != null) 
            aes.Clear(); 
    } 
} 
 
public string decrypt(byte[] dataIn, byte[] cryptoKey, byte[] iv) 
{ 
    AesManaged aes = null; 
    MemoryStream memoryStream = null; 
 
    try 
    { 
 
        aes = new AesManaged(); 
        aes.Key = cryptoKey; 
        aes.IV = iv; 
       aes.KeySize = 256; 
        aes.Mode = CipherMode.CBC; 
 
        memoryStream = new MemoryStream(); 
        CryptoStream cryptoStream = new CryptoStream(memoryStream, 
aes.CreateDecryptor(), CryptoStreamMode.Write); 
 
        // decrypt Data 
        cryptoStream.Write(dataIn, 0, dataIn.Length); 
        cryptoStream.FlushFinalBlock(); 
 
        byte[] decryptBytes = memoryStream.ToArray(); 
 
        //Dispose 
        if (cryptoStream != null) 
            cryptoStream.Dispose(); 
 
        //Retval 
        return decryptBytes; 
    } 
    finally 
    { 
        if (memoryStream != null) 
            memoryStream.Dispose(); 
 
        if (aes != null) 
            aes.Clear(); 
    } 
}

Each of the functions accept input data, a key, and an IV, all as byte arrays, and return the data resulting from the encryption or decryption as a byte array as well.

After encryption by the encrypt() method, the resulting data can be stored using the standard file I/O APIs: StorageFolder or IsolatedStorage, and StreamReader.

Applications may also use the standard Data Protection API (DPAPI) for data that will be stored locally. (If the data is transmitted to a remote host, the host would not be able to decrypt it, because only the local device knows the key.) However, there are certain cases against using it for apps requiring high levels of security, which were outlined in the Chapter 12 section, “Data Protection API Misuse on Windows Phone.” You can find the documentation for DPAPI at the following MSDN article: http://msdn.microsoft.com/en-us/library/windows/apps/hh487164%28v=vs.105%29.aspx.

If you use DPAPI, we highly recommend using the optionalEntropy parameter with a secret that only the app user knows.

Encrypting Databases

Two database types find common usage in Windows Phone applications: Windows Phone native databases and SQLite-based databases. We cover how to apply crypto to each of these main types.

Windows Phone Local Databases

Creating encrypted local databases in a Windows Phone applications is fortunately very easy; you may simply use the Password property in your database’s connection string:

string connectionString = "Data 
Source='isostore:/ToDo.sdf';Password='myDatabasePassword'";

Developers should not, of course, hard-code the password; secure credential and key management principles should be adhered to. Applying database crypto in this way results in the database’s being encrypted via AES-128 in CBC mode. The key used is the SHA-256 hash of the password specified in the connection string’s Password property.

A detailed discussion of Windows Phone local databases is beyond the scope of this section, but a short introduction appears in Chapter 12.

You can also consult MSDN’s introduction to local databases for a general example on implementing local database storage: http://msdn.microsoft.com/en-us/library/windows/apps/hh202860%28v=vs.105%29.aspx.

The documentation at the previous URL also provides information on applying crypto to a database, as we’ve also done in this short section (http://msdn .microsoft.com/en-us/library/windows/apps/hh202860%28v=vs.105%29.aspx#BKMK_DatabaseSecurity).

SQLite-Based Databases

The two main options for applying crypto to databases that are SQLite in nature are SQLite’s SQLite Encryption Extension (SEE) and SQLCipher.

Each of these options is almost as simple to use as the standard Windows Phone SQLite options, although SEE requires some setup, including compilation of the distribution.

For general information on obtaining and using encrypted SQLite-like databases in your applications, consult SQLCipher’s or SEE’s documentation at https://www.zetetic.net/sqlcipher/ and https://www.sqlite.org/see/doc/trunk/www/readme.wiki.

Secure Random Number Generation

We’ve looked at how random numbers can be badly generated in some detail in Chapter 12’s section, “Insecure Random Number Generation.” In particular, we focused on how the .NET non-cryptographically secure random number generator—System.Random—may introduce security bugs into apps that are supposed to be secure.

In the context of mobile applications, arguably the most common use case for random number generation is in the generation of crypto keys. In modern mobile computing, mobile apps often rely on data held in an app’s isolated storage as being secure, and as such, recovery of this data by attackers may potentially have very serious consequences.

System.Random is not fit for generating cryptographically secure crypto keys. This short section gives positive examples showing how the RNGCryptoServiceProvider API can instead be used for generating crypto keys. Of course, the same method may be used for generating random data for any other purposes.

RNGCryptoServiceProvider does not have the same problems with predictability of outputted data that System.Random does. Fortunately, as well, using RNGCryptoServiceProvider is straightforward. Consider the following example for generating a 256-bit crypto key:

RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); 
byte[] cryptoKey = new byte[32]; 
rng.GetBytes(cryptoKey); 
 
// cryptoKey now holds 32 random bytes!

Although the RNGCryptoServiceProvider API is significantly slower (some benchmarks estimate around 300 times slower), in the context of mobile applications, generation of crypto keys and other random data is generally a rare occurrence, hence the cryptographic security of the outputted data versus the speed of its generation is a trade-off that is absolutely worth it for apps that need to be secure.

The full documentation for the RNGCryptoServiceProvider class appears on the API’s MSDN page at http://msdn.microsoft.com/en-us/library/system .security.cryptography.rngcryptoserviceprovider%28v=vs.110%29.aspx.

Securing Data in Memory and Wiping Memory

When you’re handling sensitive data in memory, being able to wipe the memory when it is no longer immediately needed is sometimes desirable. Having sensitive memory secured is also desirable to lessen the chances of memory analysis attacks from gaining access to sensitive data in a process’s memory space. An example of such a piece of data would be a crypto key.

We advise that crypto keys be wiped from memory when they are not needed. Example scenarios for when to wipe a crypto key include:

  • When the app is placed into the background
  • When the app’s custom screen lock is applied
  • When the key is not needed for the time being

In such cases, overwriting all elements of the byte array holding the crypto key is recommended. For example:

for(int i = 0; i < 32; i++) { 
       cryptoKey[i] = 0; 
}

Of course, most Windows Phone applications are running in a runtime, and in theory the runtime might create additional copies of any objects, so clearing a byte array to rid the process of the data should be considered a “best effort” attempt.

One possible solution to this problem is to implement all crypto code as a native library and call into it from your C# code. The native library would deal with all crypto-related tasks, and then memset_s()crypto keys and other sensitive data after its tasks are complete. (The _s() prevents compiler optimization from removing the memset() call.) The following URL provides a sample project for calling into a native library (written in C++) via managed C# code: https://code.msdn.microsoft.com/windowsapps/Windows-Phone-8-JumpStart-108965b9.

If, however, your app is actually written as a native app, using memset_s() on your sensitive crypto keys should be sufficient to ensure their deletion from your process’s memory space.

Bear in mind that string objects are immutable, hence after values are held in these objects, the value cannot be cleared; the disposal of the object’s contents is at the discretion of the CLR’s garbage collector. Unfortunately, no secure equivalent, such as SecureString, is currently supported on the Windows Phone platforms. Wherever possible, then, developers should attempt to use byte[] and char[] arrays instead of strings, for storing particularly sensitive data such as passwords.

Removing sensitive data from the process’s memory is a best-effort attempt on the developer’s part. However, the object’s immediate removal is not guaranteed (that is, via garbage collection). When developers must use string objects and want to have the content’s garbage collected and removed, they may consider setting the reference to null, at which point they would call the garbage collector manually:

s = null;   // set ref to null 
GC.Collect();    // invoke GC

Note, however, that this does not guarantee that the object’s contents will be disposed of immediately, but it’s about the best a developer can do when using immutable objects.

Avoiding SQLite Injection

When apps use Windows Phone local databases for storing their data in database format, there is no risk of SQL injection, because developers interact with the database via a LINQ-to-SQL layer, rather than talking to the database directly using SQL queries.

There may be risk of SQL injection, however, when SQLite databases are used; SQL injection is possible in Windows Phone apps when developers use SQLite (such as via sqlite-net) or SQLCipher. The following APIs are prone to being misused for SQL injection attacks:

  • db.CreateCommand()
  • db.Execute()
  • db.ExecuteScalar()
  • db.Query()
  • db.Query<T>()
  • db.DeferredQuery()
  • db.DeferredQuery<T>()

When developers want to execute raw queries instead of using abstraction layers to handle SQL statement construction, SQL injection bugs occur due to direct inclusion of attacker-controlled data into queries, instead of using parameterization for construction of the query.

For example, the following code fragment is vulnerable to SQL injection, assuming an attacker is in control of the attackerInput string:

var db = new SQLiteConnection(Path.Combine(ApplicationData.Current.LocalFolder. 
Path, 
"test.db")); 
 
[ ... ] 
 
SQLiteCommand cmd = db.CreateCommand("select * from Stock where Symbol = '" + 
attackerInput + "'"); 
 
// get all stock items with name in question 
List<Stock> stockList = cmd.ExecuteQuery<Stock>();

In the preceding snippet, the attackerInput string is included into the raw query by concatenation, thus any data in the attackerInput string simply becomes part of the query itself, allowing the attacker to change the structure of the actual query.

Developers needing to construct raw queries for operations on their SQLite database should use the API’s parameterization features. The following code snippet shows how to construct the same query as earlier, without being vulnerable to SQL injection:

var db = new SQLiteConnection(Path.Combine(ApplicationData.Current. 
LocalFolder.Path, 
 "test.db")); 
 
[ ... ] 
 
SQLiteCommand cmd = db.CreateCommand("select * from Stock where Symbol = ?", 
 attackerInput); 
 
// get all stock items with name in question 
List<Stock> stockList = cmd.ExecuteQuery<Stock>();

The emboldened "?" character instructs the CreateCommand() API to include attackerInput as a parameter to the query, and as such, any data in attackerInput will be correctly treated as data, rather than as part of the query syntax itself.

In general, however, we recommend that you use a data model approach, instead of constructing raw SQL queries if possible. Sqlite-net’s github README gives a simple example of how to do this at https://github.com/praeclarum/sqlite-net/blob/master/README.mdown. The example is also applicable to SQLCipher, given the deliberate similarity of its API to other SQLite layers.

Implementing Secure Communications

As with any application that requires secure network communications, mobile apps should also use secure communications channels for their network-based interactions. This section offers guidelines for secure network communications.

Using SSL/TLS

Using SSL/TLS for all network traffic that has the potential to contain sensitive information is now standard. In general, though, we recommend using SSL/TLS for all network communications, because interference on non-sensitive communications can also end up having security consequences; consider as-of-yet unknown parsing vulnerabilities, or HTML/JavaScript injection that facilitates phishing attempts, for example.

For carrying out any kind of web-based interaction, we recommend using https:// URLs, as opposed to http:// URLs, which result in traffic transmitted in unencrypted form.

When apps use WebBrowser or WebView components, pages should be loaded via https://,

 webBrowser.Navigate(new Uri("https://www.myapp.co.uk", UriKind.Absolute));

and never via http://, as in this insecure example:

webBrowser.Navigate(new Uri("http://www.myapp.co.uk", UriKind.Absolute));

The same principles apply when making API requests using, for example, the WebRequest API; use SSL—as in,

string requestUri = "https://www.myapp.co.uk/webapi/getPost= + postId; 
HttpWebRequest request = 
    (HttpWebRequest)HttpWebRequest.Create(requestUri); 
 
[ ... ] 
 
request.BeginGetResponse(GetPostCallback, request);

and not via the equivalent http:// URL.

SSL connections should be used for network interactions that are not HTTP-based. The following MSDN documentation details how to enable SSL/TLS for connections being made via Windows.Networking.Sockets: http://msdn.microsoft.com/en-us/library/windows/apps/hh780595.aspx.

Although it’s arguable that requests that do not deal with sensitive information do not need to be made via SSL/TLS sessions, data encryption is not the only security advantage of using encrypted tunnels. Use of SSL/TLS for non-sensitive communications should be encouraged because SSL/TLS guarantees the integrity of data being sent and received, guarantees the identity of the remote peer, and can prevent unanticipated attacker vectors that could occur as a result of an attacker’s being able to inject into a non-SSL/TLS’d stream (that is, phishing attempts or exploiting a bug in a library being used by an app, either directly or indirectly).

We therefore recommend the use of SSL/TLS for all network communications made by mobile apps, especially given that using smartphones on untrusted networks such as open Wi-Fi networks in coffee shops, bars, and in hotels has become very common. Some standard cell phone protocols, such as General Packet Radio Service (GPRS), also have known problems relating to forcing phones to connect to an attacker-controlled base station (http://blog.mdsec .co.uk/2014/11/44con-2014-greedybts-hacking-adventures.html).

SSL/TLS Certificate Validation

In general, the only sensible reason for disabling certificate validation in applications is that the application is in development, because many development environments do not have certificate authority (CA)-signed certificates installed on their infrastructure. In production, generally no good reasons exist for having SSL/TLS certificate validation disabled.

In Windows Phone 8, the HTTP APIs expose no documented way to disable certificate validity checks, thus ensuring that certificate validation is enabled is not generally a concern in Windows Phone 8 apps.

Windows Phone 8.1, however, does allow certificate validation to be turned off in Windows.Web.Http.HttpClient objects, via use of an HttpBaseProtocolFilter object. Code like the following disables certificate validation:

HttpBaseProtocolFilter filter = new HttpBaseProtocolFilter(); 
 
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.Untrusted); 
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.Expired); 
 
[ ... ] 
 
var httpClient = new Windows.Web.Http.HttpClient(filter);

Developers preparing their applications for build and release should ensure that no HttpBaseProtocolFilter object is being instantiated and used for disabling SSL/TLS certificate validation. Failure to ensure that certificate validation is turned on in production builds may endanger the data of app users, thus adding such checks to an engineer’s build checklist is highly encouraged.

Avoiding Cross-Site Scripting in WebViews and WebBrowser Components

In Chapter 12, we discussed how injection attacks into WebBrowser and WebView components could have serious security consequences. In particular, cross-site scripting attacks by suitably positioned attackers (that is, unencrypted Wi-Fi in coffee shops and hotels) could result in attacks such as cookie theft and phishing attacks. Because guarding against these attacks is important for secure smartphone apps, we offer guidelines for minimizing the risk of cross-site scripting in WebBrowser and WebView components.

Using SSL/TLS for Network Communications

When WebBrowser and WebView components fetch and render data via HTTP (and not HTTPS), the risk always exists of a suitably positioned attacker injecting data into the session. Such data could include JavaScript and HTML that sets up a phishing attempt, or JavaScript that attempts to steal a user’s session cookies could be introduced. Injected HTML and JavaScript could also attempt to exploit parsing vulnerabilities in the HTML and JavaScript engines themselves.

As mentioned earlier in this chapter, using SSL/TLS sessions for all communications, whether traffic is deemed to be sensitive or not, is advisable.

Disabling JavaScript

If a WebBrowser control does not specifically require JavaScript to provide the app’s functionality, not enabling it is advisable. WebBrowser components actually require JavaScript to be explicitly enabled for JavaScript to be executed in the first place.

JavaScript may be enabled via the IsScriptEnabled property, either programmatically or in the appropriate XAML markup. The default is False, but copying and pasting code examples from sites such as StackOverflow may result in some developers shipping apps that enable JavaScript without that particular intention.

If your app’s WebView or WebBrowser does not explicitly require JavaScript to be enabled, ensure that the app does not contain the following (on a non–case-sensitive basis), in any XAML pages, or in its codebase:

IsScriptEnabled="True"

Setting the IsScriptEnabled property to False explicitly for your WebBrowser instances may be advisable, if you don’t need JavaScript, in case Microsoft changes the default to True in the future. JavaScript can be explicitly disabled in the XAML page markup that the WebBrowser component is contained within, i.e.,

<phone:WebBrowser Name="browser" 
                          IsScriptEnabled="False" 
                          ScriptNotify="browser_ScriptNotify" 
                          Source="https://www.myapp.com"/>

Alternatively, the setting can be set programmatically on the object in question:

myWebBrowser.IsScriptEnabled="False"

Currently no documented way exists to disable JavaScript on a WebView object, so a developer who does not require the use of JavaScript may consider using WebBrowser in place of WebView.

Safe Construction of Dynamic HTML and JavaScript

Some apps may construct HTML and JavaScript dynamically, often using data that is influenced or controlled by an attacker. For example, consider the following code fragment:

string someHtml = "<html><head><img src="attackerInfluencedValue"></html>"; 
 
[ ... ] 
myWebView.NavigateToString(someHtml);

In such situations, developers must ensure that attacker-influenced values being inserted into dynamically-generated HTML and JavaScript code is sanitized so that attackers cannot control the syntax of the resulting code.

To prevent many cases of malicious content from being injected into HTML/JavaScript strings, use the HttpUtility.HtmlEncode() API:

string someHtml = "<html><head><img src="" + 
HttpUtility.HtmlEncode(attackerInfluencedValue) +" "></html>";

In such cases, the attacker’s string would be unable to break out of the src="..." parameter, thus preventing scripting injection attacks.

Developers must also be careful in passing attacker-controlled values as JavaScript function parameters, however. Consider the following case:

string someHtml = "<html><head><script>someFunction(" + 
attackerControlledString + ")</script><html>";

In this case, an attacker could, for example, pass alert(1) in as attackerControlledString, which would result in alert(1) being executed before control is passed to someFunction().

To prevent such cases, enclose the attacker-controlled value in double-quotes, and also escape it to prevent escape from the double quotes:

string someHtml = "<html><head><script>someFunction("" + 
HttpUtility.HtmlEncode(attackerControlledString) + "")</script><html>";

Avoiding Local Scripting Attacks

In the Chapter 11 we described how opening files in WebBrowser and WebView controls from the local filesystem could result in the theft of files from the app’s sandbox. In particular, this is possible because the same-origin policy allows access to documents that are from the same origin; in the context of a file loaded locally, this is the local filesystem.

Therefore, avoiding the construction or offline saving of web pages for future loading from the filesystem is advisable, unless you’re very careful in ensuring that their contents are safe.

Secure XML Parsing

It’s well understood in the computer security industry that the main risks around XML parsing is the resolution of Document Type Definitions DTDs)—particularly DTDs that refer to external entities such as local files and other URLs. External entity attacks can result in theft of files from the filesystem and may allow internal web services to be hit via URLs being resolved as external entities; both cases are obviously undesirable from a security perspective. Expanding DTDs can also result in denial-of-service (DoS) attacks, often called the “billion laughs” attack.

As we discussed in some detail in the Chapter 11 section, “Attacking XML Parsing”, the standard API for XML processing in Windows Phone apps is XDocument and associated classes.

Fortunately for the Windows Phone developer, XDocument objects do not parse DTDs by default, and as such, a developer must manually set an attribute on the object to enable such parsing. This, however, is possibly more common than expected, given that developers often copy and paste code from community contribution sites such as StackOverflow.

Developers and security testers should ensure that apps do not have code similar to the following, which enables DTD parsing:

var settings = new XmlReaderSettings { DtdProcessing = DtdProcessing.Parse }; 
 
XmlReader xmlReader = XmlReader.Create("someFile.xml", settings); 
 
// parse the XML file 
XDocument xmlDoc = XDocument.Load(xmlReader);

Clearing Web Cache and Web Cookies

If a device is compromised, an attacker may be able to gain access to cookies and the web cache that was acquired via the app’s web-based interactions. Compromising cookies may allow access to a user’s web session, and compromising the cache may result in disclosure of sensitive information to the would-be attacker.

From a security perspective, clearing cookies and the web cache when they are no longer needed, such as when an app’s screen lock is enabled, or when the user logs out of the app or the web interface it’s talking to, is therefore good practice. We’ll discuss here how you can do that.

Clearing Cookies

Remove cookies from the device when they are no longer needed, because they may otherwise still be present in the app’s INetCookies directory. The WebBrowser control allows cookies to be deleted using the ClearCookiesAsync() API:

await new WebBrowser().ClearCookiesAsync();

Note that the ClearCookiesAsync() API may simply be called on any WebBrowser component instantiated by the app, or statically, as in the previous code snippet.

There is also a way to delete cookies when WebView is being used:

Windows.Web.Http.Filters.HttpBaseProtocolFilter myFilter = new 
Windows.Web.Http.Filters.HttpBaseProtocolFilter(); 
var cookieManager = myFilter.CookieManager; 
HttpCookieCollection myCookieJar = cookieManager.GetCookies(new 
Uri("https://www.targeturi.com")); 
foreach (HttpCookie cookie in myCookieJar) 
{ 
    cookieManager.DeleteCookie(cookie); 
}

Here https://www.targeturi.com is the URL for which cookies are to be deleted.

Clearing Web Cache

The most full-proof way of ensuring that none of your application’s web interactions result in cache storage to its INetCache folder is to ensure that the web server being interacted with specifies appropriate non-caching directives in its HTTP(S) responses. For example, the following headers in HTTP(S) responses should be sufficient to prevent WebView, WebBrowser, WebRequest (and other such classes) from caching data from any responses:

Cache-Control: no-store 
Pragma: no-cache

The previous snippet represents our general advice for prevention of data caching.

When applications use a WebBrowser control, you can programmatically delete that WebBrowser’s cache, using the ClearInternetCacheAsync() API. Refer to the API’s MSDN documentation at the following URL: http://msdn.microsoft .com/library/windows/apps/jj571213(v=vs.105).aspx.

Unfortunately, at the time of writing, there is no documented way to programmatically clear a cache put in place by use of a WebView. See the appropriate section at the following MSDN blog post: http://blogs.msdn.com/b/wsdevsol/archive/2014/04/03/ten-things-you-need-to-know-about-webview-_2d00_-an-update-for-windows-8.1.aspx#AN7.

Avoiding Native Code Bugs

Because native code does not have the safety features of the Common Language Runtime (CLR) to protect it, Windows Phone applications written in native code (C, C++), or those calling into native modules, need to be carefully written to avoid native code vulnerabilities.

Native code components containing such vulnerabilities as memory corruption bugs (heap overflows, stack overflows, and so on), format string bugs, uninitialized variable use, and so on, may all fall prey to classic native code attacks.

Developers should therefore review their native codebases for dangerous API misuse and other insecure coding practices.

We recommend consulting the following resources for information on security coding guidelines for native code development, which are provided by CERT: C secure coding guidelines at https://www.securecoding.cert.org/confluence/display/seccode/CERT+C+Coding+Standard and C++ secure coding guidelines at https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=637.

We also recommend consulting Microsoft’s banned API list, which is offered as a C and C++ header file. You may obtain the file directly via the following URL: http://download.microsoft.com/download/2/e/b/2ebac853-63b7-49b4-b66f-9fd85f37c0f5/banned.h.

Consider inserting #include to place the file into your code for analysis purposes. The following resource discusses how to use banned.h to analyze whether your codebase is misusing potentially dangerous APIs: http://blogs.microsoft .com/cybertrust/2012/08/30/microsofts-free-security-tools-banned-h/.

Otherwise, you can manually analyze your app’s usage of APIs listed in banned.h to ensure no API misuse could result in classic native code vulnerabilities.

Using Exploit Mitigation Features

As we already discussed in Chapter 10 and Chapter 11, Windows Phone supports several exploit mitigation features, including:

  • /GS protections (stack cookies and other stack overflow protections such as variable reordering)
  • NXCOMPAT (DEP)
  • SafeSEH
  • /DYNAMICBASE (ASLR)

As per Visual Studio’s default settings, all of these are enabled on native binaries built from Visual Studio, hence unless these settings have been changed, your application’s native components should have these. Having exploit mitigation features significantly reduces the ease with which native code vulnerabilities may be exploited in vulnerable apps. Enabling them on all native binaries that are part of your app is highly recommended.

Microsoft released a useful tool named BinScope, available at http://www .microsoft.com/en-gb/download/details.aspx?id=11910, for the purpose of analyzing native binaries to ensure that the recommended exploit mitigation technologies are enabled on the binary in question.

We recommend that developers run BinScope on all native binaries distributed as part of their applications. In any case, it appears that for Windows Phone 8.1 apps, Microsoft insists upon BinScope’s catalog of tests passing. See the following resource for further details: http://msdn.microsoft.com/en-us/library/windowsphone/develop/dn629257.aspx#binscope.

Summary

In this chapter, we’ve aimed to offer some key guidelines for implementing secure Windows Phone apps. We recommend following the guidelines when trying to implement Windows Phone applications with security requirements:

  • Encrypt all sensitive data, whether stored in databases, or other file formats.
  • Follow industry-standard cryptography practices, and preferably, use AES-256.
  • Apply sensible cryptography key management principles. For example, use PBKDF2, and enforce a reasonably strict password complexity policy.
  • Use a secure random data source, when needed (i.e., RNGCryptoServiceProvider).
  • Attempt to wipe keys and passwords from memory, via a best-effort approach, when they are no longer required.
  • Avoid SQL injection in apps that use SQLite-derived databases.
  • Implement secure network communications via SSL/TLS.
  • Take care to avoid cross-site scripting and script injection bugs.
  • Ensure that XML parsing doesn’t resolve DTDs, unless this functionality is specifically required by your app.
  • Try to clear web cache and cookies when they’re no longer needed.
  • Apply native code secure coding guidelines to avoid traditional bugs such as buffer overflows.
  • Build your native modules with exploit mitigation features enabled.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.216.239.46