Está en la página 1de 29

Internet de las Cosas (IoT), Ciberseguridad y Aplicaciones.

Curso 2023-2024

Contenido
Introducción .................................................................................................................................. 2
Instalación de node.js.................................................................................................................... 4
Instalación de MongoDB ............................................................................................................... 4
Instalación y configuración del IDE ............................................................................................... 8
Inicialización del proyecto ............................................................................................................. 8
Primera prueba de node.js ............................................................................................................ 9
Instalación de módulos con NPM................................................................................................ 11
Creación y prueba del API REST .................................................................................................. 13
API REST con MongoDB............................................................................................................... 15
Establecer el modelo ............................................................................................................... 15
POST: altas en el API REST ....................................................................................................... 15
GET: Consultas al API REST ...................................................................................................... 21
PUT: modificaciones API REST ................................................................................................. 22
DELETE: eliminación API REST ................................................................................................. 23
Inyecciones NoSQL .................................................................................................................. 24

Página 1 de 29
Internet de las Cosas (IoT), Ciberseguridad y Aplicaciones. Curso 2023-2024

Introducción

En esta práctica crearemos un API REST en la cual simularemos dispositivos IoT por los que se
puede acceder a sus servicios a través de peticiones HTTP como POST, GET, PUT y DELETE que
devolverán la información en formato JSON. Para ello crearemos un servidor en node.js en el
cual instalaremos módulos para programar el API REST y almacenaremos los datos en MongoDB,
una base de datos NoSQL.

También se realizarán pruebas de funcionamiento con la herramienta “Postman” como


aplicación cliente que utiliza los servicios del API REST.

Finalmente veremos cómo se puede realizar un ataque de inyección NoSQL para obtener
información reservada y medidas para evitar este tipo de ataques.

El API REST que desarrollaremos proporcionará diferentes servicios según las rutas a las que se
acceda por ejemplo “http:localhost/devices” o “http:localhost/devices/temperature ” (donde
“temperature” es el tipo ‘type’ del dispositivo) y estos servicios serán diferente servicio según
el tipo de petición HTTP, es decir GET, POST, PUT o DELETE

Página 2 de 29
Internet de las Cosas (IoT), Ciberseguridad y Aplicaciones. Curso 2023-2024

De tal manera que nuestro API REST ofrecerá los siguientes servicios:

Petición
Ruta Descripción
HTTP
/devices GET Mensaje de que el API REST funciona

/devices POST Añade un nuevo dispositivo a la base de datos


Devuelve toda la información actual de un
/devices/:type GET
dispositivo indicando su ‘type’
/devices/:type PUT Modifica el parámetro ‘value’ del dispositivo

/devices/:type DELETE Elimina un dispositivo según su campo ‘type’

/devices/find POST Devuelve los valores de un dispositivo

Página 3 de 29
Internet de las Cosas (IoT), Ciberseguridad y Aplicaciones. Curso 2023-2024

Configuración del entorno


Instalación de node.js
Desde la página oficial de node.js ( https://nodejs.org/en ) descargamos la última versión
LTS (long-term support) en estos momentos la 20.09.0 Con él se instala su gestor de
paquetes npm
En la consola de comandos de Windows “cmd” probamos que está correctamente
instalado con los comandos:
node -v
npm -v
Que nos devuelven las versiones de node.js y del gestor de paquetes npm (con las
versiones actuales)

Instalación de MongoDB
Desde la página oficial de MongoDB https://www.mongodb.com/download-center/community
en versión elegimos la 7.0.3, durante la instalación seleccionamos la opción “complete”.

Página 4 de 29
Internet de las Cosas (IoT), Ciberseguridad y Aplicaciones. Curso 2023-2024

Desactivamos que instale mongo como servicio, para no tener siempre el servicio de mongo
activo cuando se inicia el equipo,

Instalamos mongodb Compass

Página 5 de 29
Internet de las Cosas (IoT), Ciberseguridad y Aplicaciones. Curso 2023-2024

Una vez terminada la instalación creamos las variables de entorno para utilizar MongoDB desde
la línea de comandos para ello vamos a propiedades del sistema variables del entorno.

Página 6 de 29
Internet de las Cosas (IoT), Ciberseguridad y Aplicaciones. Curso 2023-2024

En el “Path” se añade la ruta de instalación de MongoDB: “C:\Program


Files\MongoDB\Server\7.0\bin”

A continuación, es necesario crear el directorio “C:/data/db” ruta por defecto donde se


almacenan los documentos creados por MongoDB.

cd C:\

md "\data\db"

Página 7 de 29
Internet de las Cosas (IoT), Ciberseguridad y Aplicaciones. Curso 2023-2024

Para comprobar su funcionamiento desde consola se ejecuta el comando

mongod --version

Instalación y configuración del IDE

En primer lugar, crearemos una carpeta que llamaremos “APIrest” dentro del directorio
“documentos” donde realizaremos nuestro proyecto

Como entorno de desarrollo utilizaremos el editor “Visual Studio Code” que se puede descargar
desde su página oficial https://code.visualstudio.com/ es un editor de texto ligero que
pertenece a la familia de editores livianos y modernos como Atom, Brackets y sublime text que
se adapta a nuestras necesidades a través de la utilización de extensiones

Creación de un proyecto de node.js


Inicialización del proyecto
Desde el terminal accedemos al directorio donde vamos a crear nuestro proyecto (en este caso
la carpeta “APIrest” en el directorio “documentos”) utilizamos el comando

npm init

Esto nos da un asistente para la configuración del proyecto que se guarda en el fichero
package.json, como se muestra a continuación:

Página 8 de 29
Internet de las Cosas (IoT), Ciberseguridad y Aplicaciones. Curso 2023-2024

Primera prueba de node.js


Para probar que todo funciona correctamente escribiremos un código que simplemente cree un
servidor en node.js de tal manera que cuando se acceda a su dirección y puerto muestre un
mensaje de que funciona correctamente para ello, desde nuestro editor “Visual Studico code”
abrimos la carpeta de nuestro proyecto “APIrest” (File ->Open Folder) creamos el fichero (File -
> new file) para guardarlo como server.js (File->Save as) y ponemos el nombre “server.js”.

En esta primera prueba utilizaremos el módulo ‘http’ propio de node.js y empezaremos a utilizar
funciones callback.

Una vez instalado el editor abrimos desde él la carpeta “APIrest”.

Página 9 de 29
Internet de las Cosas (IoT), Ciberseguridad y Aplicaciones. Curso 2023-2024

Los callbacks son funciones que reciben como parámetro otras funciones, se utilizan para
programar de manera asíncrona y orientada a eventos, es decir, cuando ocurre un evento se
utiliza el callback que trata los parámetros de ese evento. En el caso de este primer en ejemplo
“http.createServer” el parámetro es una función de callback que recibe el objeto del request
‘req’ y la respuesta ‘res‘ que devolveremos al navegador. En esta función de callback podemos
hacer cualquier procesamiento necesario para generar una respuesta, la cual deberá ser cargada
sobre el objeto res.
var http = require('http');
var puerto = 9000;
var host='127.0.0.1';
//como parametro de crate server hay un callback con dos argumentos,
pregunta/ respuesta

http.createServer(function(req, res){
res.writeHead(200, {'Content-Type': 'text/plain'});
// en req.url viene la ruta que se esta solicitando
res.end('Servidor node funcionando en ' + host + ':' + puerto + req.url
+ '\n');
}).listen(puerto, host, function(){
//mostrar por consola que el servidor esta corriendo
console.log('Servidor node corriendo en ' + host + ':' + puerto);
});

Para ejecutar el servidor desde la ruta donde se encuentra server.js ejecutamos el comando
node server.js

Desde el navegador web si escribimos la ruta 127.0.0.1:9000

Si indicamos alguna ruta a mayores la mostrara a través de “req.url”

Con esto probamos un sencillo servidor en node.js utilizando el módulo propio de node.js “http”

Página 10 de 29
Internet de las Cosas (IoT), Ciberseguridad y Aplicaciones. Curso 2023-2024

Creación del API REST


Una vez que hemos probado que nuestro servidor en node.js funciona correctamente
empezaremos a crear nuestra API REST con rutas URL que ofrecen los diferentes servicios
indicados en la introducción, para ello necesitaremos descargar módulos de node.js programar
las diferentes acciones en cada ruta

Instalación de módulos con NPM


Express: es un módulo muy potente que proporciona un framework de desarrollo de
aplicaciones web en menos tiempo porque proporciona funcionalidades como el enrutamiento.
Es decir, da la posibilidad de establecer las acciones (los diferentes métodos HTTP) en las
diferentes rutas del nuestro API REST de una manera sencilla.
Cors: este módulo permite el acceso al API REST desde cualquier cliente que pertenezca a otra
red, no solo desde la propia red que la crea.
Para instalarlos utilizamos los comandos desde el directorio de nuestro proyecto
npm install --save express
npm install --save cors
El parámetro --save en el comando de npm hace que se guarde esta dependencia en el fichero
package.json como un módulo utilizado en el código de nuestro proyecto. Actualizándose el
documento package.json de la siguiente manera:
{
"name": "apirest",
"version": "1.0.0",
"description": "api REST con node.js",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"cors": "^2.8.5",
"express": "^4.18.2"
}
}

Existen otras maneras de instalar módulos con npm:


Con el parámetro --g se instala el módulo de manera global.

Con el parámetro --save-dev para la instalación de módulos útiles solo para el entorno de
desarrollo

Al añadir las dependencias en el documento package.json hace más portable el proyecto, por
ejemplo, así no es necesario subir a un repositorio todos ficheros del directorio “node_modules”
ya que los módulos se instalan simplemente utilizando npm install desde la ruta del proyecto.

Página 11 de 29
Internet de las Cosas (IoT), Ciberseguridad y Aplicaciones. Curso 2023-2024

También hay que tener consideraciones de seguridad a la hora de instalar los paquetes NPM ya
que existen paquetes fraudulentos que utilizan la técnica denominada ‘typo-squatting’ que
consiste en nombrar al paquete fraudulento con un nombre ligeramente similar al nombre de
un paquete real. Se busca engañar al usuario para su instalación e infección.
Algunos de los paquetes detectados son

• babelcli
• cross-env.js
• crossenv
• d3.js
• fabric-js
• ffmepg
• gruntcli
• http-proxy.js
• jquery.js
• mariadb
• mongose
• mssql-node
• mssql.js
• mysqljs
• node-fabric
• node-opencv
• node-opensl
• node-openssl
• node-sqlite
• node-tkinter
fuente: https://blog.npmjs.org/post/163723642530/crossenv-malware-on-the-npm-registry

Página 12 de 29
Internet de las Cosas (IoT), Ciberseguridad y Aplicaciones. Curso 2023-2024

Creación y prueba del API REST

Borramos el código de la prueba de funcionamiento de node.js del fichero server.js y añadimos


el siguiente código en el cual se usa la librería express para enrutar, (establecer las diferentes
acciones en las diferentes rutas del API REST) las peticiones con los métodos GET POST PUT y
DELETE del API REST. En este caso se hace una petición GET a la ruta “/devices” para que nos
devuelva como resultado un mensaje en JSON que indique que el API REST funciona
correctamente:

var express = require('express');


var cors = require('cors');
var bodyParser = require('body-parser');
var app = express();
var port = 3000;
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cors());
app.get('/devices', function (req, res) {
res.json({
msg:'el API REST funciona!'
});
});
app.listen(port, function () {
console.log('Servidor node.js corriendo en el puerto ' + port);
});

Una vez cambiado el código es necesario parar el servidor node.js con el ejemplo anterior con
el comando ‘ctrl+c’ y volver a iniciar el servidor con “node server.js”

Para probar el API REST instalamos POSTman desde su página oficial


https://www.getpostman.com/con este programa se puede ver todos los detalles de las
peticiones y respuestas a un api REST, una vez instalado no es necesario registrarse siendo
posible posponerlo
Desde la interfaz de postran se introduce la ruta a consultar y pulsamos “send”. Nos indica la
respuesta del servidor el tiempo y el tamaño de la respuesta.

Página 13 de 29
Internet de las Cosas (IoT), Ciberseguridad y Aplicaciones. Curso 2023-2024

También podemos consultar las cabeceras, pulsando la pestaña “headers”, que nos da
información relevante sobre la conexión y el API REST, como puede ser el tipo de acceso o con
que esta creado, en este caso Express

También se pueden obtener desde el navegador web al realizar la petición

Página 14 de 29
Internet de las Cosas (IoT), Ciberseguridad y Aplicaciones. Curso 2023-2024

API REST con MongoDB


En este apartado estableceremos una conexión con una base de datos de MongoDB para
almacenar la información actualizada de los dispositivos, a esta información se accederá para
hacer altas bajas consultas y modificaciones desde los diferentes servicios que ofrezca nuestra
API REST

Establecer el modelo

En este paso nos conectaremos a una base de datos MongoDB en la cual a través del API REST
realizaremos altas bajas y modificaciones

Instalamos el módulo mongoose que utilizaremos para modelar (definir que estructura tendrán
los datos) y conectarnos a la base de datos MongoDB

npm install --save mongoose

Como datos almacenaremos información que simulará dispositivos IoT por lo tanto
establecemos que estructura de los datos recibidos por estos dispositivos

Creamos el modelo para la colección devices (donde se almacenarán los dispositivos) para ello
en el directorio de nuestro proyecto “APIrest” creamos la carpeta “models” y dentro de ella el
fichero JavaScript device.js. En este fichero escribimos el código del esquema o estructura de la
colección devices.

Una vez creado el modelo se exporta como un módulo de node.js es muy importante tener en
cuenta que el nombre del modelo tiene que ser el nombre de la colección en singular
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
// definimos el esquema de nuestro modelo de datos
var DeviceSchema = new Schema({
type: String,
name: String,
description: String,
unit: String,
value: Number
});
// importante nombre de la colección en SINGULAR
module.exports = mongoose.model('device', DeviceSchema);

POST: altas en el API REST

En el código de server.js nos conectamos a la base de datos de mongodb


“mongodb://localhost/demoAPIREST” donde “mongodb://localhost” es la ruta por defecto
donde se ejecuta MongoDB y demoAPIREST la base de datos a crear, no es necesario crearla
antes, al pedir acceso a ella e introducir contenido se crea automáticamente

A continuación añadimos POST en la ruta “ /devices” para dar de alta un nuevo dispositivo, que
toma los datos de “req.body” es decir lo enviado por post y lo almacena en la colección “devices”

Quedando el código de server.js de la siguiente manera:

Página 15 de 29
Internet de las Cosas (IoT), Ciberseguridad y Aplicaciones. Curso 2023-2024

var express = require('express');


var cors = require('cors');
//añadimos mongoose
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
//añadimos el modelo
var Device = require('./models/device');
var app = express();
var port = 3000;
var database = 'mongodb://localhost:27017/demoAPIREST';
mongoose.connect(database);
var db= mongoose.connection;

db.on('error', console.error.bind(console, 'Error de conexion:'));


db.once('open', function() {
console.log('Conectado a la base de datos');
});

app.use(bodyParser.urlencoded({ extended: true }));


// configuramos par obtener datos en formato json
app.use(bodyParser.json());
//permite el acceso a la API desde cualquier origen

app.get('/devices', function (req, res) {


res.json({
msg:'el API REST funciona!'
});
});

//peticion POST para crear un nuevo dispositivo


app.post('/devices', async function (req, res) {
try {
// Creamos un nuevo dispositivo con los datos del request
var device = new Device(req.body);
// Guardamos el dispositivo en la base de datos usando await para
esperar la promesa
await device.save();
console.log("device guardado");
console.log(device);
res.status(200).json({
msg: 'Dispositivo guardado correctamente',
device: device
});
} catch (err) {
res.status(500).json({
msg: 'Error al guardar el dispositivo',
error: err
});
}
});

// app.listen para arrancar el servidor web con express en el puerto 3000


app.listen(port, function () {
console.log('Servidor node.js corriendo en el puerto ' + port);
});

Página 16 de 29
Internet de las Cosas (IoT), Ciberseguridad y Aplicaciones. Curso 2023-2024

La ejecución del código seria de la siguiente manera:

Primero es necesario iniciar la base de datos de MongoDB para ello ejecutamos desde un
terminal nuevo ejecutamos el comando

mongod

Desde otro terminal o el que teníamos abierto del ejemplo anterior, paramos la ejecución del
servidor anterior, y volvemos a iniciar este con

node server.js

Para realizar un alta de un Nuevo dispositivo utilizamos “Postman “seleccionamos la URL y la


opción de post.

Se añaden los diferentes datos del nuevo dispositivo a añadir como clave/valor, por ejemplo:

type: temperature

name: temperature sensor

description: a temperature sensor

unit: Celsius

value: 0

Página 17 de 29
Internet de las Cosas (IoT), Ciberseguridad y Aplicaciones. Curso 2023-2024

Una vez realizado el alta se verá por la consola de node.js el json enviado en “req.body”

Página 18 de 29
Internet de las Cosas (IoT), Ciberseguridad y Aplicaciones. Curso 2023-2024

La base de datos se puede consultar a través de la terminal para ello es necesario descargar la
herramienta del siguiente enlace

https://www.mongodb.com/try/download/shell

copiar los dos ficheros de la carpeta “bin” en la capreta “bin” del directorio de instalación de
mongodb tipo “C:\Program Files\MongoDB\Server\7.0\bin”

Desde otro terminal ejecutamos los siguientes pasos (sin importar el directorio donde nos
encontremos)

Acceder a la base de datos

mongosh

Ver las bases de datos disponibles

show dbs

Seleccionar la base de datos demoAPIREST

use demoAPIREST

Ver las colecciones de la base de datos

show collections

Mostrar todos los datos de la colección

db.devices.find().pretty()

Mostrando resultados como en la siguiente captura

Página 19 de 29
Internet de las Cosas (IoT), Ciberseguridad y Aplicaciones. Curso 2023-2024

Añadimos otro dispositivo desde “postman” por ejemplo:

Type: humidity

Name: Humidity Sensor

Description: description: A humidity sensor.

unit: %

value: 0

Página 20 de 29
Internet de las Cosas (IoT), Ciberseguridad y Aplicaciones. Curso 2023-2024

GET: Consultas al API REST


Se va a implementar una consulta que devuelve el dispositivo por su tipo, utilizando una petición
GET indicando el tipo del dispositivo
Para ello añadimos el siguiente código a server.js
//peticion GET para obtener los datos de un dispositivo por su tipo
app.get('/devices/:type', async (req, res) => {
try {
console.log(JSON.stringify(req.params, null, 2));
// Realiza la búsqueda con un filtro, por ejemplo, {"type":
"temperature"}
const devices = await Device.find(req.params).exec();
res.json(devices);
} catch (err) {
res.status(500).json({
msg: 'Error al buscar dispositivos',
error: err
});
}
});

Se comprueba con “postman”

Página 21 de 29
Internet de las Cosas (IoT), Ciberseguridad y Aplicaciones. Curso 2023-2024

PUT: modificaciones API REST


Para modificar el valor que contiene un dispositivo utilizaremos PUT , para ello identificamos el
dispositivo por su tipo y enviamos el nuevo “value” de tal manera que se almacena en el
parámetro “value”, quedando el código de la siguiente manera:
//Peticion PUT para atualizar los datos de un dispositivo
app.put('/devices/:type', async (req, res) => {
try {
// Busca el dispositivo por type y lo actualiza con los datos del
request
// Una mejor opcion es usar "ID" se usa findByIdAndUpdate,
const device = await Device.findOneAndUpdate(req.params,
req.body).exec();
res.json({
msg: 'Dispositivo actualizado correctamente',
device: device
});
} catch (err) {
res.status(500).json({
msg: 'Error al actualizar el dispositivo',
error: err
});
}
});

Página 22 de 29
Internet de las Cosas (IoT), Ciberseguridad y Aplicaciones. Curso 2023-2024

Desde “Postman” probamos a actualizar el dispositivo de temperatura:

Se puede comprobar con la herramienta “MongoDB Compass Community” accediendo a nuestra


colección “devices” (como se indicó anteriormente) y pulsando el botón actualizar podemos
comprobar que el dato se ha actualizado

DELETE: eliminación API REST

Ante una petición DELETE eliminaremos un dispositivo según el tipo indicado


//Peticion DELETE para borrar un dispositivo
app.delete('/devices/:type', async (req, res) => {
try {
console.log(JSON.stringify(req.params, null, 2));
// Busca el dispositivo por type y lo borra
const device = await Device.findOneAndDelete(req.params).exec();
res.json({
msg: 'Dispositivo borrado correctamente',
device: device
});
} catch (err) {
res.status(500).json({
msg: 'Error al borrar el dispositivo',
error: err
});
}
});

Página 23 de 29
Internet de las Cosas (IoT), Ciberseguridad y Aplicaciones. Curso 2023-2024

Desde “postman” hacemos la petición DELETE y el dispositivo a eliminar

Tras comprobar su eliminación lo volvemos a añadir el elemento para trabajar con él en el


siguiente apartado

Inyecciones NoSQL

Las bases de datos NoSQL tienen menos restricciones de coherencia y son más flexibles que las
relacionales, pero sin embargo esto ocasiona vulnerabilidades pudiendo ser posible realizar
consultas maliciosas que dejen ver información privada, o dar como afirmativo el acceso a un
login.

Vamos a añadir el código para poder realizar búsquedas por una petición post, ya que puede
surgir por requerimientos en el desarrollo de una aplicación. Para ello añadimos este apartado
en el código de server.js
//peticion post para buscar dispositivos
app.post('/devices/find', async (req, res) => {
try {
console.log(JSON.stringify(req.body, null, 2));
// Realiza la búsqueda con un filtro, por ejemplo, {"type":
"temperature"}
const devices = await Device.find(req.body).exec();
res.json(devices);
} catch (err) {
res.status(500).json({
msg: 'Error al buscar dispositivos',
error: err
});
}
});
Se va a realizar un ataque de inyección NoSQL anidando una consulta en este caso {"$gt": ""}
esta consulta devuelve todos los resultados en los que el tipo de dispositivo sea mayor que “” lo
que resulta verdadero y devuelve todos los datos en “Postman” se realiza de la siguiente
manera:

Página 24 de 29
Internet de las Cosas (IoT), Ciberseguridad y Aplicaciones. Curso 2023-2024

Anidamos la consulta en el parámetro “type”


{

"type": {"$gt":""}

Con esta inyección podemos ver todos los elementos de una colección, no solo los de las
consultas pudiendo de esta manera acceder a información que podría ser privada de otro
usuario.

Con el paquete “mongo-sanitize” https://www.npmjs.com/package/mongo-sanitize es posible


sanear las peticiones a la base de datos de MongoDB de tal manera que ante la misma ejecución
nos da el siguiente resultado:

Página 25 de 29
Internet de las Cosas (IoT), Ciberseguridad y Aplicaciones. Curso 2023-2024

Página 26 de 29
Internet de las Cosas (IoT), Ciberseguridad y Aplicaciones. Curso 2023-2024

Página 27 de 29
Internet de las Cosas (IoT), Ciberseguridad y Aplicaciones. Curso 2023-2024

Crear routes
var express = require('express');
var router = express.Router();

router.get('/devices/:type/:id', function (req, res) {


console.log(req.params);

res.json({
msg: 'el API REST funciona!'
});
});

module.exports = router;

var express = require('express');


var cors = require('cors');
var bodyParser = require('body-parser');
var rutes = require('./routes.js');
var app = express();
var port = 3000;
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cors());
//peticion get /devices como res el api funciona
app.use('/', rutes);

// listen del servidor en el puerto 3000


app.listen(port, function () {
console.log('Servidor node.js corriendo en el en un puerto ' + port);
});

Página 28 de 29
Internet de las Cosas (IoT), Ciberseguridad y Aplicaciones. Curso 2023-2024

Crear controllers

const Device = require('../models/device');

exports.deleteDevice = async (req, res) => {


try {
const device = await Device.findOneAndDelete({ type: req.params.type
}).exec();
res.json({
msg: 'Dispositivo borrado correctamente',
device: device
});
} catch (err) {
res.status(500).json({
msg: 'Error al borrar el dispositivo',
error: err
});
}
};

var deviceControllers = require('./controllers/deviceControllers');

app.delete('/devices/:type', deviceControllers.deleteDevice);

Página 29 de 29

También podría gustarte