TransbankDevelopers / transbank-sdk-php

Código fuente Transbank SDK para PHP
BSD 3-Clause "New" or "Revised" License
56 stars 30 forks source link

Laravel anulación de la transacción cierra la sesión del usuario actual. #211

Closed huenchunb closed 3 years ago

huenchunb commented 3 years ago

Tengo una aplicación en Laravel ejecutando pagos correctamente, ahora cuando necesito ejecutar una anulación de la transacción, en caso de que el usuario se arrepienta y quiera anular, al volver a la página de redirección que entrego al momento de crear la transacción, la sesión actual que tengo abierta en Laravel se cierra, y eso causa un error, ya que, tengo consultas con Eloquent y Guard que no se ejecutan al cerrarse la sesión.

No entiendo porque ocurre esto, ya que, son dos aplicaciones distintas y la api de Transkbank solo debería darme una respuesta y no influir en mi sesión de Laravel.

Para realizar pagos funciona correctamente, pero al momento de redirigir a Transkbank y hacer click en anular transacción, me redirecciona a la url que entregue al momento de crear la transacción pero me arroja error.


Adjunto una pequeña captura de una parte del codigo que confirma la respuesta desde transkbank.

Capturas de pantalla

SharedScreenshot

Versiones

ffflabs commented 3 years ago

No es que Transbank esté metiéndose con tu sesión. Es justo al contrario. La petición con que el visitante es devuelto a tu sitio, via POST, se trata como si viniera de una pestaña de incógnito.

Esto no depende de Transbank. Es una medida que se anunció previo al release de Chrome 80 (Firefox empezó a hacer lo mismo poco después), y afecta al atributo SameSite de las Cookies. El default ya no es SameSite: None sino SameSite: Lax

La idea de fondo es que si visito un sitio malicioso éste no pueda gatillar, disimuladamente, un request que le permita ver dónde estoy logueado. Esto es lo normal en peticiones fetch/xhr, pero desde el cambio que menciono también afecta, por ejemplo, a los formularios y los iframes.

Cookies are not sent on normal cross-site subrequests (for example to load images or frames into a third party site), but are sent when a user is navigating to the origin site (i.e. when following a link).

(O sea, sólo se mandan cookies cuando hay navegación acompañando al request) Y luego:

Lax replaced None as the default value in order to ensure that users have reasonably robust defense against some classes of cross-site request forgery (CSRF) attacks.

Junto con ese anuncio de Chrome 80, algunos párrafos más abajo explican que "por mientras" van a dejar que las peticiones POST sigan igual que antes, para no romper algunos sistemas de SSO. Y nunca dijeron hasta cuándo duraba "por mientras"

Q: What is the Lax + POST mitigation? This is a specific exception made to account for existing cookie usage on some Single Sign-On implementations where a CSRF token is expected on a cross-site POST request. This is purely a temporary solution and will be removed in the future. It does not add any new behavior, but instead is just not applying the new SameSite=Lax default in certain scenarios.


Si tu sitio se sirve con https, puedes declarar que la cookie de sessión tenga SameSite: None. Además, creo que SameSite es un setting para la cookie de sesión soportado desde PHP 7.3 en adelante, pero no estoy seguro.

Otra alternativa es un workaround que no requiera estar logueado al recibir el POST. Por ejemplo... tomar el token del body y redirigir mediante GET a una URL pasando el token como query string o como header.

gdespirito commented 3 years ago

Exactamente.

Eso pasa porque la redirección desde Transbank a tu sitio web es a través de POST. Ahora con la Api 1.2 en teoría es por GET, pero algunos casos de borde, como el anular una transacción en el formulario aun redirigen por POST

gdespirito commented 3 years ago

De momento asegurate de tener tus cookies como SameSite=none y Secure = true; para evitar el problema

huenchunb commented 3 years ago

Hasta el momento estamos manejando el error de otra manera pero tomaré en cuenta sus indicaciones. Gracias.

huenchunb commented 3 years ago

No es que Transbank esté metiéndose con tu sesión. Es justo al contrario. La petición con que el visitante es devuelto a tu sitio, via POST, se trata como si viniera de una pestaña de incógnito.

Esto no depende de Transbank. Es una medida que se anunció previo al release de Chrome 80 (Firefox empezó a hacer lo mismo poco después), y afecta al atributo SameSite de las Cookies. El default ya no es SameSite: None sino SameSite: Lax

La idea de fondo es que si visito un sitio malicioso éste no pueda gatillar, disimuladamente, un request que le permita ver dónde estoy logueado. Esto es lo normal en peticiones fetch/xhr, pero desde el cambio que menciono también afecta, por ejemplo, a los formularios y los iframes.

Cookies are not sent on normal cross-site subrequests (for example to load images or frames into a third party site), but are sent when a user is navigating to the origin site (i.e. when following a link).

(O sea, sólo se mandan cookies cuando hay navegación acompañando al request) Y luego:

Lax replaced None as the default value in order to ensure that users have reasonably robust defense against some classes of cross-site request forgery (CSRF) attacks.

Junto con ese anuncio de Chrome 80, algunos párrafos más abajo explican que "por mientras" van a dejar que las peticiones POST sigan igual que antes, para no romper algunos sistemas de SSO. Y nunca dijeron hasta cuándo duraba "por mientras"

Q: What is the Lax + POST mitigation? This is a specific exception made to account for existing cookie usage on some Single Sign-On implementations where a CSRF token is expected on a cross-site POST request. This is purely a temporary solution and will be removed in the future. It does not add any new behavior, but instead is just not applying the new SameSite=Lax default in certain scenarios.

Si tu sitio se sirve con https, puedes declarar que la cookie de sessión tenga SameSite: None. Además, creo que SameSite es un setting para la cookie de sesión soportado desde PHP 7.3 en adelante, pero no estoy seguro.

Otra alternativa es un workaround que no requiera estar logueado al recibir el POST. Por ejemplo... tomar el token del body y redirigir mediante GET a una URL pasando el token como query string o como header.

Gracias a tu respuesta, maneje el error de otra manera pero esto me sirvió para saber la forma que se genera el flujo. Gracias!