Tutorial: Własna wtyczka do WordPress na bardzo prostym przykładzie – część 4

Minął już jakiś czas od poprzedniej części, a wtyczka wciąż nie jest gotowa. Najwyższy czas zamknąć już ten drobny temat. Podsumowując więc, mamy prosty dodatek do WordPress, który łączy się z zewnętrznym API i podmienia tekst naszego posta. Zauważyłem jednak dwa problemy z obecną wersją.

Bezpieczeństwo

Kod naszej wtyczki nie jest zabezpieczony, a pliki są dostępne publicznie. W najłagodniejszym scenariuszu, ktoś może zwyczajnie używać Twojego kodu i wykonywać niechciane zapytania zarówno do Twojego serwera, jak i do API serwisu spolszcz.pl, niestety wciąż pod tożsamością naszej strony.

wp_4_1

Powyższy adres pokazuje nam pełnię możliwości do korzystania z naszego publicznego skryptu. Ta sama sytuacja ma miejsce, gdy nasz dodatek funkcjonuje pod każdym realnym adresem www. Na szybko do głowy przychodzą mi dwa rozwiązania. Można w skrypcie sprawdzać czy zapytanie przychodzi z naszego serwera. Inne podejście wykorzystuje fakt, że nasz skrypt konsumujemy przy użyciu AJAX. Warto więc w skrypcie sprawdzać, czy zapytanie zostało wykonane właśnie w ten sposób.


if(empty($_SERVER['HTTP_X_REQUESTED_WITH']) || strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest') {
   die;
}

Zapytanie ajax jest oflagowanie nagłówkiem http X-Requested-With i w PHP możemy sprawdzić jego zawartość właśnie w powyższy sposób.

Czy już możemy spać spokojnie? Niestety nie, bo nagłówki takich zapytań, a nawet adres przychodzący (Referer) można bez problemu podrobić. Szybki test udowadnia, że świat nie jest idealny:

wp_4

Dodałem powyższy komunikat w celu sprawdzenia, czy to nieco naiwne zabezpieczenie zadziała. Następnie przy użyciu polecenia curl z linii komend wysyłam zapytanie do skryptu wcześniej umieszczonego na moim serwerze ftp.

curl_wp_spolszczpl_test

Nie znam prostego sposobu na zaszyfrowanie tego. Przychodzi mi do głowy generowanie jakiejś wartości w skrypcie js naszej wtyczki, a następnie sprawdzanie jej w skrypcie wg ustalonego algorytmu, ale to chyba za dużo jak na tak prosty plugin. Być może jednak to dobry temat na oddzielny wpis!

Przycisk nie zawsze działa?

Okazuje się, że nasze rozwiązanie działa jedynie w trybie „tekstowym” edycji posta. W trybie „wizualnym” za edycje tekstu odpowiada oddzielny skrypt, więc prawdopodobnie będzie trzeba dobrać się właśnie do niego, żeby uzyskać dostęp do treści rzeźbionego posta. Spójrzmy więc do dokumentacji tiny_mce, który to skrypt właśnie jest używany w WordPress do wizualnej edycji postów.

function isTinyMCEEnabled()
{
	var contentWrapper = jQuery('#wp-content-wrap');
	return !contentWrapper.hasClass('html-active');
}

Zaczynam od ustalenia, w którym widoku aktualnie jesteśmy. Jednym że sposobów jest sprawdzenie klasy na elemencie otaczającym edytor wysiwg. Tego typu logiką pozwala nam na zastosowanie odpowiedniej ścieżki działania:

function getContent()
{
	if(isTinyMCEEnabled())
	{
		return tinyMCE.activeEditor.getContent();
	}
	else
	{
		return jQuery('#content').val();
	}
}

function setContent(newContent)
{
	if(isTinyMCEEnabled())
	{
		tinyMCE.activeEditor.setContent(newContent);
	}
	else
	{
		jQuery('#content').val(newContent);
	}
}

Jak widać powyżej, API edytora tinyMCE okazało się bardzo przyjazne i w prosty sposób pozwala na odczyt i modyfikację treści. Szybki test potwierdza, że teraz nasz dodatek działa w obu przypadkach. Bardzo dobrze!
Jeżeli właśnie to czytasz i masz więcej pomysłów jak usprawnić tą wtyczkę lub poprawić zabezpieczenia, chętnie poznam Twoją opinię!

Tym samym jest to ostatnia część tej mini serii. Jeżeli potrzebujesz tej wtyczki lub coś jest dla Ciebie niezrozumiałe, przypominam, że poszczególne kroki i cały, działający kod źródłowy znajduje się w tym repozytorium. Zapraszam również do kontaktu jeżeli masz jakieś sugestie lub pytania!