Jak przechowywać nazwę użytkownika i hasło do API w opcji DB WordPress?

19

Obecnie opracowuję wtyczkę i istnieje duże prawdopodobieństwo, że wydam ją w publicznym repozytorium wtyczek, aby inni mogli z niej korzystać.

Wtyczka będzie korzystać z interfejsu API. Aby korzystać z tego interfejsu API, musisz podać nazwę użytkownika i hasło. Więc moja wtyczka musi przechowywać te dane logowania w bazie danych. Nie chcę przechowywać ich w postaci zwykłego tekstu, chociaż interfejs API potrzebuje ich w postaci zwykłego tekstu.

Więc moje pytanie brzmi: jak przechowywać te wrażliwe informacje? Hashowanie jest wyłączone, więc musi to być jakieś szyfrowanie.

Czy w WordPress istnieje unikalny klucz, którego można używać, który będzie się różnił między blogami? Jakich funkcji php należy używać do szyfrowania i deszyfrowania? Szukam funkcji, które bardziej niż prawdopodobne będą działać na wszystkich instalacjach WP.

Brady
źródło
3
To jest trochę nierozwiązywalne. Nie ma znaczenia, ile szyfrujesz, jeśli ma być odwracalne. Jeśli WP może go odszyfrować, a WP jest zagrożone, szyfrowanie nie ma znaczenia.
Rarst
Ale dlaczego Twój interfejs API musi znać hasło? Czy to nie wystarczy, jeśli interfejs API wie, że użytkownik zna hasło?
onetrickpony,
1
@One Trick Pony - Hasło musi być przechowywane, aby proces mógł zostać zautomatyzowany bez interwencji użytkownika.
Brady,
1
@Rarst - Zdaję sobie sprawę, że jeśli WP zostanie naruszone, hasła również. Nie mogę temu zapobiec. Mogę zapobiec temu, że jeśli zostanie uzyskany zrzut SQL, hasła nie będą miały zwykłego tekstu.
Brady,
@Brady tak, jeśli tylko zrzut SQL jest zagrożony, pomocne byłoby szyfrowanie. Jednak taki scenariusz wydaje mi się mało prawdopodobny. Jeśli masz dostęp do bazy danych, nie jest łatwo skompromitować WP.
Rarst

Odpowiedzi:

4

Chociaż zgadzam się z poprzednimi odpowiedziami, aby odpowiedzieć na faktycznie zadane pytanie, przychodzi mi na myśl użycie jednej z tych stałych dla wp-config.php:

Zdefiniuj („AUTH_KEY”, „redacted”);
Zdefiniuj („SECURE_AUTH_KEY”, „redacted”);
Zdefiniuj („LOGGED_IN_KEY”, „zredagowany”);
Zdefiniuj („NONCE_KEY”, „zredagowany”);

Mają być unikalne we wszystkich instalacjach wordpress - i dotyczą jedynych opcji wcześniejszych kluczy, które można znaleźć w wordpress. Alternatywą byłoby dodanie własnej podobnej stałej, która jest zbudowana przez zakodowanie jednego z nich z adresem e-mail administratora lub podobnym - a następnie przechowywanie tego w opcji ukrytego ustawienia - aby zabezpieczyć się przed zgubieniem klucza, jeśli ktoś przypadkowo zmodyfikuje klucze po twoim wtyczka jest zainstalowana. Niebezpieczeństwo polega na tym, że jeśli nie zostaną one unikalne przy pierwszej instalacji, ale administrator / właściciel witryny zdecyduje się naprawić błąd po fakcie, nie powinni przypadkowo złamać szyfrowania hasła.

Jeśli chodzi o funkcje szyfrowania / deszyfrowania - szybkie wyszukiwanie w Google zwraca następujący wykaz z kodem, który wydaje się pasować do rachunku: http://maxvergelli.wordpress.com/2010/02/17/easy-to-use-and-strong- szyfrowanie-deszyfrowanie-php-funkcje /

funkcja szyfrowania ($ input_string, $ key) {
    $ iv_size = mcrypt_get_iv_size (MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
    $ iv = mcrypt_create_iv ($ iv_size, MCRYPT_RAND);
    $ h_key = hash ('sha256', $ key, TRUE);
    return base64_encode (mcrypt_encrypt (MCRYPT_RIJNDAEL_256, $ h_key, $ input_string, MCRYPT_MODE_ECB, $ iv));
}

funkcja deszyfrowania ($ encrypted_input_string, $ key) {
    $ iv_size = mcrypt_get_iv_size (MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
    $ iv = mcrypt_create_iv ($ iv_size, MCRYPT_RAND);
    $ h_key = hash ('sha256', $ key, TRUE);
    return trim (mcrypt_decrypt (MCRYPT_RIJNDAEL_256, $ h_key, base64_decode ($ encrypted_input_string), MCRYPT_MODE_ECB, $ iv));
}

Oto dokumentacja zastosowanego tutaj szyfrowania AES: http://www.chilkatsoft.com/p/php_aes.asp

marfarma
źródło
4

To jest dokładnie okoliczność, dla której zaprojektowano OAuth.

Ze strony głównej OAuth :

Dla programistów usługodawców ...

Jeśli wspierasz ...

  • Aplikacje internetowe
  • interfejsy API po stronie serwera
  • mashups

Jeśli przechowujesz chronione dane w imieniu użytkowników, nie powinni oni rozpowszechniać swoich haseł w Internecie, aby uzyskać do nich dostęp. Użyj OAuth, aby dać użytkownikom dostęp do swoich danych, jednocześnie chroniąc poświadczenia konta.

Zaletą OAuth jest to, że nie musisz przechowywać hasła użytkownika. Kiedy po raz pierwszy konfigurują wtyczkę, są proszeni o zalogowanie się przy użyciu nazwy użytkownika i hasła za pośrednictwem aplikacji (zwykle strona hostowana na tym samym serwerze co interfejs API i załadowana albo do przekierowania strony, aplikacji typubox lub iframe) .

Gdy użytkownik jest zalogowany, serwer (twój system) tworzy bezpieczny klucz, którego jego system (WordPress) może użyć do połączenia z interfejsem API. Ten klucz jest unikalny dla konta użytkownika i witryny - i daje aplikacji (na WordPress) uprawnienia do robienia rzeczy z interfejsem API w imieniu użytkownika bez przekazywania ich informacji uwierzytelniających za każdym razem.

Jeśli chcesz zobaczyć przykład tego działania, sprawdź Jetpack .

Gdy aktywujesz wtyczkę, skarży się, że nie jest połączona. Kiedy go „łączysz”, wpisujesz swoje poświadczenia za pośrednictwem WordPress.com i konfigurujesz interakcję OAuth między WordPress i ich API.

Ale musisz to zrobić tylko raz, a nazwa użytkownika / hasło WordPress.com nigdy nie są przechowywane w lokalnej bazie danych WordPress.

EAMann
źródło
1
Byłoby miło z tego skorzystać, ale API, z którym mam do czynienia, nie jest moje i nie mają zainstalowanego systemu OAuth.
Brady,
1
W takim przypadku jedyną realną opcją jest zaakceptowanie konieczności przechowywania hasła w bazie danych i tego, czy zaszyfrujesz je, czy nie, tak naprawdę nie różni się ono istotnie od bezpieczeństwa. Jak inni wspominali powyżej, jeśli jest on w bazie danych, a szyfrowanie jest odwracalne, to każdy, kto ma dostęp do WordPress (legalny lub zhakowany) może go zdobyć.
EAMann
0

Jest to ważna kwestia, ponieważ wiele usług nadal nie obsługuje OAuth, a przechowywanie haseł w bazie danych opcji sprawia, że ​​są one czytelne dla każdej wtyczki Wordpress (patrz mój komentarz powyżej).

To nie jest (jeszcze) prawdziwa odpowiedź na pytanie, ale także zbyt długa na komentarz. Mam nadzieję zainicjować dyskusję na ten temat, aby znaleźć „najlepsze” możliwe rozwiązanie tego „nierozwiązywalnego” problemu.

Podstawowa idea, która każe mi myśleć, że szyfrowanie haseł jest możliwe, jest następująca:

Każdy użytkownik ma jedną tajną informację: hasło do Wordpress. Powinno być możliwe przechowywanie poświadczeń do usług stron trzecich zaszyfrowanych za pomocą tajnego formularza pochodnego tego hasła i odszyfrowanie ich tylko po zalogowaniu się użytkownika.

W ten sposób powinno być możliwe co najmniej uniemożliwienie kradzieży haseł z kopii plików i bazy danych Wordpress. Nie może rozwiązać problemu kradzieży poświadczeń przez inne wtyczki, ponieważ każda wtyczka może przechwycić hasło w postaci zwykłego tekstu podczas logowania.

W rzeczywistości odszyfrowanie jest dość łatwe: Załóżmy, że mamy już zaszyfrowaną wersję usługi innej firmy przechowywanej w bazie danych, możemy podłączyć się do 'authenticate'filtra lub zastąpić wp_authenticate()funkcję, wygenerować słony hash hasła użytkownika w postaci zwykłego tekstu (przez oznacza wp_hash_password()), przechowuj hasło jako klucz szyfrujący gdzieś prywatnie, dopóki użytkownik się nie wyloguje (użyj 'wp_logout'haka, aby usunąć klucz) i używaj go za każdym razem, gdy potrzebujemy hasła innej firmy do odszyfrowania zaszyfrowanej wartości w bazie danych.

Chociaż mam wrażenie, że powinno być możliwe wykonanie tej pracy, istnieje jednak kilka nierozwiązanych problemów:

  1. Jak wykonać szyfrowanie? Potencjalnie można przechowywać hasło w postaci zwykłego tekstu, dopóki użytkownik nie wyloguje się i nie wyloguje, a następnie nie wykona szyfrowania 'authenticate'. Użytkownik może zostać poproszony o zalogowanie się w celu zachowania krótkiego okresu.
  2. Gdzie przechowywać klucz i jak go usunąć podczas wylogowania? Czy rozumiem poprawnie, że 'authenticate'jest uruchamiany tylko wtedy, gdy użytkownik faktycznie się loguje?
  3. Jeśli istnieje teraz sposób na przechowywanie zaszyfrowanego hasła, może zamiast tego można uzyskać klucz z pliku cookie sesji?
  4. Kto zajmuje się zmianami haseł? Wygląda na to, że możliwe jest przechwycenie takich zmian hasła, a hasło innej firmy musiałoby zostać ponownie zaszyfrowane przy użyciu klucza pochodzącego z nowego hasła.
  5. Czy istnieje sposób na zapewnienie wsparcia wielu użytkownikom? Idealnie byłoby, gdyby administrator miał możliwość ustawiania haseł stron trzecich w ustawieniach, które mogą być następnie pozwane przez mniej uprzywilejowanych użytkowników do interakcji z usługami stron trzecich, najlepiej nawet bez ujawnienia im tych haseł. W tym celu administrator musiałby być w stanie wygenerować klucze dla wszystkich użytkowników, które inni użytkownicy mogą wygenerować tylko dla siebie. Czy to w jakiś sposób możliwe?
cgogolin
źródło