Изменить пароль пользователя для базы данных Oracle с помощью оператора SQL в C # - PullRequest
0 голосов
/ 10 января 2019

Я работаю над требованием, при котором я должен изменить пароль соединения оракула текущего пользователя из моего приложения.

Я обнаружил, что могу использовать следующую инструкцию для выполнения этой задачи с использованием SQL:

ALTER USER *username* IDENTIFIED BY *password*

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

У меня есть рабочее решение, когда я объединяю строку и отправляю ее как обычный SQL-запрос через мой экземпляр Entity Framework DbContext, например:

using (var context = _dbContextFactory.CreateContext())
{
    await context.Database.ExecuteSqlCommandAsync(
      $"ALTER USER {username} IDENTIFIED BY \"{newPassword}\"");
}

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

Меня не беспокоит параметр имени пользователя, поскольку он управляется внутри кода бэкэнда, однако пароль напрямую вводится пользователем.

Есть ли способ изменить пароль текущего пользователя в базе данных Oracle из C #, используя безопасный подход? Я также открыт для других подходов, таких как метод diffrent или создание хранимой процедуры в базе данных, при условии, что она может быть реализована в клиентском приложении C #.

Мы используем Oracle версии 12+, поэтому я не могу использовать синтаксис IDENTIFIED BY VALUES ''

Ответы [ 2 ]

0 голосов
/ 10 января 2019

Кажется, это работает на моем локальном тестовом БД Oracle (из драйвера ODP.net). Важный бит, казалось, НАЧИНАЕТСЯ / КОНЕЦ; (не будет работать без него).

using (var con = (OracleConnection)db.Server.GetConnection())
{
    con.Open();

    //string pw = "'''';++";
    string pw = "newpass";

    var cmd = new OracleCommand(@"
BEGIN
EXECUTE IMMEDIATE CONCAT('ALTER USER B identified by ',:pw);
END;", con);
    cmd.CommandType = CommandType.Text;

    var p2 = cmd.CreateParameter();
    p2.ParameterName = "pw";
    p2.Value = pw;
    p2.DbType = DbType.String;
    cmd.Parameters.Add(p2);

    cmd.ExecuteNonQuery();
}
0 голосов
/ 10 января 2019

Для username мы должны предоставить Идентификатор Oracle (в случае сохранения исходного запроса), который равен

  • Длина до 30 символов
  • Должен начинаться с буквы
  • Может включать $ (знак доллара), _ (подчеркивание) и # (знак хеша)

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

if (!Regex.IsMatch(username, @"^[A-Za-z][A-Za-z0-9_#\$]{0,29}$")) {
  // username is invalid
}

Для password мы можем

  • Удвоить все предложения: my"password -> my""password
  • Убедитесь, что password содержит только допустимые символы (например, давайте исключим юникод управляющие символы , такие как пробел и другие)

Так что код будет примерно таким

if (!Regex.IsMatch(username, @"^[A-Za-z][A-Za-z0-9_#\$]$")) {
  // username is invalid
}

if (string.IsNullOrEmpty(newPassword) || newPassword.Any(c => char.IsControl(c))) {
  // password is invalid
}

using (var context = _dbContextFactory.CreateContext()) {
  await context.Database.ExecuteSqlCommandAsync(
    $"ALTER USER {username} IDENTIFIED BY \"{newPassword.Replace("\"", "\"\"")}\"");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...