Edited at

Cordova で iOS9 App Transport Security を回避する

More than 3 years have passed since last update.


App Transport Security(ATS) とは

Apple のサーバ側セキュリティ基準。

Apple 基準を満たしていない場合、サーバ接続できず、 An SSL error has occurred and a secure connection to the server cannot be made. みたいなエラーが出る。


設定で回避


hook を作成

設定で回避できるため、Hooks Guide - Apache Cordova を使い設定を追加する。

hook は Cordova で提供されている、特定のタイミングでコードを実行できる仕組み。

今回は after_prepare に shell を書いた。


project_root/hooks/after_prepare/ios9-transport-security.sh

#!/bin/bash

PLIST=platforms/ios/*/*-Info.plist

cat << EOF |
Add :NSAppTransportSecurity dict
Add :NSAppTransportSecurity:NSExceptionDomains dict
Add :NSAppTransportSecurity:NSExceptionDomains:dev.example.com dict
Add :NSAppTransportSecurity:NSExceptionDomains:dev.example.com:NSExceptionAllowsInsecureHTTPLoads bool YES
Add :NSAppTransportSecurity:NSExceptionDomains:dev.example.com:NSExceptionRequiresForwardSecrecy bool NO
Add :NSAppTransportSecurity:NSExceptionDomains:dev.example.com:NSExceptionMinimumTLSVersion string TLSv1.0
Add :NSAppTransportSecurity:NSExceptionDomains:production.example.com dict
Add :NSAppTransportSecurity:NSExceptionDomains:production.example.com:NSExceptionAllowsInsecureHTTPLoads bool YES
Add :NSAppTransportSecurity:NSExceptionDomains:production.example.com:NSExceptionRequiresForwardSecrecy bool NO
Add :NSAppTransportSecurity:NSExceptionDomains:production.example.com:NSExceptionMinimumTLSVersion string TLSv1.0
EOF
while read line
do
/usr/libexec/PlistBuddy -c "$line" $PLIST
done

true

なお、 config.xml には 以下の whitelist を設定してある。

  <access origin="http://*.example.com"/>

<access origin="https://*.example.com"/>


cordova prepare 後の info.plist の結果

..略..

<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>example.com</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
<key>dev.example.com</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.0</string>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
</dict>
<key>production.example.com</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.0</string>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
</dict>
</dict>
</dict>
..略..


Plugin で回避もできる?

leecrossley/cordova-plugin-transport-security という plugin も出ていて、 NSExceptionAllowsInsecureHTTPLoads だけだったらこれで設定できる。

ただし自分の場合は、特定の URL だけの設定をしたかったので、上記 Plugin ではダメだった。


hook を作った理由

Plugin に NSExceptionDomains の設定を書くと、access origin と競合してしまうようで、 access origin が優先して上書きしてしまう?ような現象が起きた。

これでだいぶ時間がかかってしまった。

本来ならば Plugin に <config-file target="*-Info.plist" parent="NSAppTransportSecurity"> を書くのが筋だと思う、ただそうするとうまくいかなかったので shell を書いた次第。