Hello Everyone! I need help with creating a command, that will change password. I have simple authorization plugin. Here is the main.php PHP: <?phpnamespace wmpe;use pocketmine\plugin\PluginBase;use pocketmine\utils\Config;use pocketmine\utils\TextFormat as F;use pocketmine\command\Command;use pocketmine\command\CommandSender;use pocketmine\event\Listener;use pocketmine\event\player\PlayerMoveEvent;use pocketmine\event\player\PlayerChatEvent;use pocketmine\event\player\PlayerDropItemEvent;use pocketmine\event\player\PlayerJoinEvent;use pocketmine\event\player\PlayerQuitEvent;use pocketmine\event\player\PlayerCommandPreprocessEvent;use pocketmine\Player;use pocketmine\Server;use pocketmine\event\block\BlockBreakEvent;use pocketmine\event\player\PlayerInteractEvent; class wAuth extends PluginBase implements Listener { private $db, $users = array(), $reg = array(); public function onEnable() { if(!is_dir($this->getDataFolder())) @mkdir($this->getDataFolder()); $this->config = (new Config($this->getDataFolder()."config.yml", Config::YAML, ["salt" => "salt"]))->getAll(); $this->db = new \SQLite3($this->getDataFolder()."users.db"); $this->db->exec(stream_get_contents($this->getResource("database.sql"))); $this->getServer()->getPluginManager()->registerEvents($this, $this); } public function onPlayerMove(PlayerMoveEvent $event) { if(!isset($this->users[strtolower($event->getPlayer()->getName())])) $event->setCancelled(true); }public function onDrop(PlayerDropItemEvent $e){ if(!isset($this->users[strtolower($e->getPlayer()->getName())])) $e->setCancelled(true); }public function onBreak(BlockBreakEvent $e){ if(!isset($this->users[strtolower($e->getPlayer()->getName())])) $e->setCancelled(true);}public function onTap( PlayerInteractEvent $e){ if(!isset($this->users[strtolower($e->getPlayer()->getName())])) $e->setCancelled(true);} public function onPlayerJoin(PlayerJoinEvent $event) { $player = $event->getPlayer(); $sql = $this->db->prepare("SELECT * FROM `users` WHERE `nickname` = :nickname"); $sql->bindValue(":nickname", strtolower($player->getName()), SQLITE3_TEXT); $sql = $sql->execute(); $user = $sql->fetchArray(SQLITE3_ASSOC); if(isset($user["nickname"])) { $ip = $player->getAddress(); if($ip == $user["ipLast"]) { $this->users[strtolower($player->getName())] = [ "pass" => $user["password"], "ip" => $ip ]; $player->sendMessage("§8(§eMineWix§8)§f Вы уже вводили свой пароль! §aПриятной игры!");//you already enter your password. have a nice day! } else $player->sendMessage("§8(§eMineWix§8)§f Введите §bсвой пароль §fв чат, который вводили при регистрации.");//enter your password in chat } else $player->sendMessage("§8(§eMineWix§8)§f Придумайте и введите §bсвой пароль §fв чат, для регистрации.");//create new password(registration) $sql->finalize(); } public function onPlayerQuit(PlayerQuitEvent $event) { unset($this->users[strtolower($event->getPlayer()->getName())]); } public function onPlayerCommandPreprocess(PlayerCommandPreprocessEvent $event) { $login = "§8(§eMineWix§8)§f Введите §bсвой пароль §fв чат, который вводили при регистрации.";//enter your password in chat $player = $event->getPlayer(); $name = strtolower($player->getName()); $ip = $player->getAddress(); $msg = $event->getMessage(); if(!isset($this->users[$name])) { if(count(explode("/", $msg)) > 1) { $event->setCancelled(true); $player->sendMessage($login); } else { $msg = explode(" ", $msg); if(count($msg) == 1) { $sql = $this->db->prepare("SELECT * FROM `users` WHERE `nickname` = :nickname"); $sql->bindValue(":nickname", $name, SQLITE3_TEXT); $sql = $sql->execute(); if($sql instanceof \SQLite3Result) { $pass = crypt(md5($msg[0]), sha1($this->config["salt"])); $user = $sql->fetchArray(SQLITE3_ASSOC); if(!empty($user["nickname"])) { if($pass == $user["password"]) { $upd = $this->db->prepare("UPDATE `users` SET `ipLast` = :ip WHERE `nickname` = :nickname"); $upd->bindValue(":ip", $ip); $upd->bindValue(":nickname", $name); $upd = $upd->execute(); $upd->finalize(); $this->users[$name] = [ "pass" => $pass, "ip" => $ip ]; $player->sendMessage("§8(§eMineWix§8)§f Вы успешно §aавторизировались §fна сервере. Приятной игры!");//success } else $player->sendMessage("§8(§eMineWix§8)§f Вы ввели §cневерный пароль.");//unsuccess } else { if(!isset($this->reg[$name])) { $this->reg[$name] = $pass; $player->sendMessage("§8(§eMineWix§8)§f Введите §c<свой пароль> §fв чат повторно!");//enter your password again(registration) } else { if($pass == $this->reg[$name]) { $add = $this->db->prepare("INSERT INTO `users`(`nickname`, `password`, `ipReg`, `ipLast`) VALUES(:nickname, :password, :ip, :ip)"); $add->bindValue(":nickname", $name); $add->bindValue(":password", $pass); $add->bindValue(":ip", $ip); $add = $add->execute(); $add->finalize(); $this->users[$name] = [ "pass" => $pass, "ip" => $ip ]; $player->sendMessage("§8(§eMineWix§8)§f Вы успешно §aзарегистрировались, §fне забудьте свой пароль!");//success sign up } else { unset($this->reg[$name]); $player->sendMessage("§8(§eMineWix§8)§f Вы ввели §cневерный повторный пароль!§f Придумайте себе пароль снова и отправьте его в чат два раза.");//you entered wrong second password. create your password again and type it again } } } } $sql->finalize(); } else $player->sendMessage($login); } $event->setCancelled(true); } else { if($ip != $this->users[$name]["ip"]) { $event->setCancelled(true); $player->sendMessage($login); } }} }?>
Is that actually your plugin? If it is, I've never seen anyone with the knowledge of SQL facing such a simple issue. Anyway, from what I think your SQL table looks like, PHP: public function changePassword(string $playername, string $password){ $playername = strtolower($playername); $password = crypt(md5($password), sha1($this->config["salt"])); //$this->db->exec("UPDATE users SET password='$password' WHERE nickname='$playername'"); is what you must not be doing! $stmt = $this->db->prepare("UPDATE users SET password=? WHERE nickname=?"); $stmt->bind_param("ss", $password, $playername); $stmt->execute(); $stmt->close();}
What @SOFe means is by no means copy the code provided. Do not use that code. You should utilize prepared statements as you are already doing in the code you provided. If you copy the code, your server could become the target of an SQL injection attack.
Wait what? So everything should be prepared to avoid possible attacks? (Sounds interesting, didn't know there was a difference between preparing and directly executing )
Preparing escapes whatever you give it. You could also do PHP: $your_mysql_variable->real_escape_string($whatever_the_user_gives_you) and directly execute that
You may want to use libasynql, which offers convenient methods for both synchronous and asynchronous queries. Example for async prepared queries with libasynql (version: ^1.2): https://github.com/poggit/libasynql...seg/libasynql/poolexample/PoolExample.php#L65 Example for sync prepared queries with libasynql (version: ^1.2): PHP: MysqlResult::executeQuery($mysqli, "UPDATE users SET password = ? WHERE nickname = ?", [["s", $password], ["s", $nickname]]); Note that a big backward-incompatible change occurred in libasynql 2.0 update, so in your .poggit.yml, it's recommended that you use ^1.2 as the virion version.