Validando peticion GET manualmente

Iniciado por AlbertoBSD, 13 Septiembre 2016, 20:36 PM

0 Miembros y 1 Visitante están viendo este tema.

AlbertoBSD

Buen dia estoy desarrollando un pequeño servidor en C para un proyecto que tengo.

Ya tengo buena parte trabajado, pero me gustaria consultarles si existen mas cosas que deba de validar en una peticion GET  el ejemplo que mas o menos tengo del codigo es el siguiente:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define KB 1024

int main() {
char *type,*resource,*protocol,*extra,*hasQuery,**values = NULL,*key,*value,*aux;
int values_count= 0,i;
char *temp = malloc(KB);
strcpy(temp,"GET /LALALA/xD.txt?q=xD&XD HTTP/1.1");
type = strtok(temp," ");
resource = strtok(NULL," ");
protocol = strtok(NULL," ");
extra = strtok(NULL," ");
printf("type = %p: %s\n",type,type);
printf("resource = %p: %s\n",resource,resource);
printf("protocol = %p: %s\n",protocol,protocol);
printf("extra = %p\n",extra);
hasQuery = strstr(resource,"?");
if(hasQuery) {
printf("query = %p: %s\n",hasQuery,hasQuery);
aux =  strtok(hasQuery+1,"&");
do {
if(aux) {
values = realloc(values,sizeof(char*)*(values_count+1));
values[values_count] = aux;
printf("values: %s\n",values[values_count]);
values_count++;
}
aux =  strtok(NULL,"&");
}while(aux);
i = 0;
while(i < values_count) {
key = strtok(values[i],"=");
value = strtok(NULL,"");
//Aqui salvo los valores key y value para su posterior uso
printf("Key: %s\nValue: %s\n",key,value);
i++;
}
}
else
printf("query = %p\n",hasQuery);
if(values)
free(values);
if(temp) {
free(temp);
}
}



Estoy releyendo el protocolo del HTTP y estoy validando de momento solo la primera LINEA de la peticion.

Saludos!
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

Kaxperday

#1
Buenas,

Según veo quieres validar solo la request line y solo para el caso de GET, entonces me parece que la validación puede considerarse correcta, aquí los límites los pones tu si quieres un server de calidad asegurate de hacer un buen control de errores, sino me equivoco todos los HTTP request (incluido el GET por supuesto) tienen en su request line 3 partes: el método, la uri, y la versión de protocolo HTTP empleado, si tienen más o menos de 3 deberías considerar la request como errónea.

Para un GET no veo necesario validar más, ahora deberías de pensar en validar los headers también, e implementar los métodos que deeses y que debes de mostrar cuando te envíen un HTTP OPTIONS.

También cuidado al programar el GET pues por lo general sirve archivos, y pueden hacer algo como "GET ../../passwords.txt HTTP 1.1" y puedan acceder a directorios anteriores que el de la carpeta root del servidor, para ello debes controlar que la uri no empiece con "..", pero eso ya sería más adelante cuando vayas a servir el archivo.

Ánimo con el proyecto, me parece interesante.

Un saludo.
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

kub0x

Como ejemplo está bien, pero ten cuidado con el parseo/análisis de datos arbitrarios y su consecutivo almacenamiento, pues un buffer overrun podría terminar en consecuencias serias. Por ejemplo podría mandar un paquete que no siguiera el esquema de request de HTTP, sin GET ni POST ni otros.

Lo mejor es seguir el RFC, también te ahorraras cuelgues estilo DOS/DDoS manteniendo la tabla de sesión (socks) en buen estado (apache slowloris que recuerdos).

Saludos!
Viejos siempre viejos,
Ellos tienen el poder,
Y la juventud,
¡En el ataúd! Criaturas Al poder.

Visita mi perfil en ResearchGate


AlbertoBSD

Muchas gracias por contestar, sabia que te interesaria el topic.

CitarTambién cuidado al programar el GET pues por lo general sirve archivos, y pueden hacer algo como "GET ../../passwords.txt HTTP 1.1"

Claro que habia considerado los dotdotpwn... de hecho el recurso siempre lo valido, contra una tabla de recursos validos, si existe lo carga pero con el segundo campo de mi tabla (Un archivo previamente validado con su path valido).

Ya he validado tambien los headers y solo estoy trabajando para leer los datos cuando se trata de un POST, estoy haciendo una pequeña tabla de estados para saber que es lo que sigue y en caso de no coindidir el numero de tokens o alguna otra variable marque error.

Saludos!
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

ivancea96

Cita de: AlbertoBSD en 13 Septiembre 2016, 20:36 PM

strcpy(temp,"GET /LALALA/xD.txt?q=xD&XD HTTP/1.1");
type = strtok(temp," ");
resource = strtok(NULL," ");
protocol = strtok(NULL," ");
extra = strtok(NULL," ");


Como detalle, yo comprobaría que las 3 partes son correctas. Que no tengan caracteres inválidos (como saltos de línea o retornos de carro), y que tanto el "type" como el "protocol" sean válidos; aunque supongo que eso ya lo tendrás en cuenta en el futuro xD

Oh, y yo dejaría de usar ese strtok cuanto antes. Si es un servidor, es probable que pretendas hacerlo multi-thread.

AlbertoBSD

CitarOh, y yo dejaría de usar ese strtok cuanto antes. Si es un servidor, es probable que pretendas hacerlo multi-thread.

Muy bien acabo de ver los problemas que implica y al parecer no debo de usarlo xD usare strtok_r en su lugar con un 3 parametro para salvar el estado de la funcion.

Saludos
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW