security
parent
aa95fcefe8
commit
560f53928a
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
@ -0,0 +1,256 @@
|
||||
# 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
|
||||
Loading…
Reference in New Issue