Ошибка в iOS 9 при использовании клиентских SSL-сертификатов и генерации ошибок HTTP 403

Я думаю, что мы только что обнаружили ошибку в iOS 9 (версия от 23 октября 2015 года) при использовании клиентских SSL-сертификатов для взаимодействия с внутренним API. Как и многие службы REST, наш API генерирует коды ошибок 4xx для сообщения о состоянии. Одной из них является ошибка 403 Forbidden, когда клиент пытается получить доступ к путям, к которым не имеет доступа определенный идентификатор клиента. Обратите внимание, что эта ошибка HTTP возникает ПОСЛЕ того, как сертификат SSL клиента установил действительное соединение и идентификатор клиента был аутентифицирован.

В iOS 9 эта последовательность вызовет недопустимую ошибку SSL клиента:

FAILED: Error Domain=NSURLErrorDomain Code=-1206 "The server “our.server.here” requires a client certificate."

(примечание: это продолжение моего твита здесь: https://twitter.com/ckmaresca/status/657576686318256128 - я подумал, что большинство людей будут искать это именно на SO)




Ответы (1)


Нам потребовались дни, чтобы окончательно понять, но оказалось, что эта конкретная ошибка генерируется новой системой безопасности Apple Application Transport Layer. В частности, кажется, что если вы используете клиентские сертификаты, а ваш серверный API генерирует ошибку HTTP 403, ATL считает, что сертификат неисправен, и уничтожает всю транзакцию.

Мы знаем это, потому что мы можем видеть в журналах нашего сервера, что запрос проходит и выполняется правильно. Мы также заметили, что сокет остается активным через запрос, и эта ошибка появляется только после получения ответа от сервера. Мы также знаем, что наш клиентский сертификат работает, поскольку любой путь, не возвращающий 403, работает с нулевыми ошибками, а изменение кода ошибки HTTP на 401 устраняет эту проблему.

Это проблематично по ряду причин, но в основном потому, что ошибки HTTP не являются ошибками SSL. Они могут работать независимо друг от друга, и вполне возможно получить ошибку 403 с действительным SSL-сертификатом на стороне клиента....

Обходной путь заключается в том, чтобы изменить все ваши ошибки 403 на что-то другое. Я хотел бы отметить, что большое количество серверов Oauth1/2 будут генерировать различные ошибки 403, поэтому это может быть нетривиально. В качестве альтернативы можно использовать обратный прокси-сервер для переназначения ошибок HTTP 403 на другой код HTTP — мы не проверяли это.

Мы сообщили об ошибке в Apple, но я хотел предупредить людей, чтобы они могли не биться головой о стену, как это делали мы в течение недели....

Спасибо команде разработчиков Sherbit.io (в частности, Варуну и Мэтту) за отладку.

person ckm    schedule 23.10.2015
comment
Привет, @ckm, у меня точно такая же проблема, и я потратил на нее несколько дней. Какое решение вы в итоге использовали? Я не могу контролировать сервер, чтобы он не возвращал 403. :( Вы нашли какой-нибудь обходной путь? - person Raphael Oliveira; 06.04.2016
comment
Можете ли вы также вставить ссылку rdar, пожалуйста? - person Raphael Oliveira; 06.04.2016
comment
@ckm, у нас все еще та же проблема, какие-нибудь новости о радаре? - person Chandra; 11.10.2017
comment
Нет обновлений, извините. Ошибка все еще присутствует в iOS10/11? Мы решили эту проблему, изменив код ошибки HTTP при возврате. - person ckm; 12.10.2017
comment
Было бы здорово узнать, решена ли эта проблема в iOS 10/11. - person Orion Edwards; 01.03.2018
comment
Я не знаю, извините. Это довольно легко проверить, если вы разрабатываете приложения для iOS и имеете доступ к веб-серверу.... - person ckm; 02.03.2018
comment
Спасибо, @ckm. Мы сталкиваемся с той же проблемой в iOS 13.4. Apple до сих пор не исправила ошибку. Как только мы заменяем код 403 при возврате, приложение для iOS работает нормально. - person SamBundy; 06.04.2020
comment
Я столкнулся с той же проблемой. Но мой запрос не достигает сервера API, вместо этого он терпит неудачу на конце устройства, и он показывает то же самое, что требует ошибки сертификата клиента. Любая помощь в этом? - person Ashok; 05.05.2020
comment
@ashok, извините за поздний ответ, только что увидел это. Я бы предложил разбить транзакцию, как я описал во втором абзаце, и протестировать все, регистрируя как можно больше подробностей. Также проверьте все прокси или WAF, которые могут быть между API и клиентским устройством. - person ckm; 16.11.2020