Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [php]Ograniczenie dostępu do wybranych danych dla poszczególnych użytkowników
Forum PHP.pl > Forum > Przedszkole
Jarod
W skrócie: aplikacja wyświetla listę pracowników. Imię każdego pracownika to link (zawierający id pracownika), po kliknięciu którego wyświetlają się szczegółowe informacje na temat wybranego usera. Problem w tym, że każdy kierownik ma dostęp tylko do swoich pracowników. Ale można to ominąć poprzez manipulację numerem id pracownika w adresie url.

Zastanawiam się nad dodatkowym zapytaniem sql, które pobierałoby numery id pracowników, do których dany kierownik ma dostęp i po wybraniu usera a przed wyświetleniem danych sprawdzało, czy kierownik rzeczywiście ma dostęp do jego informacji. To na razie jedyne rozwiązanie, które przychodzi mi do głowy.

Macie inne pomysły?
piotrekkr
Jak masz tabele w bazie zbudowane?? Bycmoze ze masz przy id pracownika takze informacje z id kierownika wtedy sprawdzasz czy istnieje pracownik o podanym id oraz z id kierownika ktory przeglada baze aktualnie.

  1. SELECT COUNT(*) FROM pracownicy WHERE pracownik_id = $pracownik_id AND kierownik_id=$kierownik_id

no i jesli count zwroci zero to wiadomo ze ten kierownik nie moze ogladac info tego pracownika
Jarod
(...)

Odświeżam temat bo problem poniekąd istnieje nadal. Cała aplikacja napisana jest zgodnie z wzorcem MVC. Frontcontroller sprawdza przed odpaleniem akcji czy dany user może tą akcję wywołać. Jeśli nie to ładowana jest akcja domyślna, jeśli tak to ładowana jest akcja którą użytkownik wywołuje. To się sprawdza super.


Może wystąpić i często występuje sytuacja, że użytkownik mając dostęp do jakiejś akcji może mieć wgląd tylko do niektórych danych.
Tak jak opisywałem wcześniej, jest pewna ilość pracowników pracujących w różnych działach. Kierownik działu handlowego może mieć wgląd w info o pracownikach działów/sekcji/podziałów, które mu podlegają. Ale tu można manipulować numerami id czy nazwami działów poprzez adres url. Samo sprawdzanie uprawnień do akcji nie wystarczy. Bo skoro może akcję wywołać to i może także manipulować adresem - tu się wszyscy ze mną zgodzą..

Przed manipulacją numerami id w adresie url zabezpieczam się tak, że przed wyświetleniem danych wykonuję dodatkowe zapytanie sql - takie weryfikujące czy użytkownik może zobaczyć info na temat tego konkretnego usera.
Nie mogę zastosować rozwiązania podanego przez piotrekkr ze względu na budowę tabel.
Takie rozwiązanie sprawdza się.

Moje pytania:
1. Z biegiem czasu dochodzę do wniosku, że np. rozwiązanie, które zastosowałem jakiś czas temu może być "mało eleganckie". Tak jak powyższy sposób. Dlatego proszę o podpowiedzi w jaki sposób Wy się zabezpieczacie przed manipulacją danymi z adresu url. Na pewno na tym forum jest sporo ludzi, którzy pisali zaawansowane aplikacje, z podziałem uprawnień..

2. Zalogowany użytkownik może także manipulować danymi (nawet jeśli w pewnych miejscach programu opieram się na danych wysyłanych POSTem) poprzez odpowiednio spreparowany formularz. Jak się bronicie przed takim rodzajem manipulacji? Mógłbym zastosować rozwiązanie takie jak wyżej opisałem ale może są lepsze sposoby.

Budowanie aplikacji opartej na uprawnieniach to za mało w aplikacjach php. Niestety.
Pilsener
Cytat
Samo sprawdzanie uprawnień do akcji nie wystarczy. Bo skoro może akcję wywołać to i może także manipulować adresem
- no niezupełnie. Gdy wpisze nowy adres, to strona się przeładuje, więc treść zostanie stworzona na nowo. Musisz stworzyć relację typu przełożony||pracownik w bazie. np:

Kowalski||23
Nowak||78

- gdzie cyfra to numer kierownika. Kierownik o id 78 zobaczy tylko Nowaka, nie widzę takiej opcji, żeby miał zobaczyć Kowalskiego, a gdy podmieni jego numer w adresie to guzik zobaczy, bo pracowników filtrujesz po ID przełożonego, a id przełożonego nie przechowujesz w adresie, lecz w sesji.

Jeśli nie masz takiej relacji tabel to musisz niestety stosować dodatkowe zapytanie albo jakieś inne kombinowanie. Niestety często bazy są jakie są i nic się nie poradzi - ale mniej więcej w ten sposób należy postępować.

A co do POST to hmm... walidacja, walidacja i jeszcze raz walidacja. Definiowanie tego, co użytkownik może zrobić a dopiero potem wyświetlanie w zależności od otrzymanych zmiennych - tak, aby użytkownik nie miał żadneog wpływu na przydzieloną mu "kostkę". Na przykład w bazie masz ID||Tresc - metoda bezpośrednia czyli ID z formularza jako WHERE nie jest bezpieczna, bo user podmieniając ID może próbować dostać się do zakazanej treści. 100% bezpieczne jest stworzenie dla danego usera tablicy, która zawiera tylko część treści. Teraz jak user podmieni ID to nic nie zobaczy, chyba, że się przeloguje (mam nadzieję, że dobrze to wyklarowałem)
Jarod
Cytat(Pilsener @ 7.05.2008, 14:58:45 ) *
- no niezupełnie. Gdy wpisze nowy adres, to strona się przeładuje, więc treść zostanie stworzona na nowo. Musisz stworzyć relację typu przełożony||pracownik w bazie. np:

Kowalski||23
Nowak||78

- gdzie cyfra to numer kierownika. Kierownik o id 78 zobaczy tylko Nowaka, nie widzę takiej opcji, żeby miał zobaczyć Kowalskiego, a gdy podmieni jego numer w adresie to guzik zobaczy, bo pracowników filtrujesz po ID przełożonego, a id przełożonego nie przechowujesz w adresie, lecz w sesji.

Jeśli nie masz takiej relacji tabel to musisz niestety stosować dodatkowe zapytanie albo jakieś inne kombinowanie. Niestety często bazy są jakie są i nic się nie poradzi - ale mniej więcej w ten sposób należy postępować.

Rozumiem, ale nie mam takiej struktury tabel o czym pisałem wyżej - wolałbym uniknąc zmiany dlatego pytam się o jakieś sensowne inne rozwiązania.
W tym momencie przykładowy adres wygląda tak: http://serwer/main/PokazUsera/dzial/HAN/data/2008-04-01
i zostają wyświetleni pracownicy działu handlowego z informacjami z dnia 2008-04-01. Załóżmy, że kierownik ma dostęp tylko do działu HAN, ale nic nie stoi na przeszkodzie aby wywołał adres http://serwer/main/PokazUsera/dzial/MAR/data/2008-04-01 i zobaczy dane pracowników z działu marketingu. Zobaczy ponieważ ma dostęp do akcji PokazUsera więc kontroler ją odpali. Mam nadzieję, że jasno napisałem.



Cytat(Pilsener @ 7.05.2008, 14:58:45 ) *
A co do POST to hmm... walidacja, walidacja i jeszcze raz walidacja. Definiowanie tego, co użytkownik może zrobić a dopiero potem wyświetlanie w zależności od otrzymanych zmiennych - tak, aby użytkownik nie miał żadneog wpływu na przydzieloną mu "kostkę". Na przykład w bazie masz ID||Tresc - metoda bezpośrednia czyli ID z formularza jako WHERE nie jest bezpieczna, bo user podmieniając ID może próbować dostać się do zakazanej treści. 100% bezpieczne jest stworzenie dla danego usera tablicy, która zawiera tylko część treści. Teraz jak user podmieni ID to nic nie zobaczy, chyba, że się przeloguje (mam nadzieję, że dobrze to wyklarowałem)

Możesz jaśniej? Co masz na myśli pisząc walidacja. Wyobraź sobie sytuację że nasz opisywany Kierownik ma selecta ze skrótami działów, które może przeglądać. Dane przesyłane są postem, więc w id nie wstuka innego działu, np takiego do którego nie ma dostępu. Ale jak spreparuje formularz to mu się uda.
Pilsener
Co do pierwszego to jasno - niestety nie ma na to wygodniejszego sposobu, niż przydzielanie uprawnień na zasadzie:
pracownik 1||0||1||1||0 - itd.
pracownik 2||1||1||0||0 - itd. - najlepiej aby to było elastyczne i można było w każdej chwili dodać kolejne uprawnienie

Można też spróbować flagi:
pracownik 1||a||s||r||r
pracownik 2||a||c||d||z - np. pierwsze uprawnienie dotyczy dostępu do jednostek organizacyjnych. Flaga a - najmniejsze uprawnienia, z - największe. W dodatkowych tabelach definiujesz jaka flaga odpowiada za jakie uprawnienia lub coś w tym stylu.

Możesz zmodyfikować akcję "pokazusera" tak, aby wyświetlała tylko informacje w ramach uprawnień - ale to wiąże się praktycznie z jeszcze większą dawką zachodu niż zrobienie systemu uprawnień de novo - bo dla każdego kierownika będziesz robił jakiegoś ifa?

A propo walidacji - niech już będzie ten select. Kontrolkę select tworzysz na podstawie tablicy, następnie należy sprawdzić, czy $_POST['select']['wartosc'] istnieje w tej tablicy (funkcją in_array) - to jest właśnie walidacja, bo uniemożliwiamy podstawienie do selecta innej wartości, niż oczekujemy. Dane walidujemy na wszelkie strony i sposoby: usuwamy niedozwolone znaki, sprawdzamy typ, długość, częstość, gęstość - wszystko co się da.
Jarod
Cytat(Pilsener @ 7.05.2008, 20:09:36 ) *
Co do pierwszego to jasno - niestety nie ma na to wygodniejszego sposobu, niż przydzielanie uprawnień na zasadzie:
pracownik 1||0||1||1||0 - itd.
pracownik 2||1||1||0||0 - itd. - najlepiej aby to było elastyczne i można było w każdej chwili dodać kolejne uprawnienie

Można też spróbować flagi:
pracownik 1||a||s||r||r
pracownik 2||a||c||d||z - np. pierwsze uprawnienie dotyczy dostępu do jednostek organizacyjnych. Flaga a - najmniejsze uprawnienia, z - największe. W dodatkowych tabelach definiujesz jaka flaga odpowiada za jakie uprawnienia lub coś w tym stylu.


Kwestię uprawnień, które proponujesz rozważałem podczas pisania fw na swoje potrzeby. Był nawet osobny wątek poruszany na tym forum. Najlepszym rozwiązaniem jest definiowanie ról, które dodawane są do grup. Następnie do grup dodawani są użytkownicy. I tak to sobie zbudowałem i to naprawdę działa super. To co proponujesz jest moim zdaniem trochę "na wyrost" i mało elastyczne.
Generalnie przy problemie, który opisałem zdefiniowałem sobie tablicę, w której zapisane są numery pracownika z przypisanymi nazwami działów. Kierowników i dyrektorów nie jest dużo. Jedyne nad czym się zastanowię to czy nie przenieść tego do osobnej tabeli. Chyba zostanę przy moim sposobie czyli dodatkowe zapytanie sql - weryfikujące dostęp. Chyba nie jest to jakiś błąd ? winksmiley.jpg


Cytat(Pilsener @ 7.05.2008, 20:09:36 ) *
Możesz zmodyfikować akcję "pokazusera" tak, aby wyświetlała tylko informacje w ramach uprawnień

Nie za bardzo rozumię co masz na myśli...

Cytat(Pilsener @ 7.05.2008, 20:09:36 ) *
- ale to wiąże się praktycznie z jeszcze większą dawką zachodu niż zrobienie systemu uprawnień de novo - bo dla każdego kierownika będziesz robił jakiegoś ifa?

Nie muszę robić osobnego ifa dla każdego kierownika. Mam switch () i sprawdzam jaką rolę posiada. Moje role są sparametryzowane, czyli:
jakas_rola(user)
jakas_rola(kierownik)
jakas_rola(dyrektor)
jakas_rola(admin)

Cytat(Pilsener @ 7.05.2008, 20:09:36 ) *
A propo walidacji - niech już będzie ten select. Kontrolkę select tworzysz na podstawie tablicy, następnie należy sprawdzić, czy $_POST['select']['wartosc'] istnieje w tej tablicy (funkcją in_array) - to jest właśnie walidacja, bo uniemożliwiamy podstawienie do selecta innej wartości, niż oczekujemy.

No właśnie coś takiego robię przy walidacji danych z url'a (napisałem to kilka linijek wyżej), z tym, że musiałbym także zastosować to dodatkowe (weryfikujące) zapytanie sql winksmiley.jpg


Pozdrawiam
henio
Zastanawiałem się ostatnio nad zrobieniem w panelu administracyjnym blokady dostępu do niektórych podstron. Tak aby np administrator miał większe prawa.
Obecnie mam stworzoną tablicę z różnymi rodzajami redaktora np: Redaktor naczelny, Redaktor newsman itp I przy podstronach mam konstrukcje warunkową czy zalogowany użytkownik jest Administratorem itp I jeśli wynikiem jest fałsz to pokazuje się komunikat o braku dostępu.

Jednak taki sposób nie jest idealny, bo ktoś kto np jest newsmanem może odpowiadać za np za relacje live, ale nie każdy newsman ma takie obowiązki.

Stąd moje pytanie i jednocześnie prośba o Wasze rozwiązania tego problemu.

Od razu zaznaczę, że interesuje mnie bardziej pomysł niż gotowy skrypt.

--
Sposób, który był przedstawiony w tym wątku jest troche nie skuteczny. Ponieważ chciałbym mieć możliwość swobodnego udzielania uprawnień do konkretnych podstron każdemu użytkownikowi.
Jarod
No to role + parametry.. Tak jak opisywałem, był nawet osobny wątek na ten temat.. "ACL ...."
henio
Mogłbyś podać mi tytuł lub link do tego tematu bo znaleźć nie mogę
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.