Witam,
piszę mały skrypt i utknąłem na curl, mianowicie jest chyba jakieś zabezpieczenie na stronie:
https://www2.coinmine.pl/dcr/index.php?page=login
próbuje przekazać w curl username i password lecz się nie udaje. Zauważyłem, że strona w klasie logowania generuje input (ctoken) o różnych wartościach przy każdym odświeżeniu strony, wiecie co to może być i jak rozwiązać tą zagadkę?, wystarczy ściągnąć wartość ctoken i wysłać ją metodą post z loginem i hasłem?, czy jest tutaj jakieś inne rozwiązanie?.
I słusznie, to jest w miarę proste zabezpieczenie przed botami i wrednymi spamerami. Stawiam że jest to coś jak CSRF token, robiłem już podobne zabiegi w pewnym serwisie. Normalnie np. może być generowany unikatowy klucz po czym zapisywany w sesji i ważny aż do jej wygaśnięcia, można również za każdym odświeżeniem generować nowy klucz, który potem będzie sprawdzany przy wysyłaniu danych za pomocą POST w formularzu, klucz będzie przedtem jednak zapisany w sesji, inaczej nie można by zweryfikować poprawności. Dokładnie przeglądałem jak to jest zrealizowane w jednym z frameworków z użyciem którego pisałem serwis.
drorat1 napisał(a):
I słusznie, to jest w miarę proste zabezpieczenie przed botami i wrednymi spamerami. Stawiam że jest to coś jak CSRF token, robiłem już podobne zabiegi w pewnym serwisie. Normalnie np. może być generowany unikatowy klucz po czym zapisywany w sesji i ważny aż do jej wygaśnięcia, można również za każdym odświeżeniem generować nowy klucz, który potem będzie sprawdzany przy wysyłaniu danych za pomocą POST w formularzu, klucz będzie przedtem jednak zapisany w sesji, inaczej nie można by zweryfikować poprawności. Dokładnie przeglądałem jak to jest zrealizowane w jednym z frameworków z użyciem którego pisałem serwis.
To jak sczytam tą wartość i ją przekaże przez post to powinno pójść ?.
Świetny Kot napisał(a):
To jak sczytam tą wartość i ją przekaże przez post to powinno pójść ?.
A to Ci powiem że sam przed chwilą sprawdzałem na takim kodzie (Kohana Framework):
class Controller_Test extends Controller
{
public function action_index()
{
$session = Session::instance();
$this->response->headers('Content-Type', 'text/plain');
if ($this->request->method() == HTTP_Request::POST)
{
// sprawdzanie CSRF zapisanego w sesji
$csrf1 = $this->request->post('csrf');
$csrf2 = $session->get('csrf');
echo $csrf1;
echo "\n";
echo $csrf2;
}
else // HTTP_Request::GET
{
// generowanie nowego CSRF i zapis do sesji
$csrf = md5(uniqid());
$session->set('csrf', $csrf);
echo $csrf;
}
}
}
Wrzuciłem to sobie na serwer gdzie mam stronę (na Kohanie) żeby było łatwiej i sprawdzałem przy użyciu CURL z linii poleceń:
- Metoda GET, z użyciem ciasteczka, zapis ciasteczka do pliku tekstowego:
curl -c cookie.txt http://jakasmojastrona/test
i wypluło mi (akurat to wygenerowało):
6435150f08434bb3c7ccd6bdbbe90697
- Wysłałem ten CSRF za pomocą POST do tego samego adresu, z użyciem zapisanego wcześniej cookie:
curl -b cookie.txt http://jakasmojastrona/test -X
POST -d csrf=6435150f08434bb3c7ccd6bdbbe90697
i wynik:
6435150f08434bb3c7ccd6bdbbe90697
6435150f08434bb3c7ccd6bdbbe90697
Wygląda mi na to że CSRF nie jest tu żadnym zabezpieczeniem przed takimi akcjami z botami opartymi o CURL i to nawet kiedy za każdym odświeżeniem ta wartość się zmienia.
Jeżeli jesteś zainteresowany bezpieczeństwem i dobrej jakości kodem to polecam zerknąć na ten framework MVC, ORM do php.
https://github.com/letsdrink/ouzo
plik Routes.php
Route::get('/test', 'person#method');
plik PersonController.php
use Ouzo\Controller;
use Ouzo\Csrf\CsrfProtector;
class PersonController extends Controller
{
function method()
{
$csrf = new CsrfProtector();
$csrf->protect($this);
$this->render('Layout/success');
}
}
Plik success
<html>
<body>
Udało się
</body>
</html>
Albo skorzystać z fajnej biblioteki posiadającej masę przydatnych funkcji operujących na arrayach, funkcjach, comparatorach, testach jednostkowych, zegarze i kilku innych przydatych rzeczach.
Ale biorąc pod uwagę tą metodę z klasy CsrfProtector:
public static function validate()
{
$csrfToken = self::getCsrfToken();
if (!isset($_COOKIE['csrftoken']) || $_COOKIE['csrftoken'] != $csrfToken) {
self::_throwException();
}
$headerToken = Arrays::getValue(RequestHeaders::all(), 'X-Csrftoken');
$postToken = Arrays::getValue($_POST, 'csrftoken');
if ($headerToken != $csrfToken && $postToken != $csrfToken) {
self::_throwException();
}
}
oraz to:
curl -b mycookie.txt -X POST http://jakasstrona/test -d "csrf=rjEGrwahdEP%2BG6XDFt7ihFxT6Fy4mX34P/mCAyAK7mo=" -H "X-Csrftoken: rjEGrwahdEP+G6XDFt7ihFxT6Fy4mX34P/mCAyAK7mo="
widać że i z tym CURL sobie poradzi. W Kohanie (3.3) generowanie CSRF jest zresztą podobne:
system/classes/Kohana/Security.php:
public static function token($new = FALSE)
{
$session = Session::instance();
// Get the current token
$token = $session->get(Security::$token_name);
if ($new === TRUE OR ! $token)
{
// Generate a new unique token
if (function_exists('openssl_random_pseudo_bytes'))
{
// Generate a random pseudo bytes token if openssl_random_pseudo_bytes is available
// This is more secure than uniqid, because uniqid relies on microtime, which is predictable
$token = base64_encode(openssl_random_pseudo_bytes(32));
}
else
{
// Otherwise, fall back to a hashed uniqid
$token = sha1(uniqid(NULL, TRUE));
}
// Store the new token
$session->set(Security::$token_name, $token);
}
return $token;
}
Więc też podobnie jak w tym Ouzo,