Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Poważny problem z mysql
Forum PHP.pl > Forum > Bazy danych > MySQL
denis94
Witam. Posiadam dość dużą stronę internetową. Osób online jest czasami ponad 200.
Strona jest pisana przeze mnie w php, zawiera dużo formularzy. Użytkownicy mogą sobie dodawać usuwać i wyświetlać informacje/rekordy zapisane w bazie mysql.

Od jakiegoś czasu użytkownicy skarżą się, że znikają im dane zapisane w bazie. Na stronie jest system tworzenia logów który zapisuje każdy ruch i akcję wykonaną na stronie. W logach nie ma żadnej informacji, że ktokolwiek coś usunął.

Wczoraj ze strony zniknęło kilka długich artykułów - dodatkowo dostęp do formularza który służy do usuwania tych artykułów posiadam tylko i wyłącznie ja tak więc nikt inny nie mógł ich usunąć.

Pisałem do administracji hostingu i dostałem odpowiedź, że rekordy w bazie nie mogą się same usuwać i mój skrypt jest prawdopodobnie podatny sql injection.

Podczas pisania skryptu zastosowałem różne zabezpieczenia, adslashes, warunki sprawdzające czy user ma odpowiednie prawa i czy treść którą chce usunąć należy do niego itp.

Dziwi mnie sytuacja z artykułami ponieważ tylko ja fizycznie mogę je usunąć.

Dziwne jest też też to, że logi nie rejestrują tych operacji tak więc wydaje mi się, że rekordy nie są usuwane przez stronę/skrypt tylko jakoś z zewnątrz.

Czy ktoś może spotkał się z podobną sytuacją? Zupełnie nie wiem czego to może być przyczyna. Proszę o pomoc.
erix
A blokowania tabel używasz? Transakcji?
denis94
Witam. Nie nie używam ani blokowania ani transakcji ale jeżeli myślisz, że to może być rozwiązaniem problemu to już biorę się za te zabezpieczenia.
Usuwanie rekordów zaczęło nasilać się coraz bardziej...

Na początku chciałbym blokować tabele z użytkownikami lecz nie na stałe a w taki sposób aby można było dokonywać SELECT lecz UPDATE byłby zablokowany.
Czy gdy użytkownik chce edytować swój profil tabela zawsze musi być odblokowywana?
Blokowanie całej tabeli może być chyba niedobre gdy użytkowników jest kilka tysięcy?

Proszę o pomoc.
kokers
a może ktoś po prostu ma dostęp do bazy, skoro wywołanie każdej akcji ma odkładać się w logach i nie ma sladu po tym.
denis94
Ta opcja jest najmniej prawdopodobna ponieważ nikt inny nie zna hasła użytkownika bazy i jest ono długie zawierające male jak i duze litery oraz cyfry.
kokers
wiesz, ja jeśli bym widziała że mi znika z bazy coś, wszystkie akcje które operują na danych z bazy były odkładane w logach, pierwsze co bym zrobiła to bym zmieniła hasło. Tak na wszelki wypadek ;o)

inna sprawa, czy w formularzach stosujesz ukryte id tych artykułów? Czy tuż przed wykonaniem operacji w bazie jest dodatkowe sprawdzenie uprawnień usera do danego wpisu?
denis94
Niestety w logach nic nie ma. Hasło zostało już zmienione kilka razy.
Gdy użytkownik chce edytować artykuł, przed wyświetleniem formularza jest sprawdzane czy artykuł należy do niego oraz po wysłaniu POST również.

Nie tyczy się to tylko "artykułów" ponieważ znikają także użytkownicy a nikt nie posiadający praw/konta administratora nie może ich usunąć.

Szukam w internecie coraz więcej informacji o mysql injection lecz zastosowałem już sporo zabezpieczeń.

Czy baza może "zwariować"? Czy istnieje opcja, że gdy baza zawiera sporo tabel i rekordów może zacząć "mylić" zapytanie SELECT z DELETE? (tak wiem, ze to pytanie jest dziwne ale głowię się z moim problemem od dawna i nic...)
kokers
nie przypominam sobie żadnej sytuacji nawet książkowej aby baza zwariowała ;o)
ale skoro znikają nie tylko artykuły, ale również wpisy w innych tabelach, to jedyne na co to może wyglądać to sql injection.

byc może to coś niecoś też rozjaśni i pomoże.
http://niebezpiecznik.pl/post/przewodnik-p...eveloperow-php/
denis94
Dziękuję, skorzystałem trochę z prezentacji. Niektóre z zabezpieczeń tam pokazanych miałem zastosowanych już wcześniej.

Przyszedł mi jeszcze jeden pomysł do głowy.
Mam ustawionego crona na skrypt który co 10 minut wyszukuje z pośród kilku tysięcy rekordów te, spełniające warunek WHERE a następnie je edytuje i wykonuje UPDATE. To wszystko w pętli for.
Czy możliwe jest, że ten skrypt może powodować usuwanie danych?

Atak sql injection wydaje się coraz mniej prawdopodobny ponieważ rekordy nie znikają jakoś równomiernie tylko np raz w tygodniu poleci 100 rekordów a potem jest kilka dni spokoju i znów...
Próbowałem samodzielnie dokonać ataku sql injection na moją stronę lecz nie udało mi się to nawet zmieniając dane post w locie. W każdym formularzu jest addlsahes, mysql_escape_string oraz valint (jeżeli potrzeba).

Jeżeli można już wykluczyć atak poprzez formularz zamieszczam cały skrypt który jest uruchamiany przez crona, może zrobiłem w nim jakiś głupi błąd którego nie potrafię odnaleźć. (tak wiem, bałagan w kodzie ale działa prawidłowo)

Skrypt sprawdza wszystkie APLIKACJE. Jeżeli APLIKACJA ma STATYSTYKI=1 to wtedy wtedy skrypt sprawdza czy w tabeli STATYSTYKI znajduje się dj o nazwie $dj. Jeżeli istnieje to go edytuje dodając mu 10 minut. Jeżeli go nie ma to go utworzy i doda mu 10 minut.

  1. <?php
  2. $starttime = time();
  3. // LACZENIE Z BAZA DANYCH
  4. function connect()
  5. {
  6. include('database.php');
  7. if (!($db = @mysql_pconnect($host, $user, $pass)))
  8. {
  9. return false;
  10. }
  11. if (!mysql_select_db($name, $db))
  12. {
  13. return false;
  14. }
  15. return $db;
  16. }
  17. $db = connect();
  18.  
  19. $zwieksz = 10; // ILE MINUT DODAWAĆ
  20. $blokowac = 6; // PO ILU SPRAWDZENIACH BLOKOWAC
  21. $zapytanie1 = "SELECT * FROM aplikacja WHERE statystyki>0 ORDER BY id ASC"; //pobranie rekordow
  22. $wynik1 = mysql_query($zapytanie1);
  23. if (!$wynik1 || mysql_num_rows($wynik1)<1)
  24. {
  25. echo "nie wykonano ";
  26. }else{
  27. for ($sip=0; $sip<mysql_num_rows($wynik1); $sip++)
  28. {
  29. $wiersz1 = mysql_fetch_array($wynik1);
  30. $haslo = addslashes($wiersz1['haslo']);
  31. $idaplikacji = stripslashes($wiersz1['id']);
  32. $ip = addslashes($wiersz1['ip']);
  33. $port = addslashes($wiersz1['port']);
  34. $dzien = addslashes($wiersz1['dzien']);
  35. $ileoffline = addslashes($wiersz1['ileoffline']);
  36. if($ip !== "" && $port !== "" && $haslo !== "")
  37. {
  38. echo "$idaplikacji<br>";
  39. $miesiac = date('n');
  40. $panelresult = "SELECT * FROM statystyki WHERE aplikacja='$idaplikacji' AND dj='$dj' AND miesiac='$miesiac'";
  41. $panelwynik = mysql_query($panelresult);
  42. if (!$panelwynik || mysql_num_rows($panelwynik)<1)
  43. {
  44. $zapytanielog = "INSERT INTO statystyki SET aplikacja='$idaplikacji', dj='$dj', minuty='$zwieksz', max='$ile', miesiac='$miesiac', stan='$stan'";
  45. $wyniklog = mysql_query($zapytanielog);
  46. }else{
  47. $wiersz = mysql_fetch_array($panelwynik);
  48. $minutydj = addslashes($wiersz['minuty']);
  49. $maxdj = addslashes($wiersz['max']);
  50. if($ile > $maxdj)
  51. {
  52. $max2 = $ile;
  53. }else{
  54. $max2 = $maxdj;
  55. }
  56. $suma = $minutydj+$zwieksz;
  57. $zapytanie2 = "update statystyki set minuty='$suma', max='$max2' WHERE idaplikacji='$idaplikacji' AND dj='$dj' AND miesiac='$miesiac'";
  58. $wynik2 = mysql_query($zapytanie2);
  59. }
  60.  
  61. if($dj == "off")
  62. {
  63. $dzien2 = date('dm');
  64. $io = $ileoffline+1;
  65. $zmien = mysql_query("UPDATE aplikacja SET dzien='$dzien2', ileoffline='$io' WHERE id='$idaplikacji'");
  66.  
  67. if($ileoffline >= $blokowac && $dzien2 == $dzien)
  68. {
  69. $zmien = mysql_query("UPDATE aplikacja SET dzien='0', ileoffline='0', statystyki='0' WHERE id='$idaplikacji'");
  70. // LOGI - ZAPIS
  71. $datalog = date("H:i d.m.Y");
  72. $zapytanielog2 = mysql_query("INSERT INTO logi SET apliakcja='$idaplikacji', login='<font color=\"red\">SYSTEM</font>', akcja='Zaktualizowano dj-a', data='$datalog', ip='system'");
  73. }
  74. }else{
  75. if($ileoffline !== "0" || $dzien !== "0")
  76. {
  77. $zmien = mysql_query("UPDATE aplikacja SET dzien='0', ileoffline='0' WHERE id='$idaplikacji'");
  78. }
  79. }
  80.  
  81. }
  82. $times = time();
  83. $times2 = $times-$starttime;
  84. if ($times2 > 120){ echo "Przekroczono czas !"; break;}
  85. }
  86. }
  87. ?>


Czy ograniczenie czasowe w skrypcie może mieć takie skutki?

Proszę o pomoc.
kokers
poza tym, że skrypt działa dla statystyki > 0 a nie =1 to nie widzę, aby on mógł powodowac kasowanie się kilkuset rekordów. Same selecty, updatey, inserty, dane updejtowane czy insertowane są z bazy, więc osobiście nie widze powodu, żeby ten skrypt był przyczyną.


niemniej jednak jeśli nie widzi się innej przyczyny to chyba jedynym rozwiązaniem nie wiedząc o co chodzi, gdzie chodzi etc jest coś ala:

http://stackoverflow.com/questions/303994/...ueries-in-mysql

Nie wiem tylko czy masz dostęp do wyciągnięcia tych logów.
denis94
Dzięki za odpowiedź.
Niestety pisałem już do administracji hostingu z prośbą o udostępnienie logów zapytań do bazy lecz dostałem odpowiedź, że takie logi nie są zapisywane ponieważ w bardzo szybkim tempie zajęły by ogromną ilość miejsca na dysku.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.