Как обеспечить доступ к моему веб-сервису только из моего кода? - PullRequest
9 голосов
/ 11 мая 2009

Я пишу очень простой веб-сервис для моего приложения для iPhone. Допустим, это http-страница, которая возвращает случайное число в http://mysite/getRand.. Как мне обеспечить доступ к этой странице только из моего приложения для iPhone, а не из других клиентов? Я думал о создании некоторого простого механизма паролей, но его легко можно прослушать, захватив то, что отправляет мое приложение.

Причина этого в том, чтобы снизить нагрузку на мой сервер, разрешив только допустимые запросы.

Ответы [ 9 ]

11 голосов
/ 11 мая 2009

Вы не можете этого сделать. Ваше приложение может быть дизассемблировано, и любой секрет в двоичном файле может быть скопирован во вредоносное приложение.

Еще одна атака, о которой вы должны знать, это то, что люди устанавливают файл hosts в расположение, которым они управляют, а затем устанавливают корневой сертификат, который позволяет им предоставлять подпись для этого домена. Ваша заявка отправит сообщение с секретом, и они смогут прочитать секрет. Таким образом, они могут извлечь пароль из любой сложной системы шифрования в двоичном файле.

Большинство идей в этой теме уязвимы для этой атаки.

Тем не менее, вероятность того, что кто-то позаботится о том, чтобы разобрать ваше приложение, вероятно, довольно мала.

Я бы просто все упростил. У вас есть пароль, который жестко запрограммирован в вашем приложении. Чтобы кто-то просто смотрел на ресурсы и пробовал каждую строку, сделайте это XOR двух строк или результат AES-дешифрования определенной фиксированной строки.

Очевидно, вы должны выполнить запрос через SSL, иначе злоумышленник может просто прослушать трафик.

Да, решительный злоумышленник обойдет схему, но, как и любая схема DRM, так было всегда. Хитрость в том, чтобы приложить слишком много усилий, чтобы стоить того.

2 голосов
/ 11 мая 2009

Чтобы продолжить идею Саймона, вы могли бы очень легко иметь строку ключа в своем приложении, затем отправить идентификатор устройства и затем DeviceID XOR (или другой простой алгоритм для шифрования строки) с вашей строкой ключа.

Поскольку вы знаете значение ключа для использования, для вас тривиально «расшифровать» эту строку на стороне сервера и убедиться, что значения совпадают.

Таким образом, пароль различен для каждого устройства пользователя, и строка «ключа» никогда не передается по проводам великих немытых интернетов. : -)

Да, это отнюдь не невозможно понять, но, как говорили другие, идея состоит в том, чтобы не сделать это невозможным. Идея состоит в том, чтобы сделать это больше проблем, чем стоит.

1 голос
/ 12 мая 2009

Вот одна мысль - отправьте идентификатор устройства вместе с запросами из вашего приложения.

Отслеживайте используемый идентификатор устройства - если вы видите тонну запросов с разных IP-адресов рядом или одновременно, это устройство, вероятно, используется в качестве фиксированного ключа в отправленных вам запросах - заблокируйте его.

Для тех, кто действительно отправляет реальный идентификатор устройства из других приложений (не из ваших), вы можете отслеживать тенденции использования, чтобы увидеть, соответствуют ли вызовы тому, как работает ваше приложение - например, один вызов используется устройством перед некоторой инициализацией вызов, который вы обычно ожидаете, и так далее - блокируйте их тоже.

По сути, имея возможность изменять правила в зависимости от модели использования, вы можете лучше приспособиться к тому, кто пытается использовать ваш сервис, убедившись, что это не фиксированная цель, как некоторые случайные ключи использования.

Вы также можете использовать простой ключ использования, а также первую линию защиты, а затем слой на подходе анализа трафика. Кроме того, пользовательские значения заголовка http, которые вы ищете, являются еще одним простым способом сбить с толку наивного злоумышленника.

1 голос
/ 11 мая 2009

Я предполагаю, что вы не хотите использовать SSL? Если вы это сделаете, то можете открыть сеанс HTTPS, а затем передать в запросе какой-нибудь секретный ключ.

Если вы не хотите использовать SSL, ваши возможности ограничены: для обеспечения псевдобезопасности я предлагаю и методы аутентификации и авторизации, и третий, чтобы уменьшить общий трафик:

Аутентификация: генератор в клиентском приложении, который создает секретные ключи путем объединения с файлом ключей. Файл ключа может обновляться часто для большей безопасности: допустим, вы обновляете файл ключа один раз в неделю. Подчеркнем: Генератор объединяет секрет приложения с файлом ключа вне приложения, чтобы сгенерировать третий ключ для передачи, используемой при аутентификации. После этого сервер сможет аутентифицироваться.

Авторизация: Конечно, вы также хотите заблокировать мошеннические приложения. Здесь было бы лучше иметь механизм авторизации с сайтом. Не заменяйте ключевые файлы, если клиент не входит в систему. Отслеживайте ключевые файлы для пользователей. и т.д.

Сокращение трафика: Если вы получаете непристойный объем трафика или подозреваете, что кто-то пытается использовать DOS на вашем сервере, вы также можете синхронизировать сервер и клиенты с запросом / ответом по процедурно сгенерированному URL, который может часто меняться. Открывать / закрывать так много сеансов HTTPS расточительно, если кто-то просто наводняет вас запросами.

1 голос
/ 11 мая 2009

Я бы тоже использовал протокол https с ключами на стороне клиента. Вы можете использовать один клиентский ключ для каждого или даже создать отдельный ключ для каждого клиента и «зарегистрировать» их на своем сервере.

Я полагаю, что для небольшого проекта много работы, но, если вам нужна аутентификация, это кажется правильным решением.

Вы должны убедиться, что владелец мобильного телефона не видит ключи. И помните, что кто-нибудь сможет взломать его в любом случае.

0 голосов
/ 12 мая 2009

Как указывалось в некоторых ответах, закрытие вашего веб-сервиса для всех остальных будет большой проблемой. Лучшее, на что вы можете надеяться, - это сделать так, чтобы хакерам было проще использовать другой веб-сервис, чем использовать ваш ...

Другим предложением для этого является генерация случайных чисел из random seed как на сервере, так и на клиенте. Сервер должен отслеживать, где в последовательности случайных чисел находятся все клиенты, и сопоставлять это число с номером, отправленным клиентом.

Клиенту также необходимо зарегистрироваться, чтобы получить доступ к серверу. Это также послужит механизмом аутентификации.

Итак:

//Client code:
$sequence = file_get_contents('sequence.txt');
$seed = file_get_contents('seed.txt');
$sequence++;

//Generate the $sequence-th random number
srand($seed);
for ($i = 0; $i <= $sequence; $i++) {
    $num = rand();
}
//custom fetch function
get_info($main_url . '?num=' . $num . '&id' = $my_id);

Это сгенерирует запрос, подобный этому:

http://webservice.com/get_info.php?num=3489347&id=3

//Server Code: (I'm used to PHP)

//Get the ID and the random number
$id = (int)$_REQUEST['id'];
$rand = (int)$_REQUEST['num'];
$stmt = $db->prepare('SELECT `sequence`, `seed` FROM `client_list` WHERE `id` = :id');
if ($stmt->execute(array(':id' => $id)) {
    list($sequence, $seed) = $stmt->fetch(PDO::FETCH_ASSOC);
}
$sequence++;

//Generate the $sequence-th random number
srand($seed);
for ($i = 0; $i <= $sequence; $i++) {
    $num = rand();
}
if ($num == $rand) {
    //Allow Access
} else {
    //Deny Access
}

Используя разные начальные числа для каждого клиента, вы гарантируете, что хакеры не могут предсказать случайное число, отслеживая предыдущие использованные числа.

0 голосов
/ 11 мая 2009

Я не являюсь разработчиком Cocoa Touch, но я думаю, что аутентификацию HTTP по SSL было бы легко реализовать, и, вероятно, это именно то, что вы ищете.

Все, что вам нужно сделать, это настроить HTTP-аутентификацию на стороне сервера (вы не упомянули, что вы используете на стороне сервера) и создать самоподписанный сертификат SSL на своем веб-сервере. Готово. :)

Расскажите нам больше о своей настройке, и мы сможем помочь вам в дальнейшем.

0 голосов
/ 11 мая 2009

Вы можете сделать что-то вроде шифрования текущего времени и IP-адреса с iPhone, а затем расшифровать их на сервере. Недостатком является то, что вам нужно, чтобы приложение для iPhone знало «секретный» ключ, чтобы только оно могло генерировать действительные токены доступа ... и как только ключ окажется в открытом доступе, его взлом будет только вопросом времени, если приложение действительно стоит усилий.

Вы можете зашифровать ответ, используя некоторую случайную часть приложения, которая предназначена для его использования, указав расположение двоичного файла в незашифрованном бите ответа. Тогда, по крайней мере, только клиенты, имеющие доступ к вашему двоичному файлу, смогут расшифровать его ... но опять же, это вряд ли на 100% безопасно.

В конечном итоге вам нужно спросить себя, сколько усилий вы хотите приложить для обеспечения безопасности сервиса, и сколько усилий, по вашему мнению, хакеры приложат для его злоупотребления.

0 голосов
/ 11 мая 2009

Я не уверен, какую веб-технологию вы используете, но если вы используете Ruby on Rails, он использует секретный маркер аутентификации во всех своих контроллерах, чтобы убедиться, что вредоносный код не получает разрушительные методы (через POST или DELETE). Вам нужно будет отправить этот токен аутентификации на сервер в теле запроса, чтобы он мог выполняться. Это должно достичь того, что, я думаю, вы ищете.

Если вы не используете Ruby on Rails, этот метод проверки подлинности кода может быть полезен для исследования и внедрения любых технологий, которые вы используете.

Взгляните на Руководство по безопасности Rails , в частности, раздел 3.1 (Контрмеры CSRF).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...