okta / okta-mobile-swift

okta-mobile-swift
https://github.com/okta/okta-mobile-swift
Apache License 2.0
44 stars 19 forks source link

Add ability to inject URLSession in WebAuthenticationUI flows to enable certificate pinning. #162

Open SwiftNativeDeveloper opened 11 months ago

SwiftNativeDeveloper commented 11 months ago

Describe the feature request?

I would like the ability to secure and instrument all network calls being made in my application. Specifically, I'd like the ability to pass in a URLSession that I control, or at least the assigned configuration and delegate. This would allow me to perform certificate pinning on the connection if I choose to mitigate MITM attacks.

The authentication challenge delegate callback is the method that needs to be overridden.

Allowing injection of a URLSession also would enable metric collection via the task metrics delegate callback as an added perk.

This request is inspired by reading Insecure Communication on OWASP.

Seealso: OWASP Mobile Top 10 2023

It appears that this would just be adding another initialization parameter. It could be optional and nil by default here.

New or Affected Resource(s)

https://github.com/okta/okta-mobile-swift/blob/master/Sources/WebAuthenticationUI/WebAuthentication.swift#L305

Provide a documentation link

No response

Additional Information?

No response

mikenachbaur-okta commented 9 months ago

The SDK already has the support for customizing the URLSession used for authentication. For example, you can supply your own URLSession when creating an OAuth2Client, which can be used when creating an authentication flow (e.g. AuthorizationCodeFlow) which can subsequently be used within the WebAuthentication class.

Beyond that though, Apple provides support for certificate pinning that doesn't require interaction with a URLSessionDelegate. https://developer.apple.com/news/?id=g9ejcf8y

I'd love to hear more though about your thoughts on customizing the URLSession, since the process for supplying a custom URLSession is somewhat cumbersome, and doesn't enable the use of some of the convenience initializers for these various classes.

SwiftNativeDeveloper commented 9 months ago

Thanks @mikenachbaur-okta for the reply. I totally missed that initializer passing in the code flow instead. I'll check it out and see if it suits my needs.

Regarding the pinning, that would certainly work to do it at the app level. That having been said, it then forces the requirement on app teams to update their app if anything changes. Having control over the URLSession and it's delegate allow the auth challenge callback to dynamically support updates if you have an out-of-band mechanism to do so.

Some use cases for having fine control over the delegate include:

As for customizing the URLSession itself (URLSessionConfiguration), my focus was on just the delegate. I'd have to double check what makes sense. I don't have any specific examples at the moment, but I might after I try that other initializer you pointed out.

mikenachbaur-okta commented 9 months ago

Yes, those all sound like sensible use-cases and are things I had planned for. The SDK utilizes the APIClient protocol (with its default implementations) which is backed by a URLSession. This is passed along from the OAuth2Client (which conforms to APIClient), and is consumed by the flows and higher-level abstractions above it.

The Credential class adds a great number of conveniences, but initializing it with an explicit URLSession isn't currently very easy to do, so this is an area I've planned to improve upon.

So from your perspective @SwiftNativeDeveloper, would you prefer to assign your own URLSession? Or simply to provide a delegate that can be assigned to any URLSession implicitly created on your behalf?

baksha97 commented 8 months ago

New member to the conversation here - it would personally be best for me to be able to assign the SDKs a URLSession to use; e.g. through some bootstrapping process or centralizing the setting in the configuration provided to the flows/credentials.

Having to re-init a Credential before use with a custom OAuth2Client for injecting a custom session, while managing any additional Okta caveats to achieve this behavior is a big deterrent to leveraging the existing paths available

Ideally this centralization of a URLSession would corral all requests from the suite of Okta SDKs.

SwiftNativeDeveloper commented 8 months ago

@mikenachbaur-okta

So from your perspective @SwiftNativeDeveloper, would you prefer to assign your own URLSession? Or simply to provide a delegate that can be assigned to any URLSession implicitly created on your behalf?

I would prefer to inject the URLSession itself so I can apply a custom configuration if necessary in addition to controlling the delegate.