Вопрос или проблема
Я веду обсуждение с командой по информационной безопасности о наследственном настольном приложении, которое напрямую обращается к базе данных SQL Server с использованием LINQtoSQL.
Команда по информационной безопасности настаивает на том, что в настольном приложении и SQL Server с открытым портом для сетевой связи существует множество уязвимостей.
Как разработчик с опытом работы более 10 лет, я могу только перечислить связанные с этим риски:
- Не подписанное приложение: полномочия компании не могут быть сертифицированы, что позволяет злоумышленнику создать копию приложения с вредоносным кодом.
- Необфусцированный код: злоумышленник может декомпилировать приложение, изменить его код и внедрить вредоносный код.
- Открытый порт: может быть использован с украденным именем пользователя и паролем SQL SERVER для утечки данных.
Но я знаю, как мы можем смягчить все эти проблемы, вместо того чтобы тратить огромные усилия на миграцию всего настольного приложения (более 8 лет) на веб-приложение (для интрамедий).
Есть ли у вас дополнительные аргументы против этой клиент-серверной архитектуры?
Не подписанное приложение: полномочия компании не могут быть сертифицированы, что позволяет злоумышленнику создать копию приложения с вредоносным кодом.
Имейте в виду, что злоумышленник может сделать то же самое с веб-приложением, если оно не защищено должным образом с помощью TLS.
Необфусцированный код: злоумышленник может декомпилировать приложение, изменить его код и внедрить вредоносный код.
Обфусцированный код – это относительно небольшое препятствие для кого-то, кто уже достаточно мотивирован, чтобы провести реверс-инжиниринг. Я не совсем уверен, что именно будет изменено или внедрено в этом случае.
Открытый порт: может быть использован с украденным именем пользователя и паролем SQL SERVER для утечки данных.
Ваши пользователи, вероятно, имеют доступ к учетным данным для базы данных, независимо от того, закодированы ли они в приложении или предоставлены пользователем.
Я думаю, что настоящая проблема заключается в том, что база данных напрямую доступна, и ваша команда по информационной безопасности, вероятно, обеспокоена контролем доступа и аудитом. Веб-приложение абстрагирует базу данных и позволяет внедрить бизнес-логику. Вы не хотите, чтобы пользователи, например, злонамеренно или случайно, удаляли всю базу данных, изменяли все записи, добавляли сомнительные/непроверенные данные и т.д. Или, возможно, пользователи должны иметь эти разрешения, но вы хотите подробный журнал того, кто, что и когда сделал.
Хотя некоторые или все эти вещи могут быть возможны с встроенными средствами управления базами данных, это, вероятно, будет намного сложнее в управлении и более подверженным ошибкам. Я думаю, что это зависит от того, сколько усилий вы готовы вложить в настройку базы данных по сравнению с созданием веб-приложения. Это также зависит от уровня доверия к пользователям, имеющим доступ.
Эта вопрос и ответы обсуждают эту проблему более подробно.
Кроме того, настольное приложение не достаточно для применения контролей и проверок, так как оно находится под контролем [недоверенного] пользователя. Логика на клиентской стороне может быть изменена или полностью обойдена с помощью прямого подключения к серверу или путем изменения приложения. Учетные данные и другая “секретная” информация, закопанные в клиентском приложении, почти всегда могут быть восстановлены. Если они зашифрованы, их легко можно перехватить из памяти при использовании. Или, если сетевые коммуникации к базе данных не зашифрованы, их можно перехватить там. По этим причинам любая важная логика всегда должна проверяться на каком-то серверном backend.
Похоже, что ваше настольное приложение имеет общую базу данных (предположительно находящуюся в локальной сети или даже в Интернете), к которой подключаются ваши пользователи? Если это так, это не идеально – серверы баз данных обычно должны быть скрыты за другим ПО, а не непосредственно открыты для недоверенных пользователей – но это не является по своей сути катастрофой, если база данных защищена должным образом. “Защищена должным образом” здесь означает такие вещи, как:
- Привилегии доступа по пользователям. Если вы находитесь в домене Windows или другой службе Active Directory/LDAP, это можно сделать, заставив приложение аутентифицироваться с помощью учетной записи Active Directory пользователя (по крайней мере, для MS SQL Server; не уверен, поддерживают ли это другие). Противоположностью будет, если все экземпляры приложения используют одни и те же учетные данные для доступа к базе данных; ЭТО будет серьезной проблемой безопасности, так как не будет возможности предотвратить чтение злоумышленником этих учетных данных из приложения и их использование для прямого подключения к базе данных и выполнения вредоносных запросов.
- Минимальные привилегии пользователей. Пользователи должны иметь доступ только к своим данным или к данным, которые предназначены для совместного использования с ними. Иногда это достигается с помощью контроля доступа на уровне таблицы, но если данные пользователей смешаны в одной таблице, то вам, вероятно, понадобится безопасность на уровне строки. В идеале пользователи вообще не должны иметь возможность выполнять произвольные запросы; ограничьте их набором хранимых процедур, которые могут делать только то, что пользователю разрешено делать. Это также хорошая идея для защиты от SQL-инъекций. Противоположностью будет то, что все пользователи имеют привилегии администратора/владельца базы данных, имея возможность полностью контролировать базу данных, если они когда-либо получат к ней доступ любым иным способом, кроме клиентского приложения.
- Сильная аутентификация пользователя. Подключение к базе данных должно требовать учетных данных, которые не используются в других местах и не могут быть легко украдены, подделаны или угаданы. Аутентификация Windows здесь немного неоднозначна; это лучше, чем многие самодельные системы аутентификации, но это не делает ее хорошей, и ваши возможности усилить безопасность ограничены (в основном отключить поддержку устаревших версий LANMAN/NTLM или слабых удаленных паролей, таких как MS-CHAPv2… но, в конечном счете, все же существует риск таких атак, как pass-the-hash, которые могут быть использованы для выдачи себя за другого пользователя). Противоположностью этого будет система, где даже если у каждого пользователя есть своя собственная учетная запись, нет безопасного способа предотвратить использование одной учетной записи другим человеком (например, если они делят пароли).
- Укрепление сервера. Даже если сервер базы данных должен быть доступен в сети, вы можете и должны отключить или ограничить большинство других удаленных подключений к хосту сервера базы данных. Отключите функциональные возможности в базе данных, которые вам не нужны, и убедитесь, что сам сервер работает на своем хосте с минимальными привилегиями, которые ему нужны. Вы также можете ограничить сетевую видимость только определенными сетями, а не всем в данной компании или (хуже) в Интернете. Также убедитесь, что ПО сервера базы данных и его ОС обновляются, и ограничьте, кто может физически получить доступ к серверу или войти в ОС хоста напрямую, особенно ограничьте доступ к привилегированным учетным записям. Противоположностью этого является сервер, расположенный где-то в публичном месте – возможно, на чьем-то столе – к которому любой сотрудник (или кто-то подобный) может войти как локально, так и удаленно; даже если они теоретически не имеют доступа к базе данных при этом, они могут попытаться использовать уязвимость повышения привилегий, чтобы получить доступ.
- Обеспечьте безопасность подключения. Требуйте использования безопасного протокола для подключения, например TLS или хотя бы SMB с шифрованием и целостностью, и убедитесь, что злоумышленники не могут получить доступ к закрытому ключу, используемому сервером базы данных для защиты соединений. В идеале вы хотите иметь секретность впереди (последние версии TLS продвигают или даже требуют этого) и аутентифицированное шифрование (аналогично). Клиент должен аутентифицировать сервер с использованием криптографического ключа (обычно сертификата), а не просто полагаться на имя хоста или IP-адрес. Противоположностью этого будет подключение в открытом виде, при котором учетные данные и данные могут быть перехвачены или даже подменены сетевым злоумышленником, или клиент, который не аутентифицирует сервер перед тем, как аутентифицировать себя, случайно отправляет учетные данные пользователя сетевому злоумышленнику.
Существует множество дополнительных ресурсов, которые вы можете прочитать, чтобы узнать о защите SQL Server (некоторые из которых могут быть применены и к другим базам данных). Например, https://learn.microsoft.com/en-us/sql/relational-databases/security/securing-sql-server?view=sql-server-ver16 и https://learn.microsoft.com/en-us/sql/relational-databases/security/sql-server-security-best-practices?view=sql-server-ver16
Ответ или решение
Безопасностные проблемы настольных приложений с доступом к SQL Server
Ваша ситуация с устаревшим настольным приложением, обращающимся к базе данных SQL Server с использованием LINQ to SQL, действительно поднимает множество вопросов безопасности. Давайте рассмотрим основные проблемы и возможные меры по их снижению, а также аргументы, которые могут помочь вам в диалоге с командой информационной безопасности.
Основные проблемы безопасности
-
Подпись приложения
Компания не может заверить подлинность приложения, что позволяет злоумышленнику создать его копию с вредоносным кодом. Это создает риск распространения модифицированных версий приложения, которые могут выполнять нежелательные действия. -
Необфусцированный код
Атакующий может декомпилировать приложение, изменять его код и внедрять зловредные изменения. Хотя обфускация кода может усложнить задачу реверс-инжиниринга, она не является надежной защитой, так как опытные злоумышленники могут обойти даже эти меры. -
Открытый порт для SQL Server
Если SQL Server доступен из сети, это может привести к утечкам данных в случае кражи учетных данных. Злоумышленник, обладающий пользователем и паролем, может запускать запросы напрямую к базе данных.
Предложения по минимизации рисков
-
Подпись приложения и использование доверенной инфраструктуры
Разработайте и внедрите процесс цифровой подписи для вашего приложения, чтобы пользователи могли уверенно его устанавливать. Это поможет предотвратить установку модифицированных версий приложения. -
Обфускация кода и ограничение доступа
Используйте инструменты обфускации, чтобы сделать процесс реверс-инжиниринга более сложным. Однако помните, что это не панацея. Реализуйте роль и разрешения для пользователей в базе данных, чтобы ограничить доступ к критическим операциям и данным. -
Изоляция базы данных через прокси или API
Учитывая риски, связанные с прямым доступом к базе данных, рассмотрите возможность использования промежуточного слоя, такого как API, который будет обрабатывать все запросы к базе данных. Это позволит эффективно управлять правами доступа и контролировать операции с данными. -
Настройка учета и контроля доступа
Настройте индивидуальные учетные записи пользователей с минимально необходимыми привилегиями. Используйте ролевую модель для предоставления доступа на основе необходимостей сотрудников. Включите аудит действий, чтобы отслеживать, кто, что и когда изменял. -
Безопасность подключения
Обязательно используйте шифрование соединения (например, TLS) для защиты данных, передаваемых между приложением и сервером базы данных. Это предотвратит утечки данных через сетевые атаки. -
Периодическая проверка безопасности и обновление компонентов
Регулярно проверяйте все используемые компоненты на наличие уязвимостей и обновляйте их для поддержания высокого уровня безопасности.
Заключение
Понимание рисков и уязвимостей в настольных приложениях — это первый шаг на пути к улучшению безопасности системы. Ваши предложения по снижению этих рисков имеют смысл, но важно также учитывать, что использование настроенного и защищенного API для обращения к БД значительно уменьшит потенциальные угрозы. Работая в тесном сотрудничестве с командой информационной безопасности и вашими разработчиками, вы сможете создать систему, которая не только функциональна, но и безопасна.