4 votos

Contraseña que protege las tablas en cartodb

Estoy tratando de encontrar una manera sencilla de mesas privadas, sin embargo, que los expone a ciertos clientes, si están autenticados.

Esta autenticación se puede lograr mediante un sistema de token que permite al cliente realizar consultas sólo si el token o las credenciales son válidas.

El enfoque que aquí iba a tener una función con la lógica de autenticación y lo consultas u operaciones que usted necesita para exponer, y llame a esa función desde el cliente junto con sus credenciales.

El problema con esto es que usted termina con un pg de la función para cada operación, la necesidad de definir con precisión la entrada y la salida de la función, no polimorphy, así que cada vez que algo cambia (como un tipo de datos), todas las funciones deben ser recreado. No es muy flexible.

Otra posibilidad sería tener sólo una función que actúa como un contenedor para lo SQL que usted envía, comprueba las credenciales, esteriliza el sql y devuelve la respuesta.

CREATE OR REPLACE FUNCTION runSQL(thesql text,client text, hash text) RETURNS SETOF RECORD as $$
DECLARE
sql text;
expiry time;
client_info RECORD;
m   varchar;
--here go the blacklisted strings
blacklist varchar[] := array['UPDATE ','INSERT ', 'ALTER ', 'DROP ', 'TRUNCATE', 'DELETE '];
BEGIN
    expiry:=INTERVAL '1 hour';
    sql:= 'SELECT * FROM auth WHERE client_id = $1 AND client_hash = $2 AND created_at > (NOW() - $3)';
        EXECUTE sql using client, hash, expiry INTO client_info ;
            -- check if it's a valid user and has an up to date token
        IF client_info IS NULL THEN
            RAISE EXCEPTION 'Authorization failed for client %', client;
        END IF;

    sql:= thesql;
            -- sanitize the sql
    FOREACH m  IN ARRAY blacklist
            LOOP
            IF position(m in upper(thesql)) = 1 OR position(concat(' ', m) in upper(thesql))>0 THEN
                    RAISE EXCEPTION 'Not enough privilleges';
            END IF;
            END LOOP;
            --send back results
        RETURN QUERY EXECUTE sql ;
END;
$$ LANGUAGE plpgsql
SECURITY DEFINER;

Y de uso sería:

SELECT * FROM runSQL('SELECT cartodb_id, the_geom FROM sometable', 'client_id', 'token') as f(cartodb_id int, geom geometry)

Mi preocupación aquí no es la apertura de un enorme agujero en la seguridad de mi base de datos. ¿Crees que sería suficiente sólo para comprobar potencialmente peligrosos de las cadenas en la consulta (como INSERT, DELETE, DROP, ALTER, OTORGAR, REVOCAR...) o existen otros problemas de seguridad con este enfoque?

Otras ideas sobre cómo tener una SEGURIDAD DEFINIDOR función que sólo permite que ciertas operaciones, como leer, o el acceso solo a algunas tablas?

Gracias!

David

10voto

Torkel Puntos 1934

Siempre he dicho que el poder de la seguridad definidor es que se puede utilizar con la imposición de tipos de datos en el plpgsql para ayudar a asegurar que usted no está recibiendo la inyección de SQL. No es totalmente cierto yo confiaría en una lista negra como esa. También se abren todas las tablas para el usuario con fichas, no estoy seguro de que es su objetivo.

¿Por qué no acaba de devolver el resultado de una instrucción SELECT * y dejar correr los filtros fuera de su función? Entonces, sólo podía pasar en un tablename cadena y asegúrese de que el tablename no es nada malicioso. Yo haría que por sólo codificar en una matriz de tablenames para comprobar contra y fallar si no.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X