Aplicación de una sola página con backend API REST basada en XML, consultada por XPath dinámico

3

Una aplicación web que estoy desarrollando será una aplicación de una sola página (SPA) que interactuará con un backend API REST, a través de jQuery.ajax() calls.

El SPA y la API se servirán a través de una conexión https / TLS. La API se servirá desde un subdominio del dominio SPA:

SPA: example.org
API: api.example.org

... y responderá con los encabezados CORS apropiados:

Access-Control-Allow-Origin: example.org
Access-Control-Allow-Methods: GET, POST, etc. // whatever applicable to the requested resource
Access-Control-Allow-Headers: Accept, Authorization, Content-Type

Al iniciar sesión en el SPA, el usuario (una organización) recibirá su sha1 API-key asociado único (ya sea en una cookie o como una variable javascript global), que el SPA utilizará para interactuar con la API, para el Duración de la sesión de inicio de sesión del usuario. El SPA emitirá este API-key en cada solicitud a la API en un encabezado Authorization :

Authorization: MyAppsApi apikey=<API-key>

El almacenamiento de persistencia de la API REST se basará en XML. Todavía no me he decidido por un proveedor de mecanismos de almacenamiento real (considerando el uso de eXistdb , por el momento). Sin embargo, en esta etapa temprana de desarrollo, simplemente estoy usando DOMDocument de PHP y DOMXPath , sin capacidades de lectura / escritura concurrentes.

La API REST además generará dinámicamente consultas XPath, basadas en la ruta del URI de la solicitud recibida. Sin embargo, la comunicación entre el SPA y la API probablemente se hará en JSON.

Considere este ejemplo de documento XML:

<?xml version="1.0" encoding="utf-8"?>
<organisations>
  <organisation id="1">
    <apiKey>some hex sha1 digest</apiKey>
    <products>
      <product id="1">
        <parts>
          <part id="1">
            <subParts>
              <subPart id="1">
                ...
              </subPart>
            </subParts>
          </part>
        </parts>
      </product>
    </products>
  </organisation>
  <organisation id="2">
    <apiKey>another hex sha1 digest</apiKey>
    <products>
      ...
    </products>
  </organisation>
</organisations>

Actualmente, este documento se valida mediante un esquema XSD personalizado.

La API REST primero determinará si existe un nodo <organisation> con el <apiKey> emitido antes de seguir interactuando con el XML. Si se encuentra el nodo <organisation> , se usará como el nodo de contexto para cualquier consulta XPath adicional.

Las rutas URI de solicitud estarán restringidas por el siguiente patrón de expresiones regulares:

~\G(/(?<collection>[a-z]+)(?:/(?<resourceId>\d+))?)(?:(?=(?1))|/?$)~

permitiendo solo /<loweralpha>+(/<digit>+)? segmentos

Considere estas rutas de ejemplo de URI de solicitud y sus XPath generadas dinámicamente:

/products/1          => .//products/*[@id="1"]
/parts/1             => .//parts/*[@id="1"]
/products/1/parts/1  => .//products/*[@id="1"]/parts/*[@id="1"]

Como puede ver, serán relativos al nodo de contexto <organisation> .

Teniendo en cuenta que aún no he investigado completamente el funcionamiento típico de los backends XML, puede resultar que mi configuración de XML anterior sea defectuosa para empezar, ya que debo crear un documento XML por organización, mitigando el riesgo de acceder a nodos que no pertenecen al nodo de contexto <organisation> .

Sin embargo, ¿ve algún defecto inherente en esta configuración actual?

En mi configuración actual, me preocupa sobre todo la consulta dinámica de XPath que podría resultar demasiado arriesgada. Tal vez un adversario es capaz de colarse en los ejes XPath, de alguna manera? Pero también me interesa conocer otras posibles fallas.

Gracias.

PS .: quizás debería haber aclarado más cuáles son los riesgos, lo que más me preocupa:

  1. ¿Puede un adversario obtener de alguna manera la clave API de una (otra) organización?
  2. ¿Puede un adversario manipular de alguna manera el contenido de una (otra) organización?
pregunta Decent Dabbler 02.05.2016 - 20:42
fuente

1 respuesta

2

Su problema principal al manejar el servicio proporcionado por el cliente será XML External Entities (XXE) ataques. Los sistemas con tales vulnerabilidades a menudo pueden ser explotados para leer archivos o enumerar la red interna en la que se encuentra el servidor. En PHP, puedes ayudar a solucionar esto llamando a libxml_disable_entity_loader(true); para deshabilitar entidades externas.

Otro problema es, potencialmente, el ataque Billion Laughs . Este es un ataque DoS de agotamiento de memoria y CPU que utiliza declaraciones de tipo de elemento anidadas. Esta pregunta de SO debería darle una buena idea sobre cómo haga una validación previa de XML antes de cargarlo para evitar este tipo de ataque, pero la respuesta corta es que libxml le permite configurar un validador DTD personalizado / devolución de llamada del cargador.

También puede considerar Inyección de XPath , aunque no estoy seguro de cuán crítico sería esto. su caso de uso Es difícil saber qué tipo de impacto podría tener en la lógica de negocios de su sistema sin tener un conocimiento más amplio de la aplicación.

    
respondido por el Polynomial 02.05.2016 - 20:51
fuente

Lea otras preguntas en las etiquetas