Feda /dev/

MisKo

Estoy con el desarrollo de una API pero quiero que se pueda acceder desde la propia web y, al mismo tiempo, que no sea accesible externamente a esta y todo lo que se me ocurre se podría falsificar si se sabe como funciona xDD

Alguien se ha encontrado alguna vez con algo así ? Es la primera vez que se me plantea el caso y no creo que haya un método 100% infalible la verdad, así que me conformaré con que sea algo tedioso xD

Por ejemplo

De paso, a quien le interesen estas cosas, dejo los cheatsheets de owasp:

wdaoajw

Desde donde exactamente quieres llamar a la API? Desde el back? No expongas la API al mundo, despliega de forma que solo la vea el servicio que la quiere llamar.

Si necesitas que sea llamada desde un navegador... debes exponerla si o si, ya sea directamente o a través de un proxy. Por exponerla me refiero a que de una forma u otra si se puede llamar desde internet se puede usar para que terceros la usen. (Todo esto si no hay ningún tipo de auth)

1 respuesta
themaz

puedes usar una VPC si usas AWS

1 respuesta
eXtreM3

Una API que se llame desde la misma web... ¿?

Del front al controller y del controller al modelo.

Si te parecen pocas capas puedes implementar el hexágono ese que propone @desu

1 respuesta
MisKo

#40052 Como comentas, no veo la manera de limitar esas llamadas a la API si se expone publicamente para ser consultada desde un navegador. Otra cosa es que se puedan poner trabas, como cambiar tokens entre peticiones y demás, pero una vez 'descubierto' el pastel, se podría automatizar igualmente.

#40053 No veo como un VPC ayudaría en algo de acceso publico, solo en caso de que se llamara a la API desde el propio backend podrías restringir el acceso a la red, pero si es publico, quien hace la petición es el propio usuario.

#40054 O no me has entendido, o no te entiendo :joy:

¿Que ves de raro en que una web utilice su api?

2 respuestas
wdaoajw

#40055 No te termino de entender, quieres una API que solo sea accesible desde un servicio del backend? o que sea llamada por código js guarrero desde un navegador?

Si es lo primero es tan simple como restringir todo el trafico hacia esa API y solo permitir el procedente del servicio que tu quieras que se le llame.

eXtreM3

#40055 una API es una agrupación de los métodos que ya tienes en los modelos, no tienes que construir nada nuevo.

Que se llame desde un subdominio son temas que no influyen. Imagina que tu enrutamiento es así

web.com/users/
web.com/noticias/
...

Si haces

api.web.com/users/get

debería ser lo mismo que internamente hacer

$this->UsersModel->get()

Por tanto, si estás desde la propia web como tú dices, puedes llamar a últimas noticias bien desde el back o desde el front, que solo añadirá un paso más porque pasa por el controller.

DESDE FRONT:

ajax -> controller -> model

DESDE BACK:

model

Edit: y ya está, los modelos no son accesibles desde fuera, ni por navegador ni postman ni nada.

1 respuesta
MisKo

#40057 Vale, no me has terminado de entender entonces, asi que como el otro tampoco me ha terminado de entender, debo explicarme como el culo ajajajajaja

La estructura interna y como montar el desarrollo en el backend no es problema. Voy a poner otro ejemplo.

Digamos que yo tengo una API que me devuelve la información de los planetas de starwars. Por ejemplo, si le paso el ID 1 , me devuelve la información de Tatooine mientras que si le paso el ID 2, me devuelve la información de Alderaan.

Digamos, por seguir con el ejemplo, que el acceso a dicha api es tal que así:

https://swapi.co/api/planets/1/
https://swapi.co/api/planets/2/

Tal y como está actualmente, cualquier petición GET a esas URLs te devuelve la información, ya sea desde ajax, postman, curl en PHP, etc...

La pregunta/problematica sería:

¿Conoceis alguna manera de que solo funcione la peticion si se ha hecho desde el navegador? Bloqueando cualquier otra fuente (curl, postman, etc..)

A ver si así me explico mejor xDD

En mi opinión, yo creo que no se puede hacer, puesto que siempre se podrían falsificar las cabeceras y demás, o analizar una petición y replicar el token, etc...

5 respuestas
eXtreM3

#40058 debo ser malísimo como profesor xDDD

No está mal que https://swapi.co/api/planets/1/ devuelva info, eso es un controller. Imagino que a nivel de servidor puedes bloquear según la proveniencia de la petición, pero ni idea.

La verdadera pregunta es, si no quieres que esa dirección sea pública, por qué simplemente no la deshabilitas? Ese controller llamará a un modelo (o debería xd) para extraer la info de la BD y listarla. En lugar de utilizar una api pública (controller) utiliza los modelos que es lo adecuado.

Si sigues sin entenderme es que definitivamente te he entendido mal y no sé responderte mejor xD

pd: no he visto SW.

1 respuesta
Grise

#40058 Para la chapuza que quieres montar creo que lo mejor es usar un servidor intermedio. La API la expones solo a ese servidor y pasas toda la información por ahí. Es una guarrada que te resuelve la papeleta, pero seguramente haya una manera mucho mejor de hacerlo.

EDIT: Mentira porque luego en el servidor intermedio tendrías que diferenciar el origen igual.

1 respuesta
wdaoajw

#40058 Lo lógico entonces es que coloques delante un servicio de validación, autenticando mediante basic auth/token/post que posteriormente llame a esa API.

Browser -> Validator(expuesto) -> API(no expuesto, solo pasa lo que el validator decide que pase)

De esta forma si puedes controlar que entra y como. Pero volvemos a lo que te decía antes, un servicio que llama a otro. Como bien dices, las cabeceras de una petición HTTP (donde puedes ver desde que dispositivo se ha hecho) se pueden toquetear fácilmente así que no te sirve como método fiable.

1 respuesta
eXtreM3

Para eso fuerzo que exista un token de sesión en la API y a tomar por culo, si no estás logueado no puedes acceder al endpoint.

B

#40058 No puedes hacer ese tipo de "cribado"... Lo máximo que se podría conseguir es crear ventanas de tiempo al más puro estilo 2FA... y que al entrar en miweb.com generase token.... así sabes que cuando se llama a miweb.com se crean tokens válidos (que podrían a llegar a usarse desde fuera... pero tocándoles las narices haciendo que cada x tiempo lancen petición contra miweb.com).

En cuanto entras a miweb.com las llamadas realmente las hace el cliente, no el servidor que sirve el sitio.

1 respuesta
MisKo

#40061 Si, no veo la manera de bloquear peticiones si no es mediante algún auth, por lo que para contenido sin autenticar lo veo dificil.

#40059 No te preocupes, te entiendo a medias, pero seguro que es culpa mia. La idea pasa por hacer una API central y que dicha API alimente por ejemplo SPAs, apps móviles, aplicaciones de escritorio, etc.. de ahí que se utilice el mismo endpoint para todo

#40060 Lo que comentas creo que no arreglaría nada la verdad ajajajaja

#40063 Si, es justo lo que pensaba, que al entrar se genere un token (al estilo CSRF) y que cualquier petición que no lo incluya sea inválida. El tema está en que esto sería automatizable (siempre que la generación de dicho token no dependa de la interacción del usuario)

De ahí a que mencionara formas tediosas de replicarlo xDDD

Wei-Yu

Yo según lo entendí no es posible. A ti te llegan peticiones con metadatos y la información que toque, cosa que se puede maquillar

Como mucho lo único que se me ocurre es meterle códigos de un solo uso que se generan en base a algo que definas tú en el js minificado que le puedas meter al front pero parece una puta mierda de plan... seguramente si al cliente le dices la de tiempo que te llevaría implantar esa mierda se iban a echar para atrás por el coste.

1 respuesta
MisKo

#40065 Si, al poderse maquillar la info en la petición no veo viable bloquearlo, como mucho dificultar las peticiones externas. Además, implementar lo que comentas en el JS perdería la seguridad por estar en cliente xDD

1 respuesta
eXtreM3

@Merkury arroja luz aquí anda que yo me explico como las mierdas.

2 respuestas
Wei-Yu

#40066 la seguridad es la misma que no tener api directamente; ofuscar y obstruir el acceso a secas.

la forma que tiene la gente de evitar el scraping y cosas del estilo es capar el número de peticiones de un cliente (que esto en último lugarcon una granja te lo saltas) o, si tienes la suficiente magnitud, ofuscar y tocar los cojones con el html y las peticiones como lo hacen facebook o google por ejemplo

1 respuesta
MisKo

#40067 que no te preocupes que te has explicado bien ajajaj

#40068 Si, veo más que toque hacer eso a intentar ponerle puertas al campo xdddd

1 respuesta
B

#40069 Igual podrías crear una webExtension para verificar que la petición viene de una "fuente válida"... pero sin duda es tratar de poner puertas al campo.

Grise

La mierda es que mandas el código al cliente visible. Si fuese un compilado se podría hacer alguna chapuza generando códigos con una semilla y lo único que verías en las llamadas que salen de tu pc es que en cada solicitud cambia la key.

Merkury

#40067 Ejecutar comandos triviales desde php a archivos con permisos 777 es una muy mala idea XD

1 respuesta
eXtreM3

#40072 pero cabrón lee un poco xd

1 respuesta
Merkury

#40073 Acabo de encontrar mi propia guia de implemetacion de una cosa que he terminado despues de invertir dos horas que me hubiese costado 5 minutos (porque tengo todos los one-liners etc) me voy a leer tus post.

1 respuesta
Ranthas

#40058 ¿Qué estás tratando de esconder, tunante?
#40074 Uno cree que es la polla cuando pasa de leer documentación de terceros. Está claro que el nivel superior es pasar de leer tu propia documentación. Ya lo siguiente será pasar de leer.

2 respuestas
wdaoajw

#40075 Docu...que? Eso que es?

1 respuesta
Ranthas

#40076 Nada útil, de eso podemos estar seguros.

desu

Sin ofender, estas mezclando niveles.

Lo que quieres hacer es muy sencillo... A nivel de ruta.

Intentar controlar en em código algo de un nivel inferior es incorrecto. Sin ánimo de ofender... Es que es tan obvio que no entiendo la duda.

Wei-Yu

claro joder, lo que quieres hacer es funcional cinturón rojo pero realmente estás haciendolo siendo amarillo

1 respuesta
desu

#40079 es que la duda no la entiendo por ningún lado.

Deberías explicar porqué estas obligado a tratarlo a nivel de código. Eso nos ayudaría a entender el problema mejor.

En el stack de spring cloud o Netflix había una herramienta que podrías usar.

Tema cerrado