【譯】Nodejs應用安全備忘錄

本人的博客http://www.wjs.photo/,感興趣的能夠看看哦,基於NodeJs框架ThinkJs前端

本文翻譯自 www.risingstack.com ,並不是逐字逐句的翻譯,有錯誤的地方請指出,謝謝啦
應用程序的安全就像是你房間裏忽然出現一隻大象,那麼明顯,可是寫代碼的同窗仍是會忽略。也都認爲應用程序的安全很是重要可是卻不多有時間認真對待,畢竟咱們有那麼多bug要改(壞笑)。因此咱們整理了一個NodeJs應用安全備忘錄,以幫助你在部署啓動NodeJs應用程序的時候進行安全檢查。固然,這些項目大部分是通用的,適用於全部的語言和框架而不只僅是Node.js。可是本文具體還涉及到一些Node.js的工具。感興趣的同窗也能夠查看個人介紹Node.js的安全性的博客。node


配置管理(Configuration Management)

HTTP安全頭部

Strict-Transport-Security:強制經過(SSL/TLS上的HTTP)鏈接到服務器
X-Frame-Options:提供阻止點擊挾持攻擊
X-XSS-Protection:啓用瀏覽器內置的跨站點腳本(XSS)篩選器
X-Content-Type-Options:防止瀏覽器從MIME探查從聲明內容類型的響應
Content-Security-Policy:防止各類攻擊,包括跨站點腳本和其餘跨網站注射
在Express中,咱們能夠很容易用helmet來設置這些頭部:nginx

var express = require('express'); 
var helmet = require('helmet');
var app = express();
app.use(helmet());

固然,在koa框架中也可使用:傳送門
這些頭部不僅是能夠放在代碼中,也能夠配置在web服務器中(Apache、nginx),這樣也就省了改動程序代碼git

# nginx.conf
    add_header X-Frame-Options SAMEORIGIN; 
    add_header X-Content-Type-Options nosniff; 
    add_header X-XSS-Protection "1; mode=block"; 
    add_header Content-Security-Policy "default-src 'self'";

nginx服務器的配置也能夠參考:這裏github

客戶端的敏感數據

在部署前端應用程序時要確保不會將祕密的API公開,公開的API會被任何人訪問
雖然沒有好的自動檢查的方法,但有兩個注意點能夠減輕因爲意外而暴露敏感數據的風險
1.檢查使用的請求
2.常規的代碼審查web

身份驗證

Brute Force Protection(暴力攻擊防禦)

暴力破解(也稱窮舉法),即將密碼進行逐個推算直到找到真正的密碼,而後在web應用程序中登陸。
爲了防止應用程序受到暴力破解的攻擊,應用程序最好要有密碼錯誤允許次數機制,在NodeJs中,你可使用:ratelimiter正則表達式

var limit = new Limiter({ id: email, db: db }); 
      limit.get(function(err, limit) { });

固然啦,你也能夠將他包裝成一箇中間件,就能夠放在應用程序中,不管是Express框架仍是Koa框都有厲害的中間件,在koa框架中,他多是這個樣子:redis

var ratelimit = require('koa-ratelimit');  
  var redis = require('redis');  var koa = require('koa');  
  var app = koa(); 
  var emailBasedRatelimit = ratelimit({
  db: redis.createClient(),   
  duration: 60000,   
  max: 10,   
  id: function (context) {     
  return context.body.email;   
  } }); 
  var ipBasedRatelimit = ratelimit({
  db: redis.createClient(),   
  duration: 60000,   
  max: 10,   
  id: function (context) {     
   return context.ip;   
   } 
   }); 
   app.post('/login', ipBasedRatelimit, emailBasedRatelimit, handleLogin);

咱們在這裏作的是有限的用戶在給定的時間裏(60000毫秒)能夠出錯多少次(10次),這樣咱們的程序能夠減輕被暴力破解的風險。不過這些配置必須爲給定的應用,不要直接複製粘貼他們。算法

會話管理

安全使用Cookie的重要性不能被低估:尤爲是在動態Web應用程序,這就須要保持整個無狀態協議狀態,如HTTP
Cookie的屬性列表
secure —這個屬性設置爲true時是告訴瀏覽器若是正在經過HTTPS發送請求,只發送cookie。
HttpOnly—-若是Cookie中設置了這個屬性,那麼經過程序(JS腳本、Applet等)將沒法讀取到Cookie信息,能夠有效的用來防止諸如跨站點腳本攻擊
限制cookie的做用範圍
Domain--這個屬性是用來比較中被請求的URL服務器的域。若是域匹配,或者若是它是一個子域,則路徑屬性將下一個檢查。
path--除了Domain,該Cookie有效期能夠指定URL路徑。若是域名和路徑匹配,那麼該cookie將被請求發送。
expires --這個屬性是用來設置Cookie的到期時間,由於該cookie不會過時,直到超出設定的日期sql

在NodeJs中,能夠很容易的建立cookie, 經過cookies或者cookie-session

var cookieSession = require('cookie-session');  
 var express = require('express'); var app = express(); 
 app.use(cookieSession({    name: 'session',   
 keys: [     process.env.COOKIE_KEY1,     process.env.COOKIE_KEY2   ] }));
 app.use(function (req, res, next) {    
     var n = req.session.views || 0;   
     req.session.views = n++;    
     res.end(n + ' views'); 
    }); 
 app.listen(3000);

(這個例子是取自cookie的會話模塊文檔)。

CSRF(跨站請求僞造)

跨站請求僞造一種挾持用戶在當前已登陸的web應用程序上執行非本身操做的攻擊方法,這種攻擊專門針對更改請求,而不是竊取數據,由於攻擊者也無法比見到僞造請求的響應
在NodeJs中要減輕這種攻擊,可使用 [csrf] (https://www.npmjs.com/package...塊,因爲這個比較底層,也有不一樣的框架包裝好的,這個例子是csurf模塊,用於CSRF保護明文中間件
在路由中,你須要作的是:

var cookieParser = require('cookie-parser');   
 var csrf = require('csurf');  
 var bodyParser = require('body-parser');         
 var express = require('express'); 
 // setup route middlewares 
 var csrfProtection = csrf({ cookie: true });  
 var parseForm = bodyParser.urlencoded({ extended: false }); 
 // create express app 
 var app = express(); 
 // we need this because "cookie" is true in csrfProtection  
 app.use(cookieParser()); 
 app.get('/form', csrfProtection, function(req, res) {  
 // pass the csrfToken to the view   
   res.render('send', { csrfToken: req.csrfToken() }); }); 
   app.post('/process', parseForm, csrfProtection, function(req, res) {    
     res.send('data is being processed');
    });

而後在視圖層:

<form action="/process" method="POST">    
  <input type="hidden" name="_csrf" value="{{csrfToken}}">Favorite color: 
  <input type="text" name="favoriteColor">
  <button type="submit">Submit</button>
 </form>

(這個例子是取自csurf模塊文檔)。

數據驗證

XSS有兩個類似,但不一樣類型的攻擊防範。一個是跨站腳本的反射版本,另外一個是存儲跨站腳本。
反射式跨站腳本,經過注入發送帶有惡意腳本代碼參數的URL,當URL地址被打開時,特有的惡意代碼參數被HTML解析、執行。
存儲跨站腳本,指的是惡意腳本代碼被存儲進被攻擊的數據庫,當其餘用戶正常瀏覽網頁時,站點從數據庫中讀取了非法用戶存入非法數據,惡意腳本代碼被執行。
爲了抵禦這類攻擊,確保你過濾或者清理用戶輸入

SQL注入

SQL注入是由用戶輸入部分或完整的SQL查詢的注入。它能夠讀取敏感信息。

select title, author from books where id=$id

在這個實例代碼中,參數$id若是用戶輸入的是2 or 1=1?,那查詢變爲以下:

select title, author from books where id=2 or 1=1

防範這類攻擊的最簡單的方法是使用參數化查詢或準備好的語句
SqlMap是一個開源的滲透測試工具,它能夠自動檢測並利用SQL注入漏洞和接管數據庫服務器的過程。使用此工具來測試SQL注入漏洞的應用程序。

命令注入

命令注入是由攻擊者向遠程的Web服務器上運行的系統命令的技術。用這種方法攻擊者可能甚至獲得的系統的密碼。
在實際開發中,若是你有一個網址,如:

https://example.com/downloads?file=user1.txt

它能夠變成:

https://example.com/downloads?file=%3Bcat%20/etc/passwd

在這個例子中%3B變成了分號,因此多個系統命令能夠運行。
爲了抵禦這類攻擊,確保你始終過濾或清理了用戶輸入
另外,在Node.js中咱們能夠這樣來檢測:

child_process.exec('ls', function (err, data) {      console.log(data); });

child_process.exec建立一個子線程來調用執行/bin/sh,因此他是一個bash的解釋,而不是一個程序的啓動,當用戶輸入被傳遞給這個方法,就會被執行,顯示目錄下的全部文件。一個新的命令被攻擊者注入。
爲了防止被攻擊,可使用child_process.execFile

安全傳輸

SSL版本,算法,密鑰長度

因爲HTTP是一種明文協議,若是經過了SSL / TLS隧道,被稱爲HTTPS進行保護。現在高檔的密碼一般使用,在服務器配置錯誤能夠用來強制使用弱密碼 - 或者在最壞的狀況沒有加密。
你必須測試:

  • 密碼,鑰匙和從新談判的配置是否正確

  • 證書有效期

使用工具NMAPsslyze能夠很容易掃描出來
檢查證書信息

nmap --script ssl-cert,ssl-enum-ciphers -p 443,465,993,995 www.example.com

利用sslyze能夠測試SSL / TLS的漏洞

./sslyze.py --regular example.com:443

HSTS

在配置管理的一部分,咱們使用這個briefly - Strict-Transport-Security 頭強制執行安全(基於SSL的HTTP / TLS)鏈接到服務器上。就拿從Twitter下面的例子:

strict-transport-security:max-age=631138519

這裏max-age定義爲秒,瀏覽器自動將全部的HTTP請求轉換爲HTTPS的數量。
它的測試是很是簡單的:

curl -s -D- https://twitter.com/ | grep -i Strict

拒絕服務

賬戶鎖定

賬戶鎖定是減小暴力攻擊的方法。這就意味着,若是帳戶屢次登陸失敗,就讓這個帳戶在必定時間內(最初也能夠是一兩分鐘,而後就能夠成倍增長)鎖定。
這能夠保護應用程序不被攻擊。

正則表達式

大多數正則表達式可能會致使攻擊者的破解工做變得緩慢和低效。這些的正則表達式被稱爲邪惡的正則表達式:

  • 與重複分組

  • 裏面的重複組

    • 重複

    • 輪換具備重疊

([a-zA-Z]+)*,(a+)+或者(a|a?)+是全部弱勢的正則表達式做爲一個簡單的輸入同樣aaaaaaaaaaaaaaaaaaaaaaaa!會致使重計算。每增長一個a,時間就會翻倍。

在NodeJs中,若是要檢查正則表達式,你能夠safe-regex

$ node safe.js '(beep|boop)*' true  $ node safe.js '(a+){10}' false

錯誤處理

錯誤代碼,堆棧跟蹤

不一樣的錯誤狀況的應用程序可能會泄漏對底層基礎架構的敏感細節,如:X-Powered-By:Express。
棧跟蹤不被視爲本身的漏洞,但他們每每多是吸引的攻擊者的信息。提供了調試信息和產生錯誤操做的結果都被認爲是很差的作法。應該用日誌記錄下來,而不是顯示給用戶。

NPM

NPM有不少包提供給你們使用,可是這也是有代價的:應該好好檢查你須要爲你的應用程序是什麼。也許你使用以後可能含有重要的安全問題。

The Node Security Platform

不過幸運的是,有一個偉大的工具--The Node Security Platform,能夠檢查使用的模塊爲已知的漏洞。

npm i nsp -g  # either audit the shrinkwrap nsp audit-shrinkwrap  # or the package.json nsp audit-package

你還可使用requireSafe

SnykSnyk

SnykSnyk相似於The Node Security Platform,但他的目的是提供一種工具,不能只檢測,只是在代碼庫修復安全相關的問題。
更多信息你能夠看看snyk.io
本人的博客http://www.wjs.photo/,感興趣的能夠看看哦,基於NodeJs框架ThinkJs

相關文章
相關標籤/搜索