You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

6.4 KiB

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

  • 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
    
    
    
  • role based access control

Security date at rest

  • encrypt
    • sensitive files
    • storage drive
    • password
  • security of username and password

Regulation and Standards

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
// 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
    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
    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
    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
    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

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

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