Обмен учетными данными между ios 8 приложениями и вебом,...

Post on 15-Jan-2015

437 Views

Category:

Technology

3 Downloads

Preview:

Click to see full reader

DESCRIPTION

Речь пойдёт о том, как реализовать обмен учётными данными пользователя между iOS-приложениями и вебом с учётом особенностей iOS 8.

TRANSCRIPT

Kanstantsin Charnukha, Yury Vasileuski

Sharing credentials between native apps and Safari

Mobile Camp, 2 August, 2014

iOS authorization development team

Content

Credentials

Sharing credentials and iOS 7

Sharing credentials and iOS 8

5

Credentials

6

Credentials lifecycle

7

UI and memory

• Secure text entry

• Dump memory with GDB and Jailbreak

8

Network

• HTTPS

• Man in The Middle (MiTM)

9

MiTM

• HTTPS is vulnerable to MiTM

• Credentials may leak

10

SSL Pinning

• Protection against MiTM

• Connection only to known server

11

Storing and sharing credentials

12

Storing credentials on disk

• NSUserDefaults – Backup

– Jailbreak

– No ability to share between apps

• NSFileManager – NSFileProtectionComplete

– No passcode

– Brute force

– Jailbreak

– No ability to share between apps

• Keychain – Jailbreak

– Sharing between apps of the vendor

13

Keychain

• Keychain is sqlite DB

• /private/var/Keychains/keychain-2.db

• Hardware specific key encryption

• Key is unique per device

Keychain allows to share credentials

Access group

Sharing with keychain

• Same access group in entitlements

• $(AppIdentifierPrefix) is the first part of group ID

• $(AppIdentifierPrefix) may be retrieved

programmatically by getting or adding any item in

keychain

Options to store credentials

• No credentials storage

• Store authorization token

• Store passwords in keychain

• Store x-token in keychain

No credentials storage

• User enters credentials each launch

• Secure

• No credentials storage

Store authorization token

• Credentials on token expiration

• High security level

Store passwords in keychain

• User enters credentials only once

• Common approach

• Low security level

Store x-token in keychain

• User enters credentials only once

• High security level

Store x-token in keychain

• Can be used by other apps

X-Token and credentials sharing

• Password is exchanged with x-token.

• Each app saves x-token to keychain.

• Secure. Password is not stored on device.

• Sharing between apps.

• Each app can exchange it for token with special

permissions.

Credentials and Safari

?

Safari credentials in iOS 7

Safari credentials in iOS 7

• Saves

passwords

• No access to

keychain data

• No access to

cookies

28

Safari credentials in iOS 7

WWDC 2014 topics of interest

• Shared web credentials API in Safari session 506: Your App, Your Website, and Safari

• Support of actions by Safari session 217: Creating Extensions for iOS and OS X, Part Two

31

Safari credentials in iOS 8

32

Sharing credentials with Safari, iOS 8

Shared web credentials API:

• Direct export to app

• Direct import from app

Actions support:

• Indirect import to Safari

• Indirect export from Safari

• Support of specific credentials

Safari and native app

Safari Native app

34

Safari shared web

credentials

Shared shared web credentials API

void SecAddSharedWebCredential(

CFStringRef fqdn,

CFStringRef account,

CFStringRef password,

void (^completionHandler)(

CFErrorRef error));

void SecRequestSharedWebCredential(

CFStringRef fqdn,

CFStringRef account,

void (^completionHandler)(

CFArrayRef credentials,

CFErrorRef error));

Shared web credentials API

void SecAddSharedWebCredential(

CFStringRef fqdn,

CFStringRef account,

CFStringRef password,

void (^completionHandler)(

CFErrorRef error));

void SecRequestSharedWebCredential(

CFStringRef fqdn,

CFStringRef account,

void (^completionHandler)(

CFArrayRef credentials,

CFErrorRef error));

Account and password

• Raw credentials

• Easy to use and understand

• Easy to import from Safari to any app

• Difficult to export from “token-based” app to Safari

Shared web credentials API

void SecAddSharedWebCredential(

CFStringRef fqdn,

CFStringRef account,

CFStringRef password,

void (^completionHandler)(

CFErrorRef error));

void SecRequestSharedWebCredential(

CFStringRef fqdn,

CFStringRef account,

void (^completionHandler)(

CFArrayRef credentials,

CFErrorRef error));

fqdn or Fully qualified domain name

@function SecRequestSharedWebCredential

@param fqdn (Optional) Fully qualified domain name

of the website for which passwords are being

requested. If NULL is passed in this argument, the

domain name(s) listed in the calling application's

'com.apple.developer.associated-domains'

entitlement are searched implicitly.

Associated domains

Domains are listed at Safari AutoFill Settings.

41

Safari and native app

Safari Native app

42

Associating app and web site

app #5

yandex.ru

gmail.com

facebook.com

twitter.com

app #4

facebook.com

43

Associating app and web site

app #5

yandex.ru

gmail.com

facebook.com

twitter.com

app #4

facebook.com

44

Associating app and web site

app #5

yandex.ru

gmail.com

facebook.com

twitter.com

yandex.ru

app #1

app #2

facebook.com app #4

facebook.com

https://domain/apple-app-site-association

gmail.com

twitter.com

app #3

app #4

45

Associating app and web site

app #5

yandex.ru

gmail.com

facebook.com

twitter.com

yandex.ru

app #1

app #2

facebook.com

app #3 app #4

facebook.com

gmail.com

twitter.com

app #4

46

Associating app and web site

app #5

yandex.ru

gmail.com

facebook.com

twitter.com

yandex.ru

app #1

app #2

facebook.com

app #3 app #4

facebook.com

gmail.com

twitter.com

app #4

Test server setup with node.js

// missing node.js common setup

app.all('/apple-app-site-association', function(req, res,

next) {

res.setHeader('Content-Type', 'application/pkcs7-mime');

next();

});

var PORT = 8000;

var HOST = ’test.host.on.private.network.net';

var sshKey = fs.readFileSync('./certs/key.pem');

var sshCert = fs.readFileSync('./certs/cert.pem')

var https_options = {key: sshKey, cert: sshCert};

https.createServer(https_options, app).listen(PORT, HOST);

Test server setup with node.js

// missing node.js common setup

app.all('/apple-app-site-association', function(req, res,

next) {

res.setHeader('Content-Type', 'application/pkcs7-mime');

next();

});

var PORT = 8000;

var HOST = ’test.host.on.private.network.net';

var sshKey = fs.readFileSync('./certs/key.pem');

var sshCert = fs.readFileSync('./certs/cert.pem')

var https_options = {key: sshKey, cert: sshCert};

https.createServer(https_options, app).listen(PORT, HOST);

49

Notes on server setup

• Certificate is verified by iOS itself

• Not available on simulator

• No way to use self-signed certificate

• Self-installed certificates impacts Safari, but not

verification process

• Provide certificate signed by iOS trusted CA

• Use static domains, no local IPs.

• Apply to multiple domains

50

• Multiple app prefixes (AppStore, AdHoc, Debug)

• Multiple bundles (AppStore, inhouse)

• Different certificates for every domain

// apps.json content

{"webcredentials":{"apps":["APPSTORE_PREFIX.ru.yandex.app1

", "APPSTORE_PREFIX.ru.yandex.app2"]}}

cat apps.json | openssl smime -sign –inkey certs/key.pem –

signer certs/cert.pem -noattr -nodetach -outform DER > apple-

app-site-association

apple-app-site-association

User control and credential access

52

Usage drawbacks

1. User-side security but poor user experience

2. User asked on every single credential access

3. No method to check account existence

4. Difficult to sync account addition and removal

53

Actions and Safari

54

Actions

Action is an extension point that helps users to

manipulate or view content within the context of

another app, e.g. transforming DOM within Safari.

55

Empty login page within Safari

56

Safari actions bar

57

Custom actions within Safari

58

• UIActivityViewController

• NSURL

NSString *stringURL = @"https://yandex.ru";

NSURL *pageURL = [NSURL URLWithString:stringURL];

UIActivityViewController *activityVC = [[UIActivityViewController

alloc]

initWithActivityItems:@[pageURL, stringURL]

applicationActivities:nil];

[mainVC presentViewController:activityVC

animated:YES

completion:nil];

Displaying activities within Safari

59

NSExtension setup to handle Safari

• NSExtensionActivationRule

• NSExtensionActivationSupportsWebURLWithMaxCount

Native app keychain credentials

61

Completed login page

62

NSExtension setup to access DOM

• NSExtensionAttributes

• NSExtensionJavaScriptPreprocessingFile

63

• ExtensionPreprocessingJS

// PasswordHandler.js

var PasswordHandler = function() {};

PasswordHandler.prototype = {

run: function(arguments) {

...

},

finalize: function(arguments) {

...

}

};

var ExtensionPreprocessingJS = new PasswordHandler

JavaScript preprocessing file

64

run: function(arguments) {

var loginInput = document.getElementsByName("login")[0]

var loginInputText = loginInput.value

var passwdInput = document.getElementsByName("passwd")[0]

var passwdInputText = passwdInput.value

arguments.completionFunction({

”login" : loginInputText, ”passwd" : passwdInputText})

}

finalize: function(arguments) {

var loginInput = document.getElementsByName("login")[0]

var loginInputText = arguments["login"]

loginInput.value = loginInputText;

var passwdInput = document.getElementsByName("passwd")[0]

var passwdInputText = arguments["passwd"]

passwdInput.value = passwdInputText

}

Getting values from DOM

65

run: function(arguments) {

var loginInput = document.getElementsByName("login")[0]

var loginInputText = loginInput.value

var passwdInput = document.getElementsByName("passwd")[0]

var passwdInputText = passwdInput.value

arguments.completionFunction({

”login" : loginInputText, ”passwd" : passwdInputText})

}

finalize: function(arguments) {

var loginInput = document.getElementsByName("login")[0]

var loginInputText = arguments["login"]

loginInput.value = loginInputText;

var passwdInput = document.getElementsByName("passwd")[0]

var passwdInputText = arguments["passwd"]

passwdInput.value = passwdInputText

}

Getting values from DOM

66

• NSExtensionJavaScriptFinalizeArgumentKey

• kUTTypePropertyList

NSDictionary *js =

@{NSExtensionJavaScriptFinalizeArgumentKey:

@{@"login" : self.login, @"passwd": self.passwd}};

NSItemProvider *pItem = [[NSItemProvider alloc]

initWithItem:js

typeIdentifier:(NSString *)kUTTypePropertyList];

NSExtensionItem *eItem = [[NSExtensionItem alloc] init];

eItem.attachments = @[providerItem];

[self.extensionContext

completeRequestReturningItems:@[eItem]

completionHandler:nil];

Setting values to DOM

Differences

Pros:

• No server setup by default

• Custom credentials support

• Any browser and web view support

Cons:

• Not available on device by default

• More difficult to implement on client side

• No server side control by default

• Security is developer responsibility

Summary

• Credentials

• Sharing credentials and iOS 7

• Sharing credentials and iOS 8

Kanstantsin Charnukha,

xardas@yandex-team.ru

iOS authorization

development team

Thanks

Yury Vasileuski,

vasileuski@yandex-team.ru

top related