Помогите Проблемы с SQLite когда с MySQL все работает нормально. SQL error or missing database (no such colum

  • Автор темы Автор темы MySoR
  • Дата начала Дата начала

MySoR

Активный участник
Пользователь
Баллы
76
Имя в Minecraft
MySoR
У меня есть вот такой класс DataProvider https://pastebin.com/WKxsCec7 ,
Который отвечает за коммуникацию плагина с базой данных. Этот класс может работать как с SQLite так и с MySQL. Но проблема в том что при работе с MySQL проблем никаких нет и все Unit тесты проходят но когда я в настройках ставлю isMySqlEnabled false тоесть заставляю работать с SQLite то при сохранении клана мне выдает вот эту ошибку
Код:
java.sql.SQLException: [SQLITE_ERROR] SQL error or missing database (no such column: true)

    at org.sqlite.DB.newSQLException(DB.java:383)
    at org.sqlite.DB.newSQLException(DB.java:387)
    at org.sqlite.DB.throwex(DB.java:374)
    at org.sqlite.NativeDB.prepare(Native Method)
    at org.sqlite.DB.prepare(DB.java:123)
    at org.sqlite.Stmt.execute(Stmt.java:113)
    at com.lairon.xclans.data.DataProvider.saveClan(DataProvider.java:114)
    at DataProviderTests.fullClanTest(DataProviderTests.java:94)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
    at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
пишет что он не нашел колонку при использовании метода saveClan у DataProvider.

Юнит тесты: https://pastebin.com/5VDhP7nE

SQLite:
upload_2022-4-20_14-23-8.png
MySQL:
upload_2022-4-20_14-24-55.png

Пробовал удалять файлик с Базой SQLite не помогло
 
Ты пытаешься обратиться к полю с названием "true". Естественно, что такого поля нет.
Если не можешь понять, где ты его используешь - выведи на экран свой запрос после выполнения всех замен плейсхолдеров на параметры.

Но один важный момент - запросы так формировать нельзя. Ни в SQLite, ни в MySQL, ни где-либо ещё - ты ставишь под угрозу свой сервер. Почитай в интернете по запросу "SQL-инъекция".

В твоём случае необходимо заменить в строке запроса все конкретные значения параметров на знаки вопроса, а сами параметры устанавливать в запрос при помощи метода statement.setObject(). Данный метод присутствует у интерфейса PreparedStatement, поэтому тебе необходимо будет вместо connection.createStatement() использовать connection.prepareStatement()
 
Ты пытаешься обратиться к полю с названием "true". Естественно, что такого поля нет.
Если не можешь понять, где ты его используешь - выведи на экран свой запрос после выполнения всех замен плейсхолдеров на параметры.

Но один важный момент - запросы так формировать нельзя. Ни в SQLite, ни в MySQL, ни где-либо ещё - ты ставишь под угрозу свой сервер. Почитай в интернете по запросу "SQL-инъекция".

В твоём случае необходимо заменить в строке запроса все конкретные значения параметров на знаки вопроса, а сами параметры устанавливать в запрос при помощи метода statement.setObject(). Данный метод присутствует у интерфейса PreparedStatement, поэтому тебе необходимо будет вместо connection.createStatement() использовать connection.prepareStatement()
Заменил на PreparedStatement и все заработало как часы с обоими базами.
Про SQL инъекцию я знал не не думал что она работает именно так.
И кстати вывел SQL до момента изменения на PreparedStatement и он вроде бы был нормальный с виду да и MySql с ним работал хорошо.
Огромное спасибо
 
Но один важный момент - запросы так формировать нельзя. Ни в SQLite, ни в MySQL, ни где-либо ещё - ты ставишь под угрозу свой сервер. Почитай в интернете по запросу "SQL-инъекция".
Ну чтобы внедрить SQL-инъекцию это еще нужно сильно постараться. Особенно когда у тебя нет доступа к структуре БД, ты не знаешь какие там вообще таблицы и какие колонки, то вряд-ли что-то можно сделать. Или не?
 
Ну чтобы внедрить SQL-инъекцию это еще нужно сильно постараться. Особенно когда у тебя нет доступа к структуре БД, ты не знаешь какие там вообще таблицы и какие колонки, то вряд-ли что-то можно сделать. Или не?
Даже если и так, риск все равно будет.
Если представить что большинства используют таблицу с названием users, можно просто сделать что то вроде этого, при условии что запрос будет выглядеть так:

//Если представить что пользователь ввел в поле эти данные
String userName = "test; DROP TABLE users";
//Готовый запрос
String query = "SELECT * FROM users WHERE name = " + userName;


Или простым перебором таких иньекций, может быть какая та база и дропнится)
 
Ну чтобы внедрить SQL-инъекцию это еще нужно сильно постараться. Особенно когда у тебя нет доступа к структуре БД, ты не знаешь какие там вообще таблицы и какие колонки, то вряд-ли что-то можно сделать. Или не?
Существуют способы выяснения названий таблиц, столбцов и так далее (гугл в помощь). Не всегда это воплотимо, но, как написали выше, рисковать не стоит. Достаточно один раз привыкнуть не передавать параметры в строке. Это достаточно просто
 
Даже если и так, риск все равно будет.
Если представить что большинства используют таблицу с названием users, можно просто сделать что то вроде этого, при условии что запрос будет выглядеть так:

//Если представить что пользователь ввел в поле эти данные
String userName = "test; DROP TABLE users";
//Готовый запрос
String query = "SELECT * FROM users WHERE name = " + userName;


Или простым перебором таких иньекций, может быть какая та база и дропнится)
Кстати да) Так хорошо можно нашкодить
 
Существуют способы выяснения названий таблиц, столбцов и так далее (гугл в помощь). Не всегда это воплотимо, но, как написали выше, рисковать не стоит. Достаточно один раз привыкнуть не передавать параметры в строке. Это достаточно просто
Без вывода ошибок только наугад и гугл твой не поможет, яндекс тоже.
 
А что, ошибки никогда не выводятся? Специально для тебя написал "Не всегда это воплотимо"
Нет конечно, у игрока только стандартная ошибка команды будет и все. Так что инъекцию в плагине будет не так просто заюзать, как на сайтах где гореадмин не отключил логирование.
 
Последнее редактирование:
Нет конечно, у игрока только стандартная ошибка команды будет и все. Так что инъекцию в плагине будет не так просто заюзать, как на сайтах где гореадмин не отключил логирование.
Передавать параметры НЕ строкой нужно везде, включая сайты. Хватит на пустом месте полемику разводить
 
Передавать параметры НЕ строкой нужно везде, включая сайты. Хватит на пустом месте полемику разводить
Так это вы разводите, я лишь сказал, что проюзать инъекцию сложно без получения ошибок и ваши гуглы вам не помогут.
 
Назад
Верх