¿Es esta una implementación insegura de sesiones de múltiples sitios?

0

Tengo un Magento multisitio (una plataforma de comercio electrónico PHP). Las cuentas se comparten entre los sitios, pero las sesiones no, por lo que debe iniciar sesión en cada sitio individualmente. Estoy interesado en compartir estas sesiones.

Encontré una respuesta en el intercambio de pila de Magento. Cómo compartir sesiones entre tiendas con diferentes dominios . La recomendación es esta:

cookies.php

setcookie("frontend", htmlspecialchars($_GET['SID']), time() + 86400);

example1.com

<?php $sessionId = Mage::getSingleton('core/session', array('name' => 'frontend'))->getSessionId(); ?>
<img src="https://example2.com/cookie.php?SID=<?phpecho$sessionId;?>" style="display:none;" />

Estoy tratando de envolver mi cabeza en torno a las implicaciones de seguridad de esto. Si no me equivoco, esta URL se convierte en todo lo que se necesita para iniciar sesión como usuario.

Todos nuestros sitios son solo HTTPS, así que creo que eso ayuda a evitar que cualquier persona que escuche tráfico reciba esta URL, ¿correcto?

Un problema que podría ver es que si alguien está en la computadora física, tendría acceso a esa URL y podría usarla para iniciar sesión desde otra computadora, lo que de otro modo sería imposible sin la contraseña. La expiración de la sesión previene contra eso, ¿no? Si es así, las sesiones son actualmente bastante largas, por lo que los carros se mantienen vivos por más tiempo. ¿Qué tan cortas deberían ser las sesiones?

En resumen, ¿Es esta una implementación insegura de las sesiones de inicio de sesión en múltiples sitios? Si es así, ¿se puede hacer seguro este enfoque?

    
pregunta Goose 30.11.2017 - 21:03
fuente

1 respuesta

1

Muchos sistemas SSO funcionan de esta manera. Pero hay algo más que solo un par de líneas de código, específicamente:

  • utilice cookies para las sesiones con las marcas habituales httponly y de seguridad
  • cuando se recibe una solicitud de un servicio autenticado pero sin una sesión válida, redirija al usuario al SSO (esto requiere un manejo especial alrededor de POST y DELETE / PUT / PATCH si se usa)
  • si ya existe una sesión en el SSO o la autenticación de usuario de Passess, redirija al usuario a una página de destino especial en la aplicación con un token en la URL (porque esa es la única forma educada de obtener datos entre dominios)
  • en la página de destino, establezca un enlace a la sesión, configure la cookie de sesión y redirija a la página solicitada originalmente (tenga en cuenta que algunos navegadores antiguos ignoraron las cookies establecidas en una respuesta 302)
  

HTTPS [...] ayuda a evitar que las personas que escuchan el tráfico obtengan esta URL, ¿correcto?

La palabra clave aquí es "ayuda". No evita que la URL aparezca en el historial.

  

¿Qué tan cortas deberían ser las sesiones?

Tratar de solucionar el problema de perder la cookie de sesión acortando el tiempo de espera de la sesión no es el camino correcto. Un mejor enfoque es hacer que el SSO envíe un token de uso único que la aplicación pueda usar para resolver la sesión o autenticar el acceso a la sesión, por ejemplo. (en el SSO)

if (authenticated()) {
    $secretsid=encrypt(session_id(), SERVERSIDEPASSWORD);
    $_SESSION['otp']=uniqid();
    $return_url=add_get_arg($app_landing_url, array(
      'secretsid'=>$secrestsid,
      'OTP='=>$_SESSION['otp'],
      'original_requested_url'=>$originally_requested_url)
    );
    header("Location: $return_url");
    exit;
}

y en la página de destino ....

if ($_REQUEST['secreetsid']) {
    $sid=decrypt($_REQUEST['secretsid'], SERVERSIDEPASSWORD);
    if (looks_like_a_valid_session($sid)) {
          session_id($sid);
          session_start();
          if ($_SESSION['otp']==$_REQUEST['otp']) {
             unset($_SESSION['otp']);
             header("Location: $_REQUEST[original_requested_url]");
             exit;
          } else {
             // bad OTP
             log_bad_session_transfer();
             exit;
          }
    } else {
          // might be naughtiness, might be a bug
          log_bad_session_transfer();
          exit;
    }
 } else {
    // must have got here by accident - send them back to SSO
    redirect_to_sso();
    exit;
 }

Una forma alternativa de resolver / validar el token sería hacer una llamada HTTP directa desde la página de destino al SSO (es decir, de servidor a servidor, no a través del navegador) y pedirle que resuelva el SID en función del toekn recibido desde el navegador.

    
respondido por el symcbean 01.12.2017 - 13:02
fuente

Lea otras preguntas en las etiquetas