Web URL Filter implementation

66 views Asked by At

I have received a task/project from my professor to build a solution for Web URL filtering. Now this being a very open-ended problem statement to work with, I had multiple ways to approach it. One way is to do the blocking on the client side itself. So, to do that, I first chose an approach of performing a reset attack on my own computer's TCP connection. This way I shall be able to terminate the TCP connection between the blocked IP/URL server and the client's computer. Another approach I could think of was to deploy a proxy server in the middle and sniff all the requests before the data packets manage to reach the blocked host server. This again is a valid approach, however, I am not very sure for how to approach it. I am a novice in the networks domain. Could someone guide me how to proceed from here? I need to implement it for HTTPS as well, however, things complicate with encryption and stuff.

Following is my current implementation of proxy-server approach but just for HTTP:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>

#define PROXY_PORT 8080
#define BLACKLISTED_URL "example.net"

void handle_client(int client_socket) {
    char request[4096];
    ssize_t bytes_received;

    // Receive the client's request
    bytes_received = recv(client_socket, request, sizeof(request), 0);

    // printf("Received request: %s\n", request);

    if (bytes_received < 0) {
        perror("Error receiving request");
        return;
    }

    // Check if the request contains a blacklisted URL
    if (strstr(request, BLACKLISTED_URL) != NULL) {
        const char* response = "HTTP/1.1 403 Forbidden\r\nContent-Length: 19\r\n\r\nAccess Denied: URL blocked\r\n";
        send(client_socket, response, strlen(response), 0);
        close(client_socket);
        return;
    }

    // Create a connection to the target server
    int target_socket = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in target_addr;
    target_addr.sin_family = AF_INET;
    target_addr.sin_port = htons(80);
    target_addr.sin_addr.s_addr = inet_addr("127.0.0.1");

    if (connect(target_socket, (struct sockaddr*)&target_addr, sizeof(target_addr)) < 0) {
        perror("Error connecting to the target server");
        close(client_socket);
        return;
    }

    // Forward the request to the target server
    send(target_socket, request, bytes_received, 0);

    // Forward the response from the target server to the client
    char response_buffer[4096];
    ssize_t bytes_sent;
    while ((bytes_received = recv(target_socket, response_buffer, sizeof(response_buffer), 0)) > 0) {
        bytes_sent = send(client_socket, response_buffer, bytes_received, 0);
        if (bytes_sent < 0) {
            perror("Error sending response to the client");
            break;
        }
    }

    // Close the sockets
    close(client_socket);
    close(target_socket);
}

int main() {
    int proxy_socket = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in proxy_addr;
    proxy_addr.sin_family = AF_INET;
    proxy_addr.sin_port = htons(PROXY_PORT);
    proxy_addr.sin_addr.s_addr = INADDR_ANY;

    if (bind(proxy_socket, (struct sockaddr*)&proxy_addr, sizeof(proxy_addr)) < 0) {
        perror("Error binding to the proxy port");
        return 1;
    }

    if (listen(proxy_socket, 10) < 0) {
        perror("Error listening on the proxy socket");
        return 1;
    }

    printf("Proxy server listening on port %d...\n", PROXY_PORT);

    while (1) {
        struct sockaddr_in client_addr;
        socklen_t client_addr_len = sizeof(client_addr);
        int client_socket = accept(proxy_socket, (struct sockaddr*)&client_addr, &client_addr_len);

        if (client_socket < 0) {
            perror("Error accepting client connection");
        } else {
            handle_client(client_socket);
        }
    }

    close(proxy_socket);
    return 0;
}

0

There are 0 answers