Ответ на задание 1
Для управления доступом целесообразно использовать роли
и принцип минимально необходимых привилегий. Пользователь должен получать
только те права, которые необходимы для выполнения его обязанностей.
Например:
Administrator
-------------------------
SELECT
INSERT
UPDATE
DELETE
CREATE
ALTER
DROP
Администратор отвечает за управление базой данных и поэтому
может иметь расширенные права.
Для преподавателя:
Teacher
-------------------------
Student → SELECT
Course → SELECT
Grade →
SELECT, INSERT, UPDATE
Преподаватель может просматривать сведения о студентах и
дисциплинах, а также работать с оценками.
Для студента:
Student
-------------------------
ограниченный SELECT
При этом в реальной системе недостаточно просто предоставить
студентам SELECT на всю таблицу с оценками, если они должны видеть только
собственные данные. Такое ограничение обычно реализуется через представления,
политики доступа на уровне строк или прикладную логику.
Таким образом, права доступа должны соответствовать роли
пользователя и не предоставлять лишних возможностей.
Ответ на задание 2
В PostgreSQL пользователя можно создать следующим образом:
CREATE USER teacher1
WITH PASSWORD 'StrongPassword123';
Предоставим право чтения таблицы Student:
GRANT SELECT
ON Student
TO teacher1;
Для таблицы Grade предоставим несколько прав:
GRANT SELECT, INSERT, UPDATE
ON Grade
TO teacher1;
Теперь пользователь teacher1 может читать данные таблицы
Student, а в таблице Grade — просматривать, добавлять и изменять записи.
Если необходимо запретить преподавателю изменять оценки:
REVOKE UPDATE
ON Grade
FROM teacher1;
После этого права могут выглядеть следующим образом:
Student → SELECT
Grade →
SELECT, INSERT
Для большого количества пользователей удобнее назначать
разрешения не каждому пользователю отдельно, а создавать роли.
Например:
CREATE ROLE teacher_role;
GRANT SELECT
ON Student
TO teacher_role;
GRANT SELECT, INSERT, UPDATE
ON Grade
TO teacher_role;
GRANT teacher_role TO teacher1;
Это упрощает централизованное управление доступом.
Ответ на задание 3
Если SQL-запрос формируется непосредственным объединением
строк, возникает риск SQL-инъекции (SQL Injection).
Небезопасный подход может выглядеть концептуально так:
"SELECT * FROM Users WHERE Email = '" + userInput
+ "'"
В таком случае введенное пользователем значение становится
частью текста SQL-команды. Злоумышленник может попытаться изменить структуру
исходного запроса с помощью специально сформированного ввода.
Правильный подход — использовать параметризованные
запросы.
Например, в C# с Npgsql:
const string sql =
"SELECT *
FROM Users WHERE Email = @email";
await using var command =
new
NpgsqlCommand(sql, connection);
command.Parameters.AddWithValue(
"email",
userEmail
);
await using var reader =
await
command.ExecuteReaderAsync();
Здесь пользовательское значение передается отдельно от
текста SQL-запроса. СУБД рассматривает его как значение параметра, а не как
часть SQL-команды.
Дополнительно безопасность базы данных должна включать:
Таким образом, безопасность базы данных обеспечивается не
одним механизмом, а совокупностью мер на уровне СУБД, приложения,
инфраструктуры и управления доступом.