# Security and API * Defense on depth * Best Practices for web servers + switch off unnecessary funtionality + limit secure remote access + use accounts with limited privileges + segregate development, testing and live environment + segregate data + secrity patches + monitor and audit servers and logs + use security tools * Top 10 Application security risks + Injection - + Broken authentication - compromised passwords + sensitive data exposure + xxe + broken acess control + security misconfiguration [Equifax case study](https://www.csoonline.com/article/3444488/equifax-data-breach-faq-what-happened-who-was-affected-what-was-the-impact.html) * security patches * broken authentication * broken access control * security misconfiguration * single point of failure * lack of management commitment ## Security od Data in motion * HTTPS / FTPS * Type of SSL Certificates + Signed by a Cerficate Authority (CA) + Self-signed certificates (less trusted. For testing) + self sigend ``` $ openssl genrsa -out key.pem $ openssl req -new -key key.pem -out csr.pem $ openssl x509 -req -days 9999 -in csr.pem -signkey key.pem -out cert.pem $ rm csr.pem ``` ```Javascript ``` * role based access control ## Security date at rest * encrypt + sensitive files + storage drive + password * security of username and password ## Regulation and Standards * [international](https://www.pcisecuritystandards.org/) * [Singapore](https://www.mas.gov.sg/regulation/guidelines/technology-risk-management-guidelines) * [Personal Data Protection Act](https://www.pdpc.gov.sg/Overview-of-PDPA/The-Legislation/Personal-Data-Protection-Act) * [FintTech Service](https://singaporefintech.org/sfa-launches-digital-self-assessment-framework-to-fast-track-fintech-firms-partnerships-with-financial-institutions/) ## API Security * Basic Authentication * API key * Bearer token * JSON Web Token (JWT) ## SQL Injection attack * sending body `{ id = "5 or 1=1" }`, will return all records. Thus, data leak * need strong validation of inputs ```javascript // GET route for /user/id query // with body = { "id": 2 } app.get("/user/id", (request, response) => { console.log(request.body); // !!! validation example !!! if (request.body.id === null || Number.isNaN(request.body.id) || !Number.isInteger(request.body.id)) { response.send("Some id error occur"); return; } // connection.query(`SELECT * FROM users WHERE user_id = ${request.body.id}`, (err, result) => { if (err) { response.send("Some id error occur"); } else { response.send(result); } }); }); ``` ## Code organisation & management * folder tree + \server.js + \database.js + \routes => store all routes + \routes\customer.js + \routes\seller.js * modularise into individual module file + server.js : setup server listen and route linkage ```javascript const express = require("express"); const bodyParser = require("body-parser"); const CustomerRouter = require("./routes/customer"); const SellerRouter = require("./routes/seller"); let app = express(); //uri mapper app.use(bodyParser.json()); app.use("/customer", CustomerRouter); app.use("/seller", SellerRouter); app.listen(3000); ``` + database.js : database connection ```javascript const mysql = require("mysql"); let params = { host: "localhost", user: "root", password: "root", database: "sales", }; mysqlConnection = mysql.createConnection(params); mysqlConnection.connect((err) => { if (err) { console.log("Failed to Connect"); } else { console.log("Connection successful"); } }); module.exports = mysqlConnection; ``` + customer.js : customer apis ```javascript const express = require("express"); const connection = require("../database"); // import database connection CustomerRouter = express.Router(); // localhost:3000/customer/ CustomerRouter.get("/", (req, res) => { connection.query("select * from customer", (err, rows) => { if (err) { console.log(err); res.send("Some error occurred"); } else { res.send(rows); } }); }); // localhost:3000/customer/name/Zixuan CustomerRouter.get("/name/:value", (req, res) => { connection.query( `select * from customer where customer_name = '${req.params.value}'`, (err, rows) => { if (err) { console.log(err); res.send("Some error occurred"); } else { res.send(rows); } } ); }); // localhost:3000/customer/id/10 CustomerRouter.delete("/id/:value", (req, res) => { connection.query( `delete from customer where customer_id = ${req.params.value}`, (err, rows) => { if (err) { console.log(err); res.send("Some error occurred"); } else { res.send("Deleted Successfully"); } } ); }); module.exports = CustomerRouter; ``` + seller.js : seller apis ```javascript const express = require("express"); const connection = require("../database"); SellerRouter = express.Router(); // localhost:3000/seller/ SellerRouter.post("/", (req, res) => { connection.query( `insert into seller (seller_name, seller_wallet) values ('${req.body. name}',${req.body.wallet})`, (err, rows) => { if (err) { console.log(err); res.send("Some error occurred."); } else { res.send("Saved Successfully."); } } ); }); module.exports = SellerRouter; ``` * sample client fetch ```javascript const fetch = require("node-fetch"); fetch("http://localhost:3000/customer/name/Zixuan", { method: "get", // body: JSON.stringify( // (body = { // name: "dixant", // email: "mittal", // }) // ), headers: { "Content-Type": "application/json" }, }) .then((res) => res.json()) .then((json) => console.log(json)); ``` * API key ```javascript connection.query( `SELECT * FROM client WHERE client_id = ${request.body.client_id} AND client_key = '${request.body.client_key}'`, (err, result) => { if (ok) serve the request... ... } ) ``` * Backend server + formatting conflicting + flexibility with separation + separation on client-ui and backend