yakamara / yform

YForm für REDAXO 5 – Formulare im Frontend und Backend mit Verwaltung von Datenbank-Tabellen.
MIT License
77 stars 55 forks source link

Table-Manager :: CSRF-Token Frontend vs. Backend #1295

Open skerbis opened 2 years ago

skerbis commented 2 years ago

Szenario: Ich versuche aus dem Frontend in die Editierung eines Datensatzes zu gelangen. Leider wird der CSRF-Token nicht akzeptiert.

Frage Da bereits geprüft wird ob die Person eingeloggt ist (egal ob im Frontend oder Backend) ist es denn wirklich zwingend erforderlich einen CSRF für den Aufruf des Datensatzes zu generieren? Wäre es nicht besser dies nur auf Speichern oder Löschen zu beschränken?

Code

if (rex_backend_login::hasSession() && $newsDataId != "") // REDAXO 5 Backend - Login - Check
{
  $table = rex_yform_manager_table::get('rex_news');
  $_csrf_key = $table->getCSRFKey();
  $_csrf_params = rex_csrf_token::factory($_csrf_key)->getUrlParams();
  $token =  $_csrf_params['_csrf_token'];    

    $edit = ' <a style="" class="uk-button uk-button-primary" href="' . rex_url::backendPage(
        'yform/manager/data_edit',
        [
            'table_name' => 'rex_news',
            'func' => 'edit',
            'data_id' => $newsDataId,
            '_csrf_token' => $token

        ]
    ) . '">
<i class="fal fa-edit"></i>
News bearbeiten</a>
                ';
}

Lösung aktuell, Tipp von @gharlan: Vor der CSRF-Generierung rex::setProperty('redaxo', true)aufrufen und danach wieder zurücksetzen mit false.

alxndr-w commented 2 years ago

Die Funktion des CSRF-Tokens besteht genau darin, dass man dem Redakteur nicht einfach was unterjubeln kann, während er eingeloggt ist - und deswegen ist es wichtig, dass der CSRF-Token auch im eingeloggten Zustand überprüft wird.

Ich habe in einem Projekt auch Frontend und Backend gleichzeitig eingeloggt (YCom + REDAXO-User) und kann problemlos einen Link ins Backend generieren, ohne mit setPropoerty arbeiten zu müssen.


    public function getBackendUrl(): string
    {
        $_csrf_key = rex_yform_manager_table::get('rex_gruppe')->getCSRFKey();
        $token = rex_csrf_token::factory($_csrf_key)->getUrlParams();

        $params = array();
        $params['table_name'] = 'rex_gruppe';
        $params['rex_yform_manager_popup'] = '0';
        $params['_csrf_token'] = $token['_csrf_token'];
        $params['data_id'] = $this->getId();
        $params['func'] = 'edit';

        return rex_url::backendPage('yform/manager/data_edit', $params);
    }
gharlan commented 2 years ago

Das wundert mich, dass es bei dir funktioniert. Ich kann das Problem von @skerbis nachvollziehen, und es erklärt sich für mich auch eigentlich im Code. Wenn ich deine getBackendUrl()-Method im Frontend aufrufe, erhalte ich eine URL mit nicht funktionierendem CSRF-Token.

Für mich ist auch fraglich, ob für den Aufruf der Edit-Maske wirklich schon ein CSRF-Token nötig sein sollte. Scheint mir unüblich und unpraktisch zu sein. Aber ggf. gibt es hier in yform trotzdem gute Gründe dafür, ich weiß es nicht genau.