Java - escape - строка для предотвращения SQL-инъекции
Я пытаюсь внедрить некоторые средства защиты от sql-инъекции в Java, и мне очень сложно работать со строковой функцией "replaceAll". В конечном итоге мне нужна функция, которая преобразует любую существующую \ в \\, any " в \", any ' в \' и any \n в \\n, чтобы при вычислении строки MySQL SQL-инъекции блокировались.
Я доработал некоторый код, с которым работал, и от всего \\\\\\\\\\\ в функции у меня глаза разбегаются. Если у кого-нибудь случайно есть пример этого, я был бы очень признателен.
Переведено автоматически
Ответ 1
Лучше всего использовать PreparedStatements, потому что они делают SQL-инъекцию невозможной. Вот простой пример, в котором в качестве параметров используются входные данные пользователя.:
Независимо от того, какие символы содержатся в имени пользователя и адресе электронной почты, эти символы будут помещены непосредственно в базу данных. Они никоим образом не повлияют на инструкцию INSERT .
Существуют разные методы set для разных типов данных - какой из них вы используете, зависит от того, каковы поля вашей базы данных. Например, если у вас в базе данных есть столбец INTEGER, вам следует использовать setInt метод. В документации PreparedStatement перечислены все различные методы, доступные для настройки и получения данных.
Ответ 2
Единственный способ предотвратить SQL-внедрение - это параметризованный SQL. Просто невозможно создать фильтр, который был бы умнее людей, зарабатывающих на жизнь взломом SQL.
Поэтому используйте параметры для всех предложений ввода, обновлений и where. Динамический SQL - это просто открытая дверь для хакеров, и это включает динамический SQL в хранимые процедуры. Параметризуйте, параметризуйте, параметризуйте.
Не пишите свои собственные средства управления безопасностью! Изобретать велосипед заново, когда дело доходит до разработки средств управления безопасностью для каждого веб-приложения или веб-службы, приводит к потере времени и огромным дырам в системе безопасности. Наборы инструментов OWASP Enterprise Security API (ESAPI) помогают разработчикам программного обеспечения защититься от недостатков проектирования и реализации, связанных с безопасностью.
(Это в ответ на комментарий OP под исходным вопросом; Я полностью согласен с тем, что PreparedStatement - это инструмент для этой работы, а не регулярные выражения.)
Когда вы говорите \n, вы имеете в виду последовательность \+n или фактический символ перевода строки? Если это \+n, задача довольно проста:
s = s.replaceAll("['\"\\\\]", "\\\\$0");
Чтобы сопоставить одну обратную косую черту во входных данных, вы помещаете четыре из них в строку регулярного выражения. Чтобы поместить одну обратную косую черту в выходных данных, вы помещаете четыре из них в строку замены. Предполагается, что вы создаете регулярные выражения и замены в форме строковых литералов Java. Если вы создаете их любым другим способом (например, путем чтения из файла), вам не нужно выполнять все эти двойные экранирования.
Если у вас есть символ перевода строки во входных данных и вы хотите заменить его escape-последовательностью, вы можете выполнить второй проход по входным данным с помощью этого:
s = s.replaceAll("\n", "\\\\n");
Или, может быть, вам нужны две обратные косые черты (я не слишком разбираюсь в этом):