1. Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.
    Скрыть объявление
Скрыть объявление
В преддверии глобального обновления, мы проводим исследования, которые помогут нам сделать опыт пользования форумом ещё удобнее. Помогите нам, примите участие!

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

Тема в разделе "Разработка плагинов для новичков", создана пользователем MySoR, 20 апр 2022.

  1. Автор темы
    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 не помогло
     
  2. Dymeth

    Dymeth Активный участник Пользователь

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

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

    В твоём случае необходимо заменить в строке запроса все конкретные значения параметров на знаки вопроса, а сами параметры устанавливать в запрос при помощи метода statement.setObject(). Данный метод присутствует у интерфейса PreparedStatement, поэтому тебе необходимо будет вместо connection.createStatement() использовать connection.prepareStatement()
     
  3. Автор темы
    MySoR

    MySoR Активный участник Пользователь

    Баллы:
    76
    Имя в Minecraft:
    MySoR
    Заменил на PreparedStatement и все заработало как часы с обоими базами.
    Про SQL инъекцию я знал не не думал что она работает именно так.
    И кстати вывел SQL до момента изменения на PreparedStatement и он вроде бы был нормальный с виду да и MySql с ним работал хорошо.
    Огромное спасибо
     
  4. NuaN

    NuaN Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    NuaN
    Ну чтобы внедрить SQL-инъекцию это еще нужно сильно постараться. Особенно когда у тебя нет доступа к структуре БД, ты не знаешь какие там вообще таблицы и какие колонки, то вряд-ли что-то можно сделать. Или не?
     
  5. MurlikMurlik

    MurlikMurlik Активный участник Пользователь

    Баллы:
    96
    Даже если и так, риск все равно будет.
    Если представить что большинства используют таблицу с названием users, можно просто сделать что то вроде этого, при условии что запрос будет выглядеть так:

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


    Или простым перебором таких иньекций, может быть какая та база и дропнится)
     
  6. Dymeth

    Dymeth Активный участник Пользователь

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    Существуют способы выяснения названий таблиц, столбцов и так далее (гугл в помощь). Не всегда это воплотимо, но, как написали выше, рисковать не стоит. Достаточно один раз привыкнуть не передавать параметры в строке. Это достаточно просто
     
  7. NuaN

    NuaN Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    NuaN
    Кстати да) Так хорошо можно нашкодить
     
  8. alexandrage

    alexandrage Старожил Пользователь

    Баллы:
    173
    Без вывода ошибок только наугад и гугл твой не поможет, яндекс тоже.
     
  9. Dymeth

    Dymeth Активный участник Пользователь

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    А что, ошибки никогда не выводятся? Специально для тебя написал "Не всегда это воплотимо"
     
  10. alexandrage

    alexandrage Старожил Пользователь

    Баллы:
    173
    Нет конечно, у игрока только стандартная ошибка команды будет и все. Так что инъекцию в плагине будет не так просто заюзать, как на сайтах где гореадмин не отключил логирование.
     
    Последнее редактирование: 22 апр 2022
  11. Dymeth

    Dymeth Активный участник Пользователь

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    Передавать параметры НЕ строкой нужно везде, включая сайты. Хватит на пустом месте полемику разводить
     
  12. alexandrage

    alexandrage Старожил Пользователь

    Баллы:
    173
    Так это вы разводите, я лишь сказал, что проюзать инъекцию сложно без получения ошибок и ваши гуглы вам не помогут.
     

Поделиться этой страницей