Подтвердить что ты не робот

Почему не DriverManager.getConnection(String url, String user, char [] password)?

Мы знаем, что рекомендуется использовать char [] над java.lang.String для хранения паролей. Это по двум причинам (как я читал):

  • char [] изменяются, поэтому мы можем очистить пароли после использования.
  • Строковые литералы отправляются в пул, который не будет собирать мусор, как другие объекты, поэтому может появляться в дампах памяти.

Но java.sql.DriverManager не имеет getConnection(), которые соответствуют вышеуказанной лучшей практике, потому что его паролем является String.

DriverManager.getConnection(String url, String user, String password)

Я думаю, что API должен иметь перегруженный метод со следующей сигнатурой:

DriverManager.getConnection(String url, String user, char [] пароль)

Что вы думаете об этом? Вы видите какой-либо альтернативный способ преодолеть этот откат?

Хотелось бы услышать ваши мысли.

4b9b3361

Ответ 1

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

Ответ 2

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

Лучшее, что вы можете сделать, это connect, password = null, а затем явный вызов gc(). Если вам повезет, это очистит даже строки, используемые в реализации драйверов.

В любом случае...

  • То, что вы просите, в настоящее время невозможно, но было бы неплохо.
  • Даже char [] может выдержать определенные условия (например, свопинг).
  • Ваш пароль будет многократно копироваться на пути к базе данных, поэтому char [] решает только одну часть проблемы.

Реальность такова, что, если платформа не предназначена специально для обеспечения безопасности, все методы только задерживают тактику. Сделайте, что вы можете, но если определенный человек сможет получить доступ к вашей машине, char [] получит максимум 1 час.

Ответ 3

Можно только догадываться, если вы не спросите дизайнера API.

Мое предположение таково:

Основной API, который использует char[] вместо String для паролей, о которых я знаю, JPasswordField. Это делается для того, чтобы программа могла перезаписать введенный пользователем пароль другими значениями после использования значений (что невозможно при использовании String, которое будет задерживаться в памяти, по крайней мере, до тех пор, пока не будет собрано мусор).

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

Не важно, откуда оно взялось: приложение может перестроить его, когда оно уже не известно. Это большая разница между введенными пользователем паролями и программно приобретенными паролями.

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

</speculation>

Ответ 4

Ваша причина № 2 такова, которую я видел чаще всего для использования char [] над String. Однако, в целом, я думаю, что если вы предполагаете, что у кого-то есть доступ к вашему состоянию программы через отладчик или другие средства, нет причин, по которым они не могут также посмотреть содержимое char [].

Ответ 5

Аргумент для использования массивов char [] применяется в большинстве случаев, когда пользователь вводит пароль, и вы хотите минимизировать экспозицию этого пароля.

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

В любом случае стандарт JDBC позволяет передавать пароли в объектах свойств и даже в URL-адресе, поэтому я считаю, что параметр пароля char[] дал бы вам ложное ощущение безопасности.

Если у вас есть реальный прецедент, когда пароль нужно как можно быстрее удалить из памяти, чтобы быть невосстановимым, и что в противном случае имеет смысл в контексте реального приложения JDBC, я бы с удовольствием его услышал. Я могу себе представить, что такая вещь может существовать, но я не могу придумать сценарий, в котором использование char[] действительно делает вещи более безопасными.

Ответ 6

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

Итак, если вы считаете, что должны хранить свои пароли в char [], вы все равно можете создать объект String из него до вызова getConnection(). Если реализация драйвера не сохраняет внутренний объект строки, она будет быстро недоступна и, таким образом, будет собрана довольно быстро. Единственный шанс прочитать его тогда - это проверить память JVM непосредственно там, где она еще может существовать. Поэтому вы правы в том, что использование char [] будет немного более безопасным, но не так много, поскольку пароль должен быть в какой-то момент в памяти.

т.е. очень простой способ захватить пароль с любым API-интерфейсом - это ввести поддельный SQL-драйвер и захватить пароль непосредственно в методе connect. Тот, кто сможет исследовать JVM-память, чтобы найти еще не перезаписанную строку пароля, также сможет вставлять модифицированную фразу-драйвер.