安全传输阻止了明文HTTP的请求

1597

我需要在我的info.plist中设置什么才能按照以下错误信息启用HTTP模式?

传输安全性已阻止了明文HTTP(http://)资源的加载,因为它是不安全的。临时例外可以通过您的应用程序的Info.plist文件进行配置。

Xcode

假设我的域名是example.com


1
https://dev59.com/El0Z5IYBdhLWcg3wphsE#31629980 - Tom Howard
24
主持人提示:这个问题已经有36个答案了。在添加新答案之前,请确保您的解决方案是全新的。 - Matt
6
注意:这里的解决方案建议您关闭ATS(允许任意加载)。但很快这将不再可能,因为苹果将要求ATS(最初的截止日期是年底,现已延长)。-https://developer.apple.com/news/?id=12212016b - Jakub Truhlář
https://firebase.google.com/docs/admob/ios/app-transport-security - Alex1987
@Jeef 为什么你添加了iOS 10的标签?在iOS 10中有任何其他更改吗?我认为它是在iOS9中引入的,那个标签应该足以涵盖iOS版本方面的内容。 - Julian
30个回答

1015

使用NSAppTransportSecurity:

您需要在info.plist文件的NSAppTransportSecurity字典下将NSAllowsArbitraryLoads设置为YES

Enter image description here

Plist configuration


173
请注意:这是一个解决方法!如果您在使用HTTP而非HTTPS时,会给用户设备带来漏洞。虽然在许多情况下可能性不大,但遵循道德编程是最佳实践。只是提一下......此外,为测试目的工作良好。(+1) - Jacksonkr
43
这不是一个解决方案,而是一个黑客技巧!如果要添加单独的域名“例外”,请参见下面的答案:https://dev59.com/o10Z5IYBdhLWcg3wnBb_#32560433。 - DiscDev
21
虽然这个解决方案已知存在漏洞,但在开发期间,这是我唯一会建议的解决方案。在开发过程中必须输入每个精确的域名是有些愚蠢的(特别是如果你在使用第三方网络服务)。 - reTs
6
这些键的名称现在已更改为“应用程序传输安全设置”,其中包括“允许任意载荷”。 - vishal dharankar
16
为什么这个方案会遭到如此多的反对?它绝对不是黑客攻击!许多应用程序需要与实际的互联网通信,而安全协议并不总是在您的控制之下。例如,从没有 SSL 证书的其他服务器显示图像似乎非常合理。 - Oren
显示剩余14条评论

856
这里是可视化的设置:

通过Xcode GUI在info.plist中使用NSAllowsArbitraryLoads的可视化设置


12
我没有那个选项。 - User
26
如果您直接打开Info.plist文件,您可以添加NSAppTransportSecurity字典,然后在其中创建NSAllowsArbitraryLoads项(请参见下面由Umar Farooq编辑的答案)。 - Stoph
3
我也遇到了同样的问题——在7.3版本中,例外域名对我无效。 - RegularExpression
4
这个选项不存在 - XCode 7.3.1。 - jameshfisher
3
@JoshPinter提供的信息对我在XCode 8上奏效了。 - Matthew Bellantoni
显示剩余13条评论

769

请参阅论坛帖子Application Transport Security?

例如,您可以添加特定的域名,如:

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSExceptionDomains</key>
  <dict>
    <key>example.com</key>
    <dict>
      <!--Include to allow subdomains-->
      <key>NSIncludesSubdomains</key>
      <true/>
      <!--Include to allow HTTP requests-->
      <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
      <true/>
      <!--Include to specify minimum TLS version-->
      <key>NSTemporaryExceptionMinimumTLSVersion</key>
      <string>TLSv1.1</string>
    </dict>
  </dict>
</dict>

懒人选项是:

<key>NSAppTransportSecurity</key>
<dict>
  <!--Include to allow all connections (DANGER)-->
  <key>NSAllowsArbitraryLoads</key>
      <true/>
</dict>

###注意:

info.plist是一个XML文件,所以您可以将此代码放置在文件的任何位置。


2
@lmiguelvargasf,请在纯文本编辑器中打开您的info.plist文件。 - Dan Beaulieu
1
可能最好展示官方的苹果文档:https://developer.apple.com/library/prerelease/ios/technotes/App-Transport-Security-Technote/ - hris.to
9
即使将NSAllowsArbitraryLoads设置为true,我仍然会收到错误信息:异常域已设置且NSAllowsArbitraryLoads为false。这个错误还会出现。这里还有其他人遇到过这个问题吗? - klaevv
3
截至2016年1月30日,苹果文档显示键值不再带有“Temporary”一词,例如: NSExceptionAllowsInsecureHTTPLoads NSExceptionMinimumTLSVersion 请参见https://developer.apple.com/library/prerelease/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html。 - Philippe Monnet
3
如果有人因为对info.plist进行这些简单更改而感到困惑,请将更改添加到Project>Target>Info>Custom iOS Target Properties中。 - BlueGuy
显示剩余11条评论

597
如果您正在使用Xcode 8.0+和Swift 2.2+甚至Objective C: 在这里输入图片描述 如果您想允许对任何站点的HTTP连接,则可以使用以下键:
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

如果您知道要连接的域名,请添加:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>example.com</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSIncludesSubdomains</key>
            <true/>
        </dict>
    </dict>
</dict>

35
为什么NSAllowsArbitraryLoads被设置成了true?这样会破坏ATS的目的。同时请参考世界上最危险的代码:在非浏览器软件中验证SSL证书。你的软件刚刚入选了名单。 - jww
8
这是本篇文章的目的。我需要连接到播放音频的网站,但该网站尚未使用 HTTPS 协议,我不想等待。 - ThinkDigital
7
这在 iOS 10.0+ 或 MacOS 10.12+ 中无法运行。 实际上,它要求允许所有任意加载,除了那些被提及的(例如:example.com)。因此,它会产生相反于所期望结果的效果。 这里应将 NSAllowsArbitraryLoads 设置为 false。更多信息请参见:Apple文档 - Freek Sanders
1
同意,为什么所有人都要点赞这个?如果您设置了例外域名,使用NSAllowsArbitraryLoads就没有意义了。 - thibaut noah
1
NSAllowsArbitraryLoads 不需要为 true,因此必须将其删除。NSExceptionDomains 足以仅启用与该域的非安全连接。NSAllowsArbitraryLoads = true 将启用与任何域的非安全连接,因此如果仍将其设置为 true,则 NSExceptionDomains 就没有意义了,因为它已经包括所有域。 - mister_giga
可以在 Swift 5 上平稳运行。 - Alan Silva

356

这已经经过测试并在iOS 9 GM种子版上运行良好 - 这是允许一个特定域使用HTTP而不是HTTPS的配置:

<key>NSAppTransportSecurity</key>
<dict>
      <key>NSAllowsArbitraryLoads</key> 
      <false/>
       <key>NSExceptionDomains</key>
       <dict>
            <key>example.com</key> <!--Include your domain at this line -->
            <dict>
                <key>NSIncludesSubdomains</key>
                <true/>
                <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
                <true/>
                <key>NSTemporaryExceptionMinimumTLSVersion</key>
                <string>TLSv1.1</string>
            </dict>
       </dict>
</dict>

NSAllowsArbitraryLoads必须为false,因为它禁止所有不安全连接,但例外列表允许连接到某些没有 HTTPS 的域。

这里是可视化的结构图:

Info.plist structure


7
应将此标记为答案。经测试,在iOS 9 GM种子上正常工作,允许特定域使用HTTP而不是采取“懒惰”的方式完全开放您的应用程序。 - DiscDev
2
我该如何将此添加到我的info.plist文件中? - JMStudios.jrichardson
8
好的,我已经将该条目添加到我的info.plist中,但仍然出现以下错误提示 - “应用传输安全性已阻止明文HTTP(http://)资源加载,因为它是不安全的。可以通过您的应用程序的Info.plist文件配置临时例外。” - KMC
2
如果你必须使用IP地址,请尝试在IP地址末尾添加".xip.io",并将"xip.io"添加到你的NSExceptionDomains中。请参见http://xip.io。我在开发时(但不是发布时)直接连接IP,这对我非常有效。 - tpankake
3
直到意识到我把它放到了测试项目的错误 info.plist 中,它才对我起作用。确保将其放到正确的 info.plist 中! - Chucky
显示剩余9条评论

151
这是一种快速解决方法(但不建议使用)来在plist中添加此内容的方法:
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

这意味着(根据苹果文档):
NSAllowsArbitraryLoads 一个布尔值,用于禁用任何未列在NSExceptionDomains字典中的域名的App Transport Security。列出的域使用该域指定的设置。
默认值为NO,对所有连接都需要默认的App Transport Security行为。
我真的推荐链接:

这些将帮助我理解原因和所有影响。

下面的XML(在Info.plist文件中)将:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <false/>
    <key>NSExceptionDomains</key>
    <dict>
        <key>PAGE_FOR_WHICH_SETTINGS_YOU_WANT_TO_OVERRIDE</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>

禁止所有页面进行任意调用,但对于PAGE_FOR_WHICH_SETTINGS_YOU_WANT_TO_OVERRIDE,将允许连接使用HTTP协议。

您可以在上述XML中添加:

<key>NSIncludesSubdomains</key>
<true/>

如果你想允许指定地址的子域名使用不安全连接,最好的方法是阻止所有任意载入(设置为false),并添加例外以仅允许我们知道安全的地址。对于感兴趣的读者请参考2018更新: 苹果不建议关闭此功能-更多信息可以在207 session WWDC 2018中找到,有关安全的更多内容也在其中解释。
出于历史原因和开发阶段的考虑,我们保留原始答案。

1
NSAllowsArbitraryLoads 必须为 false - Sound Blaster
@SoundBlaster,你为什么要给我点踩呢?请问我的回答有什么问题吗? - Julian
通过在plist(NSAppTransportSecurity NSAllowsArbitraryLoads)中添加,所有的Web服务都可以正常工作,除了一个Web服务,在iOS 9中返回内部服务器错误(500),但在iOS8或更高版本中可以正常工作。 - amit gupta
@SoundBlaster做了一个更改,现在你不应该有任何异议了 :) - Julian
谢谢,你怎么实际添加<key>NSIncludesSubdomains</key><true/>?每个设置都必须用<dict>包围吗?你怎么编辑这个该死的plist文件?格式是什么样的?:D 谢谢。 - Agent Zebra

120

对于那些想要更多了解为什么会发生这种情况的人,以及如何解决,可以继续阅读下面的内容。

随着 iOS 9 的推出,为了改善应用和 Web 服务之间的连接安全性,应用与其 Web 服务之间的安全连接必须遵循最佳实践。 App Transport Security 强制执行最佳实践行为,以:

  • 预防意外泄露,以及
  • 提供默认的安全行为。

App Transport Security 技术说明 中所述,在与您的 Web 服务通信时,App Transport Security 现在具有以下要求和行为:

  
      
  • 服务器必须支持至少传输层安全性(TLS)协议版本1.2。
  •   
  • 连接密码限制为提供前向保密性的密码(请参见下面的密码列表)。
  •   
  • 证书必须使用 SHA256 或更好的签名哈希算法进行签名,并使用 2048 比特或更大的 RSA 密钥或 256 比特或更大的椭圆曲线(ECC)密钥。
  •   
  • 无效证书导致严重故障和无连接。
  •   

换句话说,您的 Web 服务请求应该:a.) 使用 HTTPS,b.) 使用 TLS v1.2 进行加密,并具有前向保密性。

然而,正如其他帖子中提到的那样,您可以通过在应用程序的Info.plist中指定不安全的域来覆盖 App Transport Security 的新行为。


要进行覆盖,您需要将 NSAppTransportSecurity > NSExceptionDomains 字典属性添加到您的 Info.plist 中。接下来,您将把您的 Web 服务所在的域添加到 NSExceptionDomains 字典中。

例如,如果我想要绕过位于主机www.yourwebservicehost.com 上的 Web 服务的 App Transport Security 行为,那么我将执行以下操作:

  1. 在 Xcode 中打开您的应用程序。

  2. 在 Project Navigator 中找到 Info.plist 文件,在其上“右键”单击,然后选择Open As > Source Code 菜单选项。属性列表文件将出现在右侧窗格中。

  3. 将以下属性块放置在主要属性字典中(第一个<dict>下)中。


<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>www.example.com</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSExceptionMinimumTLSVersion</key>
            <string>TLSv1.1</string>
            <key>NSIncludesSubdomains</key>
            <true/>
        </dict>
    </dict>
</dict>
如果您需要为其他域名提供异常情况,那么您可以在NSExceptionDomains下方添加另一个字典属性。
要了解上述键的更多信息,请阅读此技术说明

1
这在我的两个应用程序中有效,但在第三个应用程序中无法正常工作。还有其他人遇到过使用上述修复方法仍然收到相同错误信息的情况吗?(是的,我已更新字典以使用我的 API 域,而不是代码中的域) - helloB
最好!苹果确认此解决方案使用 - YannSteph
这适用于Cordova/Phonegap/Ionic应用程序,编辑文件./platforms/ios/<project>/<project>-Info.plist,其中包含NSAllowsArbitraryLoads=false和许多例外域到具有不同TLS/HTTP/HTTPS组合的服务。最初使用了NSAllowsArbitraryLoads=true,然后通过试错排除规则来调整,以符合指南并提交审批。请注意,config.xml <access origin=.../>语句部分填充此文件,但目前需要通过直接编辑或通过XCode进行调整以获取正确的详细信息。 - jimmont
同时 <access origin="*"/>(在config.xml中)设置了 NSAllowsArbitraryLoads=true(适用于Cordova/Phonegap/hybrid应用程序)。 - jimmont
为什么要将 NSExceptionAllowsInsecureHTTPLoads 设置为 true?这会破坏 ATS 的目的。同时请参考 The most dangerous code in the world: validating SSL certificates in non-browser software。你的软件刚刚被列入其中。 - jww

70

我不喜欢直接编辑plist文件。你可以用图形界面轻松地将其添加到plist中:

  • 在左侧的导航器中点击Info.plist。
  • 现在更改主区域中的数据:

    • 在最后一行添加+
    • 输入组名:App Transport Security Settings
    • 右键单击该组,然后选择添加行
    • 输入Allow Arbitrary Loads
    • 将右边的值设置为YES

示例


请澄清:如果“允许任意加载”为YES,并且存在“例外域”,则允许的加载将限制为“例外域”中的加载。这正确吗? - user3821934
如果我想发布应用程序,那么这是一种安全的方法吗? - Lamour
为什么将 NSAllowsArbitraryLoads 设置为 YES?这会逆转ATS的目的。另请参见《世界上最危险的代码:在非浏览器软件中验证SSL证书》(http://crypto.stanford.edu/~dabo/pubs/abstracts/ssl-client-bugs.html)。你的软件刚刚上了名单。 - jww
有时候你需要访问一个非安全的网站。在这种情况下,你可以使用上面的代码。在其他所有情况下,建议使用SSL。 - Vincent
我已经在多个项目中实现了这个功能,全部都能正常工作。您能否提供更多关于您的情况的信息? - Vincent
显示剩余2条评论

29

苹果文档1

苹果文档2

有两种解决方案:

解决方案1:

  1. Info.plist 文件中添加一个键为 'NSAppTransportSecurity' 的字典
  2. 在字典内添加另一个元素,键为 'Allow Arbitrary Loads'

Plist 结构应如下图所示。

解决方案1

解决方案2:

  1. Info.plist 文件中添加一个键为 'NSAppTransportSecurity' 的字典
  2. 在字典内添加另一个元素,键为 'NSExceptionDomains'
  3. 添加一个类型为 NSDictionary、键为 'MyDomainName.com' 的元素
  4. 添加一个类型为 Boolean,键为 'NSIncludesSubdomains',值为 YES 的元素
  5. 添加一个类型为 Boolean,键为 'NSTemporaryExceptionAllowsInsecureHTTPLoads',值为 YES 的元素

Plist 结构应如下图所示。

解决方案2

解决方案2 更可取,因为它仅允许选定的域名,而解决方案1 则允许所有不安全的 HTTP 连接。


为什么要将NSAllowsArbitraryLoads设置为YES?这会破坏ATS的目的。另请参见全球最危险的代码:在非浏览器软件中验证SSL证书。你的软件刚刚上了列表。 - jww

22

⛔️ 不要使用不良实践!

许多答案(包括被接受的答案)告诉你通过将“允许任意加载”设置为“是”(或“true”),完全不加保护地进行应用程序的网络通信!那是最危险的网络请求设置!而且它仅限于测试和临时目的。

您可以在 WWDC18 中看到这位苹果工程师明确表态,即使对于 Web 内容,您也正在尝试允许所有这些内容! enter image description here


✅ 将“允许任意加载”设置为“NO”!!!

您必须始终为您的网络事务使用HTTPS。但如果您真的无法这样做,只需向info.plist添加一个异常即可。

例如,如果您正在使用 http://google.com 并得到该错误,您必须将其改为支持 HTTPS 的 https://google.com(加上s)。

但如果你无法这样做(并且你无法说服后端开发人员支持 SSL),只需将此未加保护的域添加到 info.plist 中即可(而不是使其对于所有未加保护的网络!

异常


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接