Защита вашего уровня данных в приложении C # - PullRequest
12 голосов
/ 01 августа 2009

Я думал о том, как защитить Уровень данных в Приложении C #, уровень в этом случае мог быть или Схемой модели LINQ to SQL, сохраненной с самим Приложением, связывающимся со строкой соединения с Базой данных SQL Server.

Или это может быть соединение между приложением и веб-сервисами.

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

Итак, мой вопрос вкратце: Как вы решаете проблемы безопасности при обработке веб-сервисов и / или прямом подключении к SQL Server из приложения Windows Forms?

Ответы [ 12 ]

14 голосов
/ 01 августа 2009

В вашем случае есть две основные возможности атаки:

  • Украсть строку подключения и затем напрямую обратиться к базе данных
  • Вызов методов в вашем коде C # напрямую без использования интерфейса

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

Для прямого доступа к коду вы можете использовать защиту доступа к коду и запутывание.

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

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

Приложение для Windows с 3 слоями:

  • UI
  • Business (проверка безопасности, какой пользовательский интерфейс должен быть показан пользователю)
  • Proxy

Служба WCF с 2 слоями:

  • Фасад / Бизнес-уровень (проверка безопасности позволяет пользователю вызывать этот метод с этими данными)
  • Модель данных Entity Framework

Общие DLL для обоих слоев

  • Контракты / интерфейсы WCF
  • Объекты передачи данных

Информацию о прокси, контрактах и ​​DTO смотрите в этом видео:

http://www.dnrtv.com/default.aspx?showNum=103

4 голосов
/ 03 августа 2009

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

Да, вы хотите, чтобы доступ к базе данных осуществлялся через промежуточный уровень, предоставляемый через WCF, который навязывает любую бизнес-логику, которую вам требуется, включая полный контроль доступа. У этой службы есть строка подключения, которую вы хотите сохранить в секрете, но она недоступна для клиентов WinForm.

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

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

Надеюсь, этот подход будет полезен для решения вашей проблемы.

1012 * редактировать *

Это решение не допускает LINQ-to-SQL на клиенте, только средний уровень. Если это нарушитель, то это не для вас. Опять же, в тот момент, когда клиент может получить доступ к базе данных напрямую, открывается гигантская дверь безопасности, и ее трудно закрыть. Огромная дополнительная работа связана с защитой самой базы данных, так что она обеспечивает своего рода защиту на уровне строк, основанную на пользователях, которая естественным образом обеспечивается трехуровневым решением. Я бы вообще рекомендовал против этого, хотя я признаю, что бывают случаи, когда это совершенно уместно.

3 голосов
/ 01 августа 2009

Один из способов - использовать Доверенное соединение с SQL Server , чтобы вы не сохраняли имя пользователя / пароль в коде.

2 голосов
/ 03 августа 2009

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

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

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

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

Аутентификация

Вы можете использовать стандартную аутентификацию .NET, как предложил Стивен. Я обычно предпочитаю использовать собственное решение по двум причинам. Прежде всего, до сих пор я в основном работал с более сложными пользователями / ролями. Например, использование ролей на основе разрешений, чтобы вы могли проверять наличие разрешений вместо конкретных ролей.

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

Также вот некоторые SO темы о авторизации WCF, которые могут быть интересны: Шаблоны авторизации службы WCF Авторизация и аутентификация с использованием WCF Авторизация WCF - доступ к операциям через заявки А также книга и бумага (не бесплатно)

Изоляция

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

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

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

Если данные распределяются между пользователями, вам потребуется какой-либо способ проверки ввода, который дается от пользователя. Желательно, чтобы у вас также был какой-то уровень доверия для пользователя, например репутация SO, для предотвращения попыток взлома однократными пользователями. Это действительно слишком конкретный вопрос, чтобы давать какие-либо полезные советы.

Вам также необходимо правильно проверить ввод, который вы получаете, чтобы предотвратить взломы, такие как переполнения буфера и SQL-инъекции . Несмотря на то, что я не знаю, является ли переполнение буфера проблемой в .NET, и инъекции SQL легко предотвратить с помощью LINQ-to-SQL.


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

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

Также вы все еще можете использовать LINQ с веб-сервисами через LINQ to ADO.NET , хотя я сам не пробовал.

Эта ссылка может быть более объяснительной Как перейти от LINQ к SQL к «LINQ to WCF»?

0 голосов
/ 08 августа 2009

Если я правильно понимаю ОП, неизменными характеристиками проекта являются клиент WinForms, подключающийся напрямую к общедоступному SQL Server?

Почти все, кто ответил, в основном говорили: «Не делайте этого, используйте вместо этого веб-сервис». Это хороший совет. Даже если ws взломан, он может делать только то, для чего предназначен. Таким образом, RPC WS может выполнять только те методы, которые уже написаны, тогда как взлом соединения с SQL Server может привести к произвольному выполнению SQL. Кроме того, я думаю, вы найдете, что хорошо разработанный веб-сервис будет более производительным.

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

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

Не позволяйте приложению WinForms подключаться к вашей операционной базе данных. Вместо этого создайте другую базу данных и разрешите подключение к ней на основе строки подключения. Не делайте динамический SQL с этим дизайном, вместо этого используйте хранимые процедуры. Создайте хранимые процедуры в вашей публичной базе данных, которые будут действовать как ваш «веб-сервис rpc», чтобы скрыть реальный SQL (который будет запрашивать вашу операционную базу данных и возвращать результаты). Это скроет рабочие детали вашей схемы и уменьшит площадь атаки.

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

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

0 голосов
/ 08 августа 2009

Ответ прост для защиты строк SQL прост. НИКОГДА не устанавливать прямое соединение с SQL на стороне клиента.

Принимайте только правильно сформированные, проверенные схемой XML-сериализованные объекты в качестве входных данных вашей программы после проверки подлинности в хешированной паре открытого личного ключа (http://msdn.microsoft.com/en-us/library/6f05ezxy.aspx), являющейся сертификатом открытого ключа, поставляемым в вашей программе, кто-то подслушивает, не обнаружит пароль.

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

0 голосов
/ 05 августа 2009

Трудно дать точный ответ, потому что я не уверен, какие конкретно проблемы вы пытаетесь решить, и какой является ключевым фактором для защиты системы.
Однако в прошлом я использовал безопасную связь WinForms -> WebService, используя WSE
Мы использовали сертификаты X509 и WS-Security. Это имеет явное преимущество в обеспечении сквозной безопасности вместо использования стандартного транспорта SSL.
Однако само по себе это не решает такие проблемы, как аутентификация пользователя как таковая, в этом случае ответ Митча Уитя кажется хорошим решением.
Однако ваша модель аутентификации пользователей будет зависеть от того, является ли это общедоступным распределенным приложением, большое или маленькое число пользователей инструмента и т. Д.
Для небольшого числа пользователей или там, где стоимость не является проблемой, вы можете внедрить аутентификацию RSA SecurID , настроив сервер RADIUS или подобный. Это имеет преимущество в том, что каждый ключ RSA уникален и привязан к этому пользователю (хотя вы никогда не сможете остановить пользователя, выдающего свои учетные данные и PIN-код)

НТН

0 голосов
/ 03 августа 2009

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

С точки зрения файла конфигурации можно зашифровать сам файл или использовать встроенную защиту в качестве другого упомянутого автора.

0 голосов
/ 03 августа 2009

Безопасный метод:

Поместите слой данных за службой (WCF) на физически отдельный сервер приложений и подключите клиентов WinForms к службе, используя свои учетные данные Windows. Служба затем проверяет, могут ли пользователи получать доступ к различным методам службы на основе хранилища авторизации (такого как Active Directory) и базы данных или их комбинации.

Служба данных может затем использовать одно объединенное удостоверение для подключения к базе данных.

0 голосов
/ 03 августа 2009

Вы не защищаете его , потому что вы не можете защитить его. Во-первых, вы не можете должным образом скрыть учетные данные, даже если вы поймете, как это сделать, тогда злоумышленник может прослушать ( да, даже если он зашифрован, вы можете локально прослушать ) или выполнить SQL-инъекцию непосредственно в сети. 1005 *

Вам необходимо писать все вызовы веб-службы безопасным способом, не требующим передачи необработанного SQL-запроса или прямого соединения с SQL Server.

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

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

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