He estado buscando arriba y abajo sobre esto, pero no puedo encontrar nada relevante sobre esto, pero ¿hay una buena solución para desinfectar caracteres html en la entrada del usuario en una mutación graphql?

Sé con certeza que una entrada como name: "<script>{alert('foo')}</script>" es aceptada por graphql (apollo-server-express en mi caso) tal cual, pero eso no está bien. Claro, marcos como React no establecerán esa cadena como html, por lo que es "seguro" allí, pero ¿qué pasa si el punto final de graphql es consumido por un sitio que incrusta cadenas como html?

Entonces, ¿alguien conoce una buena solución para esto? He mirado un par de paquetes, pero en su mayoría son bastante pequeños, con poca actividad en ellos.

Otra solución sería desinfectar a nivel de la base de datos, con algo como sanitize-html, pero quería ver si había una solución adecuada a nivel de esquema

0
DanielOrtel 24 oct. 2019 a las 04:00

1 respuesta

La mejor respuesta

Terminó simplemente desinfectando a nivel de modelo, creó una clase de modelo general que desinfecta todo en args:

export default class Model {
  constructor(parent, args, context, info) {
    this.db = db;
    this.parent = null;
    this.args = null;
    this.context = null;
    this.info = null;

    this.#init(parent, args, context, info);
  }

  #init = (parent, args, context, info) => {
    this.parent = parent;
    this.args = this.#sanitizeObject(args);
    this.context = context;
    this.info = info;
  };

  #sanitizeObject = (args) => {
    let sanitizedArgs = {};

    Object.entries(args).forEach(([key, value]) => {
      if (Array.isArray(value)) {
        sanitizedArgs[key] = this.#sanitizeArray(value);
      } else if (typeof value === 'object') {
        sanitizedArgs[key] = this.#sanitizeObject(args[key]);
      } else {
        sanitizedArgs[key] = this.#sanitizeInput(value);
      }
    });

    return sanitizedArgs;
  };

  #sanitizeArray = (args) => {
    return args.map((value) => {
      if (Array.isArray(value)) {
        return this.#sanitizeArray(value);
      } else if (typeof value === 'object') {
        return this.#sanitizeObject(value);
      } else {
        return this.#sanitizeInput(value);
      }
    });
  };

  #sanitizeInput = (input) => {
    return DOMPurify.sanitize(input);
  };
}
0
DanielOrtel 24 oct. 2019 a las 12:58