Як ви обробляєте захист бази даних через настільний додаток?


12

Близько 10 років я працював над різними внутрішніми настільними клієнтськими програмами із сховищами даних SQL Server. Рідко я запускав ці проекти - більшість - це роботи з перевезення.

Одне, що здавалося незмінним скрізь, - це те, що існує один глобальний обліковий запис користувача SQL Server, який використовував цей додаток, який надав йому дозвіл на загальну базу даних, і так, в деяких наївних ситуаціях він використовував saобліковий запис користувача, який я, як правило, намагався виправити, коли це можливо .

Ви справді не можете ефективно приховати це ім’я користувача та пароль, якими користується програма для доступу до бази даних. Зазвичай вони зберігаються у файлі iniчи configфайлі, або, можливо, вкладаються у сам файл, що виконується. У всіх випадках вони помітні користувачеві, якщо вони трохи копають. В одному випадку ми фактично використовували configфайл, але зашифрували його, але, звичайно, ключ шифрування мав бути збережений у виконуваному файлі (ми не були наївними до обмежень цього, але це фактично заважало людям роздиратися, хто був достатньо кмітливим. шукати у configфайлах).

Усі ці системи мали в програмі вбудовану систему аутентифікації користувачів, але, звичайно, всіма ними керував через додаток, тобто інформація про користувачів зберігалася в базі даних. Додаток обмежував, що ви можете робити, залежно від рівня доступу, але це все-таки суперечка, якщо ви можете просто підключитися до бази даних та запустити спеціальні запити.

Мені цікаво знати, що роблять інші системи, щоб подолати цю проблему. Ось варіанти, які я знаю:

  1. Використовуйте механізм захисту SQL Server для підтримки списку користувачів та ролей, а також додайте та додайте на робочий стіл додаток та видаліть користувачів за допомогою T-SQL запитів.
  2. Замість того, щоб підключатися безпосередньо до бази даних, створіть якусь веб-службу, яка працює на сервері, і введіть туди логіку аутентифікації. Зробіть кожен запит перевірки безпеки.

Перші параметри трохи некрасиві, оскільки ви відокремлюєте користувачів від бази даних, щоб користувачі перестали бути особами першого класу, і ви не можете посилатися на них із зовнішніми ключовими відносинами тощо.

Друга просто здається головною проблемою продуктивності та великою кількістю зайвої роботи, плюс ви не можете так просто використовувати картографи ORM, як NHibernate (я думаю).

Хтось має з цим досвід? Кращі практики?

Редагувати

Подумавши трохи більше, чи може автентифікація SQL Server насправді вирішити цю проблему? Наприклад, якщо ваш користувач повинен мати можливість вставляти та оновлювати записи часових таблиць, щоб ви могли редагувати свій розклад часу, SQL-сервер не може заборонити доступ до інших рядків у таблиці деталей таблиці, що означає, що ви можете також читати та писати записи інших людей.


За темою палітурки; не використання ORM як NHibernate - я думаю, що це не проблема. Якщо ви використовуєте веб-сервіси як приклад, ви знайдете безліч способів ефективного прив’язання своїх даних до XML.
жасонька

Ви не повинні використовувати свій ORM як пряме відображення між бізнес-об'єктами та об'єктами БД, так як це поганий підхід, що спричиняє крихкі інтерфейси. Здійснюйте запити до бізнес-рівня, який отримує необроблені об'єкти БД і повертає клієнту лише необхідні дані.
gbjbaanb

@gbjbaanb - звичайно, я зміню всю архітектуру сьогодні вдень. :)
Скотт Вітлок

Я гадаю, ви могли зачекати, поки хтось зламає вас, перш ніж змінити це, але, зі сторони, принаймні тоді у вас не буде проблем із тим, щоб ваш начальник фінансував реконструкцію :-)
gbjbaanb

Ви можете запобігти оновленню чужих записів користувачем - використовуючи збережену процедуру як єдиний спосіб оновлення записів та використання користувача, який запускає програму, як частину запиту. Дивіться CURRENT_USER
gbjbaanb

Відповіді:


9

Боюся, що додавання рівня веб-сервісу - це, мабуть, правильне рішення вашої проблеми.

Відокремлення клієнта від базової реалізації бази даних, ймовірно, допоможе вам і в довгостроковій перспективі.

Додавання шару веб-сервісу не обов'язково має погіршити продуктивність ...

Дійсно, за допомогою відповідного API веб-сервіс може фактично підвищити продуктивність, об'єднавши кілька запитів до бази даних в локальній мережі даних центру, а не вимагаючи багаторазових поїздок по мережі.

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

Серверний рівень додає безпеку, яку неможливо забезпечити за допомогою програм, що працюють на віддаленому клієнті. Все, що працює на клієнті, може бути "зламане" і насправді не слід вважати жодним способом довіри. Вам слід по-справжньому покласти логіку презентації в клієнт і розмістити все важливе на апаратному забезпеченні, над яким ви повністю контролюєте.

Я не знаю про ваші програми, але мої веб-додатки, природно, розділені на кілька шарів, при цьому презентаційний код відокремлений від шару стійкості принаймні одним рівнем ділової логіки, який тримає їх один від одного. Я вважаю, що це набагато простіше міркувати про моє додаток і набагато швидше додавати або змінювати функціональність. Якщо шари все одно відокремлені, тримати презентаційний шар у клієнті відносно легко, а решта на сервері під моїм контролем.

Отже, хоча ви можете вирішити свої проблеми, не вводячи рівень "веб-сервісу", до моменту, коли ви записали всі збережені процедури (або еквівалент), необхідні для заповнення дірок у стандартній реалізації безпеки бази даних, вам, ймовірно, буде краще писати додаток на сервері, для якого можна написати належні тестові одиниці.


Я визнаю, що це не повинно бути вузьким місцем продуктивності, але це, безумовно, додає додатковий шар архітектурі, що означає набагато більше обслуговування.
Скотт Вітлок

3
Це додає шар, але не обов’язково обслуговування. Враховуйте, що з усією логікою, розміщеною в сервісі, а не в клієнті, зміни можна "виконувати", не вимагаючи від користувачів оновлення своїх клієнтських додатків.
гросмайстерB

5

Подібно до відповіді jmoreno, ви можете заборонити користувачеві доступ до всього, окрім дозволів EXECUTE на збережені процедури, а потім скористатися ланцюгом власності, щоб збережена процедура виконувала необхідні операції над таблицями.

Деталі див. Тут https://msdn.microsoft.com/en-us/library/bb669058(v=vs.110).aspx

Коли користувач вводить клієнтське ім'я користувача / пароль, я зберігаю їх і надсилаю як параметри до кожного збереженого виклику процедури. Потім ви можете перевірити їх щодо значень, збережених у таблиці, перш ніж виконати потрібну операцію.

Очевидно, це не останнє слово в галузі безпеки, але це може знадобитися, якщо на ваших ПК є загальні входи, що обмежують вашу можливість використовувати групи AD для дозволів або ви обмежили доступ до самої AD.


2

Один із підходів полягає у використанні груп AD та збережених процедур для обмеження того, що може робити користувач - наприклад, БД вашого часового журналу, може дозволяти вводити, оновлювати та видаляти користувачі години, але не допускати оновлення чужих годин. Ідентифікатор користувача буде наданий двигуном DB, користувач не матиме прямого доступу до таблиць БД, лише до sp, які виконували запити на основі свого ідентифікатора входу.

Звичайно, це не завжди можливо, але це може бути. Найкращий підхід буде залежати від ваших вимог та ресурсів.


Це те, що я не розглядав. Я не впевнений, що це чудово підходить, але це спрацювало б.
Скотт Уїтлок

1

Те, що ви натякаєте на "веб-сервіс", називається n-ярусною архітектурою . Зазвичай це шлях у випадках, коли ймовірні проблеми із безпекою чи конфігурацією (наприклад, розповсюдження програми у багатьох офісах). Однак це не повинно бути "веб-базованим". Багато хто працює з іншими протоколами.

Ви створюєте сервер додатків, щоб діяти як посередник між клієнтом та базою даних (та іншими ресурсами). Сервер додатків обробляє аутентифікацію на основі вашої програми та виконує дії від імені клієнта. Насправді, в ідеалі ви не хочете робити будь-якого SQL у своєму клієнті - скоріше ви закликаєте методи на сервері програм. Сервер додатків обробляв би всі маніпуляції з даними.

Існує ряд переваг підходу. Вам не потрібно налаштовувати підключення до бази даних та драйвери для клієнтів. Ви не зберігаєте користувачів баз даних, паролів та серверів. Конфігурація клієнтів навіть не потрібна - просто вкажіть їх у коді на потрібну URL-адресу чи адресу. Крім того, з "логікою" на сервері додатків, вам не доведеться повторювати себе під час розробки інших програм - той самий сервер додатків може бути повторно використаний різними типами клієнтів.


Ще краще, якщо (або коли) хтось зламає ваші настільні комп’ютери (або веб-сервер у веб-еквіваленті), зловмисник може мати повний доступ до ОС, але вони все ще не мають доступу до БД. І тому вони не можуть потім запустити "вибирати * з користувачів" трубопровід до файлу, який вони відбирають, зламати їх дозвілля і дозволити вашому генеральному директору пояснити ЗМІ, чому ваша захищена система була порушена. Якщо ви також використовуєте відростки в БД, що дозволяє лише виконувати доступ, то зловмисник також може зламати ваш додаток, і вони все ще не можуть отримати всю вашу базу даних користувачів.
gbjbaanb

1

Технологія трохи змінилася. Якщо ви автентифікуєте кожного користувача в самій базі даних та використовуєте ролі бази даних, тепер ви можете використовувати те, що називається оновленням перегляду, для вирішення цієї проблеми, принаймні, на SQL Server.

Ось як може виглядати оновлений вигляд для таблиці під назвою, SomeTableде кожен рядок цієї таблиці пов'язаний із співробітником. Працівник повинен мати можливість бачити пов'язані між собою рядки, а члени рольової групи повинні бачити всі рядки, наприклад:

CREATE VIEW [dbo].[vwSomeTable]
AS
    SELECT SomeTable.*
    FROM SomeTable
        INNER JOIN Employee ON SomeTable.Employee_ID = Employee.Employee_ID
    WHERE Employee.Username = USER_NAME() OR IS_MEMBER('HR_Role')=1

GO

Тоді те, що ти робиш, - це дати дозволу на читання (і, можливо, запис) для перегляду ( vwSomeTable) усім користувачам, і не давати дозволу на стіл ( SomeTable).

Ви можете перевірити це так:

EXECUTE AS USER = 'Some_Regular_Username'
SELECT * FROM vwSomeTable

... які повинні повертати лише їх рядки. Або:

EXECUTE AS USER = 'Some_HR_Username'
SELECT * FROM vwSomeTable

... що поверне всі рядки. Зауважте, що для цього тестування вам знадобляться дозволи на виконання (імперсонація).

Представлення даних оновлюються, тому навіть звичайний користувач може це робити, якщо рядок пов'язаний з їх Employeeрядком:

UPDATE vwSomeTable
SET SomeColumn = 5
WHERE SomeTable_ID = 'TheID'

0

Використання автентифікації на основі сертифікатів є "правильним" способом реалізації спільного акаунта sql. Мета - усунути використання пароля для подібних речей.

Оновлення:

Я гадаю, що це питання зрозуміло неправильно. Я подумав, що це стосується намагання знайти альтернативу введенню db імені користувача та пароля або в конфігурацію програми, або підключено в саму програму.

Ви можете усунути проблему керування паролями в додатках, скориставшись замість цього сертифікатами на стороні клієнта. Сам серт недостатній, ви повинні мати систему розподілу та управління, здатну виконувати такі операції, як скасування cert.

Довідка: http://en.wikipedia.org/wiki/Public-key_infrastructure


Чи можете ви надати більше інформації про це? Здається, це може бути ортогональним наміром мого оригінального запитання, але це цікаво.
Скотт Вітлок

0

Створюючи нове рішення для безпеки на робочому столі, ми вибрали рішення для веб-служб, я спробую описати нижче.

Ми компілюємо виконувані файли настільних програм в окремому середовищі від розробників. І обчислити HASH з цього виконуваного файлу, який записується в базу даних.

Один веб-сервіс, який надає всю необхідну інформацію для запуску програми, пароль БД, інформацію про рядок з'єднання, дозволи користувача та ін.

ми використовуємо один вхід у систему DB для кожної програми та записуємо дані користувача в базу даних в змінні сеансу, щоб мати змогу перевіряти записи.

DLL обробляє все спілкування від настільного додатка до веб-сервісу, доступне лише за допомогою вбудованого маркера в DLL.

Щоб мати змогу отримати пароль DB програми від веб-сервісу, DLL обчислює виклики DLL HASH під час виконання та передає як параметр веб-сервісу, який перевіряє маркер DLL та виконувану версію виконуваного часу HASH до того, записаного при його розгортанні. (додаток доступний лише в одній мережевій спільній установці).

Таким чином, ми впали, це гарне рішення проблеми безпеки, яку ми найбільше хвилюємо та добре знаємо кілька недоліків дизайну. Ми майже закінчуємо цю реалізацію, і поки що ми задоволені результатами.

Редагувати: Ви можете замінити ідею хешу, використовуючи цифрові підписи та сертифікати X.509.


1
Здається, досить очевидно, де знаходиться кричущий отвір для безпеки. DLL, про який ви говорите, є в системі клієнта, і код вашого сервера не може підтвердити, що він говорить з законною копією DLL або зломленою / зловмисною / підробленою. Ви просто створили для себе багато роботи, не додаючи додаткової безпеки, якщо така є, додаткової безпеки. Всі зловмисні люди потребують - маркер і алгоритм, обидва вони є в DLL для всіх, хто хоче шукати.
Скотт Вітлок

@ScottWhitlock, Так, я згоден. ми розглядаємо обтяження DLL і трафік, що переходить через HTTPS. Ми намагаємося вдосконалити це, мені дуже подобається будь-який внесок у його покращення. Але це рішення вже вирішує багато питань, які має поточна система, включаючи звичайні текстові паролі, що зберігаються в мережевих файлах. Також веб-сервіс дозволяє повторно використовувати багато кодів, доступних будь-якою з мов клієнта, якими ми користуємося тут, включаючи клієнтів Delphi та Clipper (Harbor)!
Вітор Арбекс

У вашій системі користувач входить у систему та, імовірно, автентифікується веб-службою. Якщо припустити використання HTTPS, чи не це досить добре? Вам не доведеться довіряти клієнтському програмному забезпеченню, оскільки ви знаєте, що користувач - це той, про кого вони говорять, і ви керуєте веб-службою, тому переконайтеся, що веб-сервіс передає лише інформацію, яку даний користувач має право бачити. Навіть якщо вони реверсивно розробляли клієнта і писали своє, яку шкоду вони могли зробити? Тільки ваша веб-служба знає пароль БД, і це повинно бути безпечно.
Скотт Вітлок
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.