Piotr Owsiak

Piotr Owsiak
projektant/programis
ta .NET
(freelance/contrator
), pragma...

Temat: Access + VB

Paweł Łukasik:
Piotr Owsiak:

Jeśli robisz bazę na Access'ie to SQL Injection raczej będzie Twoim najmniejszym problemem.

Jak dla mnie to czy to jest aplikacja używana tylko przez jednego użytkownika czy miliony, to zabezpieczyć się trzeba. Jeśli to jakaś aplikacja "biznesowa", to możemy dostać zarzut, że nie chronimy danych odpowiednio. To tak kwestią wyjaśnień, dlaczego o tym wspomniałem.
>
Jasne, rozumiem, ale przy jedno-użytkownikowej aplikacji, gdzie ten użytkownik jest nam znany i pracuje pod jakimś nadzorem lub mamy do niego zaufanie (np. musimy, bo bazę Access ukraść to chyba nie jest problem dla takiego pracownika) to po prostu zabezpieczanie się przed SQL Injection jest dla mnie ostatnią rzeczą o której bym myślał.
W takiej sytuacji robienie backup'ów jest o wiele ważniejsze i rozwiązuje 90% problemów jakie można nam spowodować SQL Injection (przypadkowy lub też celowy).
Jeśli ktoś płaci za soft, to uważam, że taka "funkcjonalność" byłaby niewarta swojej ceny (powtarzam: w opisywanym konkretnym wypadku)
@Paweł Łukasik:
Z "View Details" dostajesz cały stack trace i pełniejszy obraz tego co się stało.
Sam "Message" to nie wszystko co mówi exception
To na pewno do mnie? Mam nadzieję, jednak że autor nie będzie wklejał tu całego StackTrace'a bo znając formatowanie GL i czasem wylewność tych komunikatów, będziemy mieli ładny kawałek tekstu do czytania.

Kiedy poprosiłem o stack trace, to napisałeś, że na screen'ie wszystko widać.
A ja jednak lubię rzucić okiem na stack trace zanim coś komuś poradzę.Piotr Owsiak edytował(a) ten post dnia 17.04.09 o godzinie 11:57

konto usunięte

Temat: Access + VB

Dobra. Nad SqlInjection nie mamy co debatować, bo nie wiemy jak będzie używana aplikacja.
Piotr Owsiak:
Kiedy poprosiłem o stack trace, to napisałeś, że na screen'ie wszystko widać.
A ja jednak lubię rzucić okiem na stack trace zanim coś komuś poradzę.

A co do powyższego to moja odpowiedź nie była skierowana do Ciebie tylko do autora wątku :)

konto usunięte

Temat: Access + VB

Aplikacja będzie używana przez 5-10 osób z mojego działu, którzy raczej nie znają sql'a, więc zagrożenie nie jest duże, ale gdyby ktoś podesłał link lub "łopatologicznie" wytłumaczył w jaki sposób wykonać takie zabezpieczenie byłbym wdzięczny. W sieci znalazłem kilka przykładów, ale kody były trochę mocno zagmatwane.

Mam jeszcze jedno pytanie, w jaki sposób połączyć sięz zaszyfrowaną bazą? Znalazłem coś takiego, że w stringu definiującym połączenie trzeba dodać "User ID=abc;Password=123;", ale bazę Accessa mam zaszyfrowaną tylko hasłem. Czy w przypadku Accessa jest na to inne rozwiązanie?
Marcin Miga

Marcin Miga Programista. Po
prostu programista.

Temat: Access + VB

Martin Nez:
Aplikacja będzie używana przez 5-10 osób z mojego działu, którzy raczej nie znają sql'a, więc zagrożenie nie jest duże, ale gdyby ktoś podesłał link lub "łopatologicznie" wytłumaczył w jaki sposób wykonać takie zabezpieczenie byłbym wdzięczny. W sieci znalazłem kilka przykładów, ale kody były trochę mocno zagmatwane.

Mam jeszcze jedno pytanie, w jaki sposób połączyć sięz zaszyfrowaną bazą? Znalazłem coś takiego, że w stringu definiującym połączenie trzeba dodać "User ID=abc;Password=123;", ale bazę Accessa mam zaszyfrowaną tylko hasłem. Czy w przypadku Accessa jest na to inne rozwiązanie?

Wbrew pozorom Access NIE JEST odporny na SQLInjection. Akurat niedawno linka o tym zapodał Krzysztof N. (MVP) na pl.comp.bazy-danych.msaccess. Radzę poczytać. A żeby się ustrzec, to radzę stosować parametry.

Co do hasła zaś, jest wielka różnica pomiędzy "Password=", a "Jet OLEDB:Database Password=". To pierwsze odnosi się do pliku grupy roboczej.

pozdrawiaMM
Piotr Owsiak

Piotr Owsiak
projektant/programis
ta .NET
(freelance/contrator
), pragma...

Temat: Access + VB

Martin Nez:
Aplikacja będzie używana przez 5-10 osób z mojego działu, którzy raczej nie znają sql'a, więc zagrożenie nie jest duże, ale gdyby ktoś podesłał link lub "łopatologicznie" wytłumaczył w jaki sposób wykonać takie zabezpieczenie byłbym wdzięczny. W sieci znalazłem kilka przykładów, ale kody były trochę mocno zagmatwane.

Mam jeszcze jedno pytanie, w jaki sposób połączyć sięz zaszyfrowaną bazą? Znalazłem coś takiego, że w stringu definiującym połączenie trzeba dodać "User ID=abc;Password=123;", ale bazę Accessa mam zaszyfrowaną tylko hasłem. Czy w przypadku Accessa jest na to inne rozwiązanie?

http://www.squealer.yoyo.pl/SQLInjection.pdf
Przeczytaj i pytaj jeśli coś nadal będzie niejasne.
Ewentualnie może podrzucisz nam jakiś kawałek kodu i na przykładzie Ci to wytłumacyzmy.

konto usunięte

Temat: Access + VB

No ok, to już wiem trochę o SQL Injection i jakie słowa kluczowe powinny zostać zablokowane. A ktoś wyjaśni o co chodzi z tymi parametrami? Może to bardziej praktyczny sposób na ochronę?
Poniżej kawałek kodu dla przykładu. ;]

Private Sub cbbPt_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cbbPt.SelectedIndexChanged
Dim NumerPt As String = cbbPt.Items(cbbPt.SelectedIndex)
Dim NumerDtp As New OleDbCommand("SELECT grafik FROM ustalenia WHERE pt = '" & NumerPt & "'", PolaczenieDtp)
Dim OsobaDtp As New OleDbCommand("SELECT nazwisko FROM graficy WHERE id = " & CStr(NumerDtp.ExecuteScalar()), PolaczenieDtp)
If PolaczenieDtp.State = ConnectionState.Open Then
tbxDtp.Text = CStr(OsobaDtp.ExecuteScalar())
ElseIf PolaczenieDtp.State = ConnectionState.Closed Then
tbxDtp.Text = "Brak połączenia z bazą."
End If

Dim NumerMan As New OleDbCommand("SELECT manager FROM ustalenia WHERE pt = '" & NumerPt & "'", PolaczenieDtp)
Dim OsobaMan As New OleDbCommand("SELECT nazwisko FROM managerowie WHERE id = " & CStr(NumerMan.ExecuteScalar()), PolaczenieDtp)
If PolaczenieDtp.State = ConnectionState.Open Then
tbxProdukcja.Text = CStr(OsobaMan.ExecuteScalar())
ElseIf PolaczenieDtp.State = ConnectionState.Closed Then
tbxProdukcja.Text = "Brak połączenia z bazą."
End If

Dim Ustalenie As New OleDbCommand("SELECT ustalenie FROM ustalenia WHERE pt = '" & NumerPt & "'", PolaczenieDtp)
If PolaczenieDtp.State = ConnectionState.Open Then
rtbUstalenie.Text = CStr(Ustalenie.ExecuteScalar())
ElseIf PolaczenieDtp.State = ConnectionState.Closed Then
rtbUstalenie.Text = "Brak połączenia z bazą."
End If
btnLista.Visible = False
tbxDtp.Enabled = True
tbxProdukcja.Enabled = True
rtbUstalenie.Enabled = True
End Sub
Piotr Owsiak

Piotr Owsiak
projektant/programis
ta .NET
(freelance/contrator
), pragma...

Temat: Access + VB

Martin Nez:
No ok, to już wiem trochę o SQL Injection i jakie słowa kluczowe powinny zostać zablokowane. A ktoś wyjaśni o co chodzi z tymi parametrami? Może to bardziej praktyczny sposób na ochronę?
Poniżej kawałek kodu dla przykładu. ;]

Private Sub cbbPt_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cbbPt.SelectedIndexChanged
Dim NumerPt As String = cbbPt.Items(cbbPt.SelectedIndex)
Dim NumerDtp As New OleDbCommand("SELECT grafik FROM ustalenia WHERE pt = '" & NumerPt & "'", PolaczenieDtp)
Dim OsobaDtp As New OleDbCommand("SELECT nazwisko FROM graficy WHERE id = " & CStr(NumerDtp.ExecuteScalar()), PolaczenieDtp)
If PolaczenieDtp.State = ConnectionState.Open Then
tbxDtp.Text = CStr(OsobaDtp.ExecuteScalar())
ElseIf PolaczenieDtp.State = ConnectionState.Closed Then
tbxDtp.Text = "Brak połączenia z bazą."
End If

Dim NumerMan As New OleDbCommand("SELECT manager FROM ustalenia WHERE pt = '" & NumerPt & "'", PolaczenieDtp)
Dim OsobaMan As New OleDbCommand("SELECT nazwisko FROM managerowie WHERE id = " & CStr(NumerMan.ExecuteScalar()), PolaczenieDtp)
If PolaczenieDtp.State = ConnectionState.Open Then
tbxProdukcja.Text = CStr(OsobaMan.ExecuteScalar())
ElseIf PolaczenieDtp.State = ConnectionState.Closed Then
tbxProdukcja.Text = "Brak połączenia z bazą."
End If

Dim Ustalenie As New OleDbCommand("SELECT ustalenie FROM ustalenia WHERE pt = '" & NumerPt & "'", PolaczenieDtp)
If PolaczenieDtp.State = ConnectionState.Open Then
rtbUstalenie.Text = CStr(Ustalenie.ExecuteScalar())
ElseIf PolaczenieDtp.State = ConnectionState.Closed Then
rtbUstalenie.Text = "Brak połączenia z bazą."
End If
btnLista.Visible = False
tbxDtp.Enabled = True
tbxProdukcja.Enabled = True
rtbUstalenie.Enabled = True
End Sub

Akurat ten kawałek kodu nie daje nam dużych możliwości, węc troszkę będę improwizował i naginał rzeczywistość ;-)
Skupmy sie na poniższych dwóch linijkach kodu:

...
Dim NumerPt As String = cbbPt.Items(cbbPt.SelectedIndex)
Dim NumerDtp As New OleDbCommand("SELECT grafik FROM ustalenia WHERE pt = '" & NumerPt & "'", PolaczenieDtp)
...


Otóż w Twoim wypadku jak się domyślam, to wartość będzie brana z listy (ComboBox) więc problemu raczej nie będzie, ale...
dla gdyby Twoja sytuacja wyglądała np. tak:


Dim NumerPt As String = tbxPt.Text
Dim NumerDtp As New OleDbCommand("SELECT grafik FROM ustalenia WHERE pt = '" & NumerPt & "'", PolaczenieDtp)


czyli użytkownik podaje numerek z ręki i nie jest on walidowany (tzn. pozwalamy na wprowadzenie nie tylko cyfr, ale i liter oraz innych znaków).

Wyobraź sobie, że ktoś w miejsce numeru wpisuje taki ciąg znaków:
1'; DROP ALL TABLES;

Co by się stało? Straciłbyś wszystkie tabele.
Oczywiście zakładając, że istnieje takie polecenie (DROP ALL TABLES) w MS Access'ie.
Ten przyład jest naginany, bo:
1) takie polecenie na 99,9% nie istnieje
2) Ponoć Access nie obsługuje tzw. stacked queries (czyli wykonywania wielu zapytań w jednym "strzale na bazę").
3) zakończnie zapytania średnikiem nie zadziała MS Access'ie (ponoć %00 może działać, ale tu znowu potrzebne jest środowisko web)

Kilka słów komentarza:
- SQL Injection jest trudnym atakiem i wymaga czasu, sprytu i wiedzy, bo każdy silnik bazy jest inny: MSSQL, MySQL, Access, etc., a do tego aplikacja musi "sprzyjać" atakowi - czyli gdzieś musi być miejsce na wciśnięcie własnych niebezpiecznych danych wejściowych, dlatego w przykładzie zmieniłem ComboBox'a na TextBox'a
- nie jestem ekspertem w tej dziedzinie i niestety nie mam Access'a, dlatego musisz wybaczyć mi fakt, że naginam rzeczywistość ;-P
- w praktyce trzebaby potestować całą aplikację na żywo (potencjalne miejsca zwiększonego ryzyka i możliwości ataku to np. formatka logowania oraz update'y rekordów)
- przykłady podawane w tutorialach o SQL Injection są celowo proste i rzadko w rzeczywistości atak jest tak prosty

Zakładam, że nia ma opcji abyś przesłał mi cały kod, dlatego na bazie mojego naginanego przykładu polecam rozejrzeć się po całej aplikacji, bo bardzo możliwe, że coś się znajdzie.
Piotr Owsiak

Piotr Owsiak
projektant/programis
ta .NET
(freelance/contrator
), pragma...

Temat: Access + VB

A co do parametrów, to dzięki ich stosowaniu nie musisz się martwić o tzw. niebezpieczne znaki (np. apostrof, czyli zamknięcie string'a)

Silnik bazy (albo sterownik) sam zajmie się takimi znakami.
Np. gdybyś w polu nazwisko wprowadził:
Mc'Donald
to w parametrze typu string zostałoby to zamienione na coś w stylu:
Mc\'Donald
lub
Mc''Donald
Jak dokładnie jest to zamianiane zależy już składni SQL'a
Proces ten popularnie określa się escaping (od słowa escape) gdzie np. w C++ w string'ach backslash (\) ma specjalne znacznie (np. \n to nowa lina, \t to znak tabulacji).
Zatem pojawia się pytanie jak w string'u zrobić znak backslash?
Bardzo prosto: stosując dwa obok siebie, czyli \\ będzie "wydrukowany" na ekranie jako pojedynczy znak.
Taki mechanizm dotyczy większości języków programowania (VB, PHP, itd.) gdzie znak odpowiedzialny za rozpoczęcie i zakończnie string'a musi być jakoś możliwy do umieszczenia w jego wnętrzu.
np.
print 'Mc\'Donald'
WriteLn ('Mc''Donald')
itd.

Mam nadzieję, że nie zagmatwałem za bardzo ;-)

konto usunięte

Temat: Access + VB

No tak, ale nadal nie wiem jak użyć tych parametrów. W necie znajduję przykłady, ale bez dokładniejszych opisów. Poniżej daję procedurkę, w której trzeba uzupełniać 2 pola ręcznie, może na tym przykładzie będzie lepiej wytłumaczyć.

Private Sub btnEdycjaOk_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEdycjaOk.Click
sql = "SELECT pt FROM ustalenia WHERE pt = '" & cbbEdycjaLista.SelectedItem.ToString & "'"
Dim pobierzPt As New OleDbCommand(sql, PolaczenieDtp)

sql = "SELECT grafik FROM ustalenia WHERE pt = '" & pobierzPt.ExecuteScalar() & "'"
Dim pobierzDtpNr As New OleDbCommand(sql, PolaczenieDtp)
sql = "SELECT nazwisko FROM graficy WHERE id = " & pobierzDtpNr.ExecuteScalar()
Dim pobierzDtp As New OleDbCommand(sql, PolaczenieDtp)
tbxEdytujDtp.Text = pobierzDtp.ExecuteScalar()

sql = "SELECT manager FROM ustalenia WHERE pt = '" & pobierzPt.ExecuteScalar() & "'"
Dim pobierzManNr As New OleDbCommand(sql, PolaczenieDtp)
sql = "SELECT nazwisko FROM managerowie WHERE id = " & pobierzManNr.ExecuteScalar()
Dim pobierzMan As New OleDbCommand(sql, PolaczenieDtp)
tbxEdycjaProdukcja.Text = pobierzMan.ExecuteScalar()

sql = "SELECT ustalenie FROM ustalenia WHERE pt = '" & pobierzPt.ExecuteScalar() & "'"
Dim pobierzUstalenie As New OleDbCommand(sql, PolaczenieDtp)
rtbEdycjaUstalenie.Text = pobierzUstalenie.ExecuteScalar()
End Sub

PS Dzisiaj na zajęciach miałem obsługę polecenia join w sql, ale jeszcze nie miałem czasu na delikatne zmiany w tej procedurze, więc nie śmiać się z kodu, jak wspominałem dopiero zaczynam się uczyć sql'a, więc robiłem po swojemu. ;]
Pozdr.
Marcin Miga

Marcin Miga Programista. Po
prostu programista.

Temat: Access + VB


sql = "SELECT pt FROM ustalenia WHERE pt = ?param_pt"
Dim pobierzPt As New OleDbCommand(sql, PolaczenieDtp)
pobierzPt.Parameters.AddWithValue("param_pt", cbbEdycjaLista.SelectedItem.ToString)
' itd...


pozdrawiaMM
PS. Nie pamiętam, jak się w OleDB daje parametry, i cxzy ma AddWithValue, ale raczej tak.Marcin Miga edytował(a) ten post dnia 25.04.09 o godzinie 23:58

konto usunięte

Temat: Access + VB

Wyszło mi coś takiego (na Googlach znalazłem, że powinien być "@" zamiast "?"), ale nadal nie działa...

sql = "SELECT nazwisko FROM graficy, ustalenia WHERE pt = @param_pt"
Dim OsobaDtp As New OleDbCommand(sql, PolaczenieDtp)
OsobaDtp.Parameters.AddWithValue("@param_pt", strSzukajWybrane)
If PolaczenieDtp.State = ConnectionState.Open Then
tbxDtp.Text = CStr(OsobaDtp.ExecuteScalar())
ElseIf PolaczenieDtp.State = ConnectionState.Closed Then
tbxDtp.Text = "Brak połączenia z bazą."
End If

Marcin: Może jednak bym Ci podesłał ten programik i poprawiłbyś chociaż jednąc procedurę na wzór? To nie jest żaden komercyjny program, więc z przesłaniem nie będzie problemu. ;]
Pozdr.
Marcin Miga

Marcin Miga Programista. Po
prostu programista.

Temat: Access + VB

Możesz podesłać, ale parametr w MS SQL daje się z @. W Accessie na pewno było jakoś inaczej, ale w .NET nie pisałem jeszcze dla Accessa. Poza tym masz teraz jakiegoś dziwnego SQL-a. Korzystasz z dwóch tabel, ale ich nie łączysz. Czyli masz na pewno iloraz kartezjański, czyli od groma rekordów. Filtrując jednostronnie po pt, to i tak ich sporo pozostaje - przynajmniej ilość w tej drugiej tabeli.
Na priva wysyłam aders mailowy (chociaż wystarczy przeszukać googla, aby go znaleźć :) ).
Piotr Owsiak

Piotr Owsiak
projektant/programis
ta .NET
(freelance/contrator
), pragma...

Temat: Access + VB

Martin Nez:
No tak, ale nadal nie wiem jak użyć tych parametrów. W necie znajduję przykłady, ale bez dokładniejszych opisów. Poniżej daję procedurkę, w której trzeba uzupełniać 2 pola ręcznie, może na tym przykładzie będzie lepiej wytłumaczyć.

Private Sub btnEdycjaOk_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEdycjaOk.Click
sql = "SELECT pt FROM ustalenia WHERE pt = '" & cbbEdycjaLista.SelectedItem.ToString & "'"
Dim pobierzPt As New OleDbCommand(sql, PolaczenieDtp)

sql = "SELECT grafik FROM ustalenia WHERE pt = '" & pobierzPt.ExecuteScalar() & "'"
Dim pobierzDtpNr As New OleDbCommand(sql, PolaczenieDtp)
sql = "SELECT nazwisko FROM graficy WHERE id = " & pobierzDtpNr.ExecuteScalar()
Dim pobierzDtp As New OleDbCommand(sql, PolaczenieDtp)
tbxEdytujDtp.Text = pobierzDtp.ExecuteScalar()

sql = "SELECT manager FROM ustalenia WHERE pt = '" & pobierzPt.ExecuteScalar() & "'"
Dim pobierzManNr As New OleDbCommand(sql, PolaczenieDtp)
sql = "SELECT nazwisko FROM managerowie WHERE id = " & pobierzManNr.ExecuteScalar()
Dim pobierzMan As New OleDbCommand(sql, PolaczenieDtp)
tbxEdycjaProdukcja.Text = pobierzMan.ExecuteScalar()

sql = "SELECT ustalenie FROM ustalenia WHERE pt = '" & pobierzPt.ExecuteScalar() & "'"
Dim pobierzUstalenie As New OleDbCommand(sql, PolaczenieDtp)
rtbEdycjaUstalenie.Text = pobierzUstalenie.ExecuteScalar()
End Sub

PS Dzisiaj na zajęciach miałem obsługę polecenia join w sql, ale jeszcze nie miałem czasu na delikatne zmiany w tej procedurze, więc nie śmiać się z kodu, jak wspominałem dopiero zaczynam się uczyć sql'a, więc robiłem po swojemu. ;]
Pozdr.

Hmmm... ale wykorzystujesz tylko 1 pole z formatki i to w dodatku nie uzupełniane z ręki, a ComboBox'a.

Następna dyskusja:

Microsoft WebMatrix - kwas ...




Wyślij zaproszenie do