{"id":127826,"date":"2021-06-16T12:00:29","date_gmt":"2021-06-16T12:00:29","guid":{"rendered":"https:\/\/developer.apple.com\/news\/?id=jxky8h89"},"modified":"2021-06-16T12:00:29","modified_gmt":"2021-06-16T12:00:29","slug":"fine-tune-your-app-transport-security-settings","status":"publish","type":"post","link":"https:\/\/sickgaming.net\/blog\/2021\/06\/16\/fine-tune-your-app-transport-security-settings\/","title":{"rendered":"Fine-tune your App Transport Security settings"},"content":{"rendered":"<div class=\"inline-article-image\"><img decoding=\"async\" src=\"https:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2022\/09\/fine-tune-your-app-transport-security-settings.jpg\" data-hires=\"false\" alt=\"Padlock symbol badged with a globe symbol\"><\/div>\n<p>At Apple, we believe privacy is a fundamental human right. When people connect to a public Wi-Fi hotspot, they expect to use your app to send and receive data without worrying that someone in the vicinity could intercept their connection and gain access to unencrypted data. Allowing even seemingly-innocuous data to remain unencrypted can expose people to snooping and fingerprinting by anyone on the network.<\/p>\n<p>Transport Layer Security (TLS) uses encryption to protect connections from prying eyes, and URLSession provides strong TLS connections by default with App Transport Security (ATS). <\/p>\n<p>If you need to connect to older servers that don&#8217;t support TLS, however, you can now add ATS exceptions to your app. Ideally, exceptions should just carve out the specific domains or frameworks that make insecure connections, and you should limit any exceptions you do request. Avoid sending data unencrypted except when absolutely necessary for your app to function.<\/p>\n<h3>Identify necessary ATS exceptions<\/h3>\n<p>To make sure your app \u2014 and the data used within it \u2014 is as secure as possible, it\u2019s important to identify whether your app is currently making insecure connections.<\/p>\n<p>To check, disable all your active ATS exceptions by setting their values in your Info.plist to \u201cNO.\u201d From there, open your app or run your unit tests. If your app makes an insecure connection, Xcode will generate runtime errors for each one.<\/p>\n<div class=\"inline-article-image\"><img decoding=\"async\" src=\"https:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2022\/09\/fine-tune-your-app-transport-security-settings-1.jpg\" data-hires=\"false\" alt><\/div>\n<p>If your app is generating insecure connections, there are a few steps you can take to remove them.<\/p>\n<p><strong>Secure your servers<\/strong><\/p>\n<p>If your app connects to servers you control, make sure those servers support secure connections. This requires a TLS certificate. If you use a hosting service, check whether they offer certificates, and make sure those certificates meet the requirements detailed in \u201cPreventing Insecure Network Connections.\u201d<\/p>\n<p><a href=\"https:\/\/developer.apple.com\/documentation\/security\/preventing_insecure_network_connections\" class=\"icon icon-after icon-chevronright\">Preventing Insecure Network Connections<\/a><\/p>\n<p><strong>Use HTTPS<\/strong><\/p>\n<p>If your app connects to servers you don\u2019t control, you should always attempt to connect to those servers over HTTPS instead of HTTP. You can identify whether a server supports HTTPS by simply changing \u201chttp:\/\/\u201d to \u201chttps:\/\/\u201d in your URL string and trying to load data from that website. You can check this manually in a browser, or run code as follows:<\/p>\n<pre class=\"code-source\"><code><span class=\"syntax-keyword\">let<\/span> request <span class=\"syntax-operator\">=<\/span> <span class=\"syntax-type\">URLRequest<\/span>(url: <span class=\"syntax-type\">URL<\/span>(string: \u201chttps:<\/code><\/pre>\n<p>Many websites redirect HTTP connections to HTTPS. Connecting over HTTPS first can often improve the performance of your app. Note, however, that while a website may use HTTPS, that doesn\u2019t mean it\u2019s ATS-compatible. For instance, it may be using an outdated version of TLS, which, on Safari, displays a \u201cThis Connection Is Not Private\u201d warning.<\/p>\n<div class=\"inline-article-image\"><img decoding=\"async\" src=\"https:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2022\/09\/fine-tune-your-app-transport-security-settings-2.jpg\" data-hires=\"false\" alt><\/div>\n<p><strong>Remove unnecessary exceptions<\/strong><br \/>\nOn websites where you no longer receive ATS runtime errors, you can remove those exceptions. Locate \u201cApp Transport Security Settings\u201d in your Info.plist and click the \u201c-\u201d icon to remove the exceptions in question.<\/p>\n<div class=\"inline-article-image\"><img decoding=\"async\" src=\"https:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2022\/09\/fine-tune-your-app-transport-security-settings-3.jpg\" data-hires=\"false\" alt><\/div>\n<h3>Configure exception domains<\/h3>\n<p>If your app still needs to make insecure connections to specific domains, you can configure ATS exceptions for just those domains.<\/p>\n<ul>\n<li>Add Exception Domains directly to your app\u2019s Info.plist or in the project editor. Navigate to \u201cSigning &amp; Capabilities\u201d and choose the \u201c+ Capability\u201d option.<\/li>\n<\/ul>\n<div class=\"inline-article-image\"><img decoding=\"async\" src=\"https:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2022\/09\/fine-tune-your-app-transport-security-settings-4.jpg\" data-hires=\"false\" alt><\/div>\n<ul>\n<li>Select \u201cApp Transport Security Exception\u201d from the list.<\/li>\n<\/ul>\n<div class=\"inline-article-image\"><img decoding=\"async\" src=\"https:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2022\/09\/fine-tune-your-app-transport-security-settings-5.jpg\" data-hires=\"false\" alt><\/div>\n<ul>\n<li>This will add an \u201cApp Transport Security Exception\u201d section to your capabilities:<\/li>\n<\/ul>\n<div class=\"inline-article-image\"><img decoding=\"async\" src=\"https:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2022\/09\/fine-tune-your-app-transport-security-settings-6.jpg\" data-hires=\"false\" alt><\/div>\n<ul>\n<li>Click the \u201c+\u201d icon to add domains that your app needs to connect to insecurely.<\/li>\n<li>Enter a domain here to connect over HTTP to that domain and its subdomains. If you need to alter these settings, you can make changes directly in your Info.plist.<\/li>\n<\/ul>\n<div class=\"inline-article-image\"><img decoding=\"async\" src=\"https:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2022\/09\/fine-tune-your-app-transport-security-settings-7.jpg\" data-hires=\"false\" alt><\/div>\n<h3>Configure framework and class exceptions<\/h3>\n<p>On rare occasion, you still may need to make an insecure connection to an unknown domain. In this case, there are two broader exceptions you can consider offering.<\/p>\n<ul>\n<li>If your app needs to make insecure connections through WKWebView, add \u201cAllows Arbitrary Loads In Web Content\u201d to your Info.plist:<\/li>\n<\/ul>\n<div class=\"inline-article-image\"><img decoding=\"async\" src=\"https:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2022\/09\/fine-tune-your-app-transport-security-settings-8.jpg\" data-hires=\"false\" alt><\/div>\n<ul>\n<li>If your app needs to make insecure connections through AVFoundation, add \u201cAllows Arbitrary Loads for Media\u201d:<\/li>\n<\/ul>\n<div class=\"inline-article-image\"><img decoding=\"async\" src=\"https:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2022\/09\/fine-tune-your-app-transport-security-settings-9.jpg\" data-hires=\"false\" alt><\/div>\n<p>These exceptions will ensure that your app only makes insecure connections via AVFoundation or WKWebView, leaving the rest of your app protected by ATS. Because these are relatively broad exceptions, however, they will allow every part of your app that uses AVFoundation or WKWebView to make insecure connections which can be intercepted and inspected.<\/p>\n<h3>Keep your app secure<\/h3>\n<p>People want to trust your app, and ATS can help you build that trust by handling their data responsibly while in transit. To get the most out of ATS:<\/p>\n<ul>\n<li>Make sure that your app connects to servers over HTTPS instead of HTTP.<\/li>\n<li>Tailor your ATS exceptions to your app as closely as possible.<\/li>\n<li>Periodically review your exceptions to check whether servers have started supporting HTTPS or your app no longer needs to connect those servers to make insecure connections.<\/li>\n<\/ul>\n<h3>Resources<\/h3>\n<section class=\"grid activity\">\n<section class=\"row\">\n<section class=\"column large-4 small-4 no-padding-top no-padding-bottom\"> <a href=\"https:\/\/developer.apple.com\/wwdc15\/711\" class=\"activity-image-link\"> <img decoding=\"async\" class=\"actiity-image medium-scale\" width=\"250\" src=\"https:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2022\/09\/fine-tune-your-app-transport-security-settings-10.jpg\" data-hires=\"false\" alt> <\/a> <\/section>\n<section class=\"column large-8 small-8 padding-left-small padding-top-small padding-bottom-small no-padding-top no-padding-bottom\"> <a href=\"https:\/\/developer.apple.com\/wwdc15\/711\"> <\/p>\n<h4 class=\"no-margin-bottom activity-title\">Networking with NSURLSession<\/h4>\n<p class=\"activity-description\">Learn about App Transport Security, HTTP\/2 protocol support, new NSURLSession API, and best practices for networking in apps, extensions, and WatchKit apps.<\/p>\n<p> <\/a> <\/section>\n<\/section>\n<\/section>\n<p><a href=\"https:\/\/developer.apple.com\/documentation\/bundleresources\/information_property_list\/nsapptransportsecurity\" class=\"icon icon-after icon-chevronright\">NSAppTransportSecurity<\/a><\/p>\n<p><a href=\"https:\/\/developer.apple.com\/documentation\/security\/preventing_insecure_network_connections\" class=\"icon icon-after icon-chevronright\">Preventing Insecure Network Connections<\/a><\/p>\n<p><a href=\"https:\/\/developer.apple.com\/documentation\/bundleresources\/information_property_list\/nsapptransportsecurity\/nsexceptiondomains\" class=\"icon icon-after icon-chevronright\">NSExceptionDomains<\/a><\/p>\n<p><a href=\"https:\/\/developer.apple.com\/documentation\/bundleresources\/information_property_list\/nsapptransportsecurity\/nsallowsarbitraryloadsformedia\" class=\"icon icon-after icon-chevronright\">NSAllowsArbitraryLoadsForMedia<\/a><\/p>\n<p><a href=\"https:\/\/developer.apple.com\/documentation\/bundleresources\/information_property_list\/nsapptransportsecurity\/nsallowsarbitraryloadsinwebcontent\" class=\"icon icon-after icon-chevronright\">NSAllowsArbitraryLoadsInWebContent<\/a><\/p>\n<p><a href=\"https:\/\/developer.apple.com\/documentation\/webkit\/wkwebview\" class=\"icon icon-after icon-chevronright\">WKWebView<\/a><\/p>\n<p><a href=\"https:\/\/developer.apple.com\/forums\/thread\/3544\" class=\"icon icon-after icon-chevronright\">Learn more about App Transport Security on the Developer Forums<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>At Apple, we believe privacy is a fundamental human right. When people connect to a public Wi-Fi hotspot, they expect to use your app to send and receive data without worrying that someone in the vicinity could intercept their connection and gain access to unencrypted data. Allowing even seemingly-innocuous data to remain unencrypted can expose [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":127827,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[55],"tags":[],"class_list":["post-127826","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-apple-developer-news"],"_links":{"self":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts\/127826","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/comments?post=127826"}],"version-history":[{"count":0,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts\/127826\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/media\/127827"}],"wp:attachment":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/media?parent=127826"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/categories?post=127826"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/tags?post=127826"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}