Faceți 7 pași pentru a vă asigura că aplicația dvs. este invincibilă

Telefonul dvs. este blocat? Aveți un cod PIN, o parolă, o amprentă digitală sau FaceID? Sunt 99% sigur că da. Și este clar de ce – îți pasă de siguranța ta. În prezent, păstrarea telefonului protejat este la fel de importantă ca spălatul dinților dimineața.

Pentru dezvoltatorii de software sârguincioși și atenți, păstrarea aplicației în siguranță este la fel de importantă pentru protejarea telefoanelor lor. Dacă sunteți dezvoltator și alegeți să îl neglijați – vă rog să vă reconsiderați abordarea. Dacă sunteți proprietarul unui proiect și echipa dvs. de dezvoltare spune că siguranța datelor poate aștepta, vă rog să vă reconsiderați echipa.

În acest articol, vreau să vorbesc despre cum să mă asigur că Express.js proiectul este sigur și invincibil atacurilor rău intenționate.

Există 7 măsuri simple și nu foarte simple de luat în scopul securității datelor:

  1. Folosiți versiuni fiabile ale Express.js
  2. Securizați conexiunea și datele
  3. Protejați-vă cookie-urile
  4. Asigurați-vă dependențele
  5. Validați datele introduse de utilizatorii dvs.
  6. Protejați-vă sistemul împotriva forței brute
  7. Controlați accesul utilizatorilor

Să aruncăm o privire mai atentă la fiecare.

1. Utilizați versiuni fiabile ale Express.js

Versiunile învechite sau învechite ale Express.js nu sunt go. A doua și a treia versiune de Express nu mai sunt acceptate. În acestea, problemele de siguranță sau de performanță nu mai sunt rezolvate.

Ca dezvoltator, trebuie absolut migrează la Express 4. Această versiune este o revoluție! Este destul de diferit în ceea ce privește sistemul de rutare, middleware și alte aspecte minore.

2. Securizați conexiunea și datele

Pentru a securiza anteturile HTTP, puteți utiliza Helmet.js – un modul util Node.js. Este o colecție de 13 funcții middleware pentru setarea antetelor de răspuns HTTP. În special, există funcții pentru setarea politicii de securitate a conținutului, gestionarea transparenței certificatelor, prevenirea clicului, dezactivarea memorării în cache a clientului sau adăugarea unor mici protecții XSS.

npm install helmet --save

Chiar dacă nu doriți să utilizați toate funcțiile Helmet, minimul absolut pe care trebuie să îl faceți este să dezactivați antetul X-Powered-By:

app.disable('x-powered-by')

Acest antet poate fi utilizat pentru a detecta că aplicația este alimentată de Express, care permite hackerilor să efectueze un atac precis. Cu siguranță, antetul X-Powered-By nu este singura modalitate de a identifica o aplicație rulată Express, dar este probabil cea mai comună și simplă.

Pentru a vă proteja sistemul de atacurile de poluare a parametrilor HTTP, puteți utiliza HPP. Acest middleware pune deoparte parametri precum req.query și req.body și selectează în schimb cea mai recentă valoare a parametrului. Comanda de instalare arată după cum urmează:

npm install hpp --save

Pentru a cripta datele care sunt trimise de la client la server, utilizați Transport Layer Security (TLS). TLS este un protocol criptografic pentru securizarea rețelei de calculatoare, descendentul criptării Secure Socket Layer (SSL). TLS poate fi tratat cu Nginx – un server HTTP gratuit, dar eficient – și Să criptăm – un certificat TLS gratuit.

3. Protejați-vă cookie-urile

În Express.js 4, există două module de sesiune cookie:

  • express-session (în Express.js 3, a fost express.session)
  • cookie-session (în Express.js 3, a fost express.cookieSession)

Modulul de sesiune expres stochează ID-ul sesiunii în cookie și datele de sesiune de pe server. Sesiunea cookie stochează toate datele sesiunii pe cookie.

În general, sesiunea cookie este mai eficientă. Cu toate acestea, dacă datele de sesiune pe care trebuie să le stocați sunt complexe și probabil să depășească 4096 de octeți per cookie, utilizați sesiunea expresă. Un alt motiv pentru a utiliza express-session este atunci când trebuie să păstrați datele cookie invizibile pentru client.

În plus, ar trebui să setați opțiuni de securitate pentru cookie-uri, și anume:

  • sigur
  • httpNumai
  • domeniu
  • cale
  • expiră

Dacă „securizat” este setat la „adevărat”, browserul va trimite cookie-uri numai prin HTTPS. Dacă „httpOnly” este setat la „true”, cookie-ul va fi trimis nu prin intermediul clientului JS, ci prin HTTP (S). Valoarea „domeniu” indică domeniul cookie-ului. Dacă domeniul cookie se potrivește cu domeniul serverului, „cale” este utilizată pentru a indica calea cookie. Dacă calea cookie se potrivește cu calea cererii, cookie-ul va fi trimis în cerere. În sfârșit, așa cum sugerează și numele, valoarea „expiră” înseamnă perioada în care cookie-urile vor expira.

O altă recomandare importantă este să nu utilizați numele cookie-ului de sesiune implicit. Poate permite hackerilor să detecteze serverul și să execute un atac vizat. În schimb, utilizați nume de cookie generice.

4. Asigurați-vă dependențele

Fără îndoială, npm este un instrument puternic de dezvoltare web. Cu toate acestea, pentru a asigura cel mai înalt nivel de securitate, luați în considerare utilizarea doar a 6-a versiune – npm @ 6. Cele mai vechi pot conține unele vulnerabilități serioase de siguranță a dependenței, ceea ce va pune în pericol întreaga aplicație. De asemenea, pentru a analiza arborele dependențelor, utilizați următoarea comandă:

npm audit

Auditul npm poate ajuta la rezolvarea problemelor reale din proiect. Vă verifică toate dependențele în dependențe, devDependențe, pacheteleDependențe și opționaleDependențe, dar nu și peerDependencies. Aici puteți citi despre toate vulnerabilitățile actuale din orice pachet npm.

Asigurarea dependențelor

Un alt instrument pentru a asigura siguranța dependenței este Snyk. Snyk execută verificarea aplicației pentru a identifica dacă conține vreo vulnerabilitate listată în baza de date open source a Snyk. Pentru a efectua verificarea, executați trei pași simpli.

Pasul 1. Instalați Snyk

npm install -g snyk
cd your-app

Pasul 2. Rulați un test

snyk test

Pasul 3. Aflați cum să remediați problema

snyk wizard

Expertul este o metodă Snyk, care explică natura vulnerabilității dependenței și oferă modalități de remediere.

5. Validați datele introduse de utilizatorii dvs.

Controlul intrărilor utilizatorilor este o parte extrem de importantă pentru dezvoltarea de pe server. Aceasta este o problemă nu mai puțin importantă decât solicitările neautorizate, care vor fi descrise în a șaptea parte a acestui articol.

În primul rând, introducerea greșită a utilizatorului vă poate întrerupe serverul atunci când unele valori sunt nedefinite și nu aveți gestionarea erorilor pentru un anumit punct final. Cu toate acestea, diferite sisteme ORM pot avea un comportament imprevizibil atunci când încercați să setați tipuri de date nedefinite, nule sau alte tipuri de date în baza de date.

De exemplu, metoda destroyAll din Loopback.js ORM (cadrul Node.js) poate distruge toate datele dintr-un tabel al bazei de date: atunci când nu se potrivește cu nicio înregistrare, șterge totul așa cum este descris. Aici. Imaginați-vă că puteți pierde toate datele dintr-un tabel de producție doar pentru că ați ignorat validarea intrărilor.

Folosiți validarea corpului / obiectului pentru inspecții intermediare

Pentru început, puteți utiliza validarea corpului / obiectului pentru inspecții intermediare. De exemplu, folosim validatorul ajv care este cel mai rapid validator JSON Schema pentru Node.js.

const Ajv = require('ajv'); 
const ajv = new Ajv({allErrors: true}); 
const speaker = { 
  'type': 'object', 
  'required': [
    'id', 
    'name'
  ],
  'properties': { 
    'id': {
      'type': 'integer', 
    }, 
    'name': { 
      'type': 'string',
    }, 
  }, 
};
const conversation = { 
  type: 'object', 
  required: [
    'duration', 
    'monologues'
  ], 
  properties: { 
    duration: { 
      type: 'integer',
    }, 
    monologues: { 
      type: 'array', 
      items: monolog, 
    }, 
  }, 
};
const body = { 
  type: 'object', 
  required: [
    'speakers', 
    'conversations'
  ], 
  properties: { 
    speakers: { 
      type: 'array', 
      items: speaker, 
    }, 
    conversations: { 
      type: 'array', 
      items: conversation, 
    }, 
  }, 
}; 
const validate = ajv.compile(body); 
const isValidTranscriptBody = transcriptBody => { 
  const isValid = validate(transcriptBody);
  if (!isValid) { 
    console.error(validate.errors); 
  } 
  return isValid; 
};

Manipulați erorile

Acum, imaginați-vă că ați uitat să verificați un anumit obiect și faceți câteva operații cu proprietatea nedefinită. Sau folosești o anumită bibliotecă și primești o eroare. Vă poate rupe instanța, iar serverul se va prăbuși. Apoi, atacatorul poate face ping la un anumit punct final în care există această vulnerabilitate și poate opri serverul pentru o lungă perioadă de timp.

Cel mai simplu mod de a face o eroare este de a utiliza construcția try-catch:

try { 
  const data = body;
  if (data.length === 0) throw new Error('Client Error'); 
  const beacons = await  this.beaconLogService.filterBeacon(data); 
  if (beacons.length > 0) { 
    const max = beacons.reduce((prev, current) => (prev.rssi > current.rssi) ? prev : current); 
    await this.beaconLogService.save({ 
      ...max,
      userId: headers['x-uuid'] 
    }); 
    return { 
      data: { 
        status: 'Saved', 
        position: max 
      }, 
    }; 
  } 
  return { 
    data: { 
      status: 'Not valid object, 
    }, 
  }; 
} 
catch(err) { 
  this.logger.error(err.message, err.stack); 
  throw new HttpException('Server Error',     HttpStatus.INTERNAL_SERVER_ERROR); 
}

Simțiți-vă liber să utilizați un nou constructor de erori („mesaj”) pentru gestionarea erorilor sau chiar extindeți această clasă pentru propriul dvs. scop!

Folosiți JOI

Lecția principală aici este că ar trebui să validați întotdeauna datele utilizatorului, astfel încât să nu fiți victima atacurilor om-în-mijloc. O altă modalitate de a face acest lucru este cu ajutorul @ hapi / joi – o parte a ecosistemului hapi și o bibliotecă puternică de validare a datelor JS.

Acordați atenție aici modulului joi a fost depreciat. Din acest motiv, următoarea comandă este fără oprire:

npm install joi

În schimb, utilizați-l pe acesta:

npm install @hapi/joi

Utilizați validator expres

O altă modalitate de a valida intrarea utilizatorului este de a utiliza expres-validator – un set de middlewares express.js, care cuprinde validator.js și funcția de dezinfectare. Pentru a-l instala, executați următoarea comandă:

npm install --save express-validator 

Dezinfectați introducerea utilizatorului

De asemenea, o măsură importantă de luat este de a igieniza datele introduse de utilizator pentru a proteja sistemul de o injecție de operator MongoDB. Pentru aceasta, ar trebui să instalați și să utilizați express-mongo-sanitize:

npm install express-mongo-sanitize

Protejați-vă aplicația împotriva CSRF

În plus, ar trebui să vă protejați aplicația împotriva falsificării cererilor între site-uri (CSRF). CSRF este atunci când comenzile neautorizate sunt trimise de la un utilizator de încredere. Puteți face acest lucru cu ajutorul csurf. Înainte de aceasta, trebuie să vă asigurați că middleware-ul de sesiune pentru cookie-uri este configurat așa cum este descris anterior în acest articol. Pentru a instala acest modul Node.js, rulați comanda:

npm install csurf 

6. Protejați-vă sistemul împotriva forței brute

Un atac cu forță brută este cel mai simplu și cel mai comun mod de a obține acces la un site web sau la un server. Hackerul (în majoritatea cazurilor automat, rareori manual) încearcă în mod repetat diferite nume de utilizator și parole pentru a pătrunde în sistem.

Aceste atacuri pot fi prevenite cu ajutorul limitator de viteză-flexibil pachet. Acest pachet este rapid, flexibil și potrivit pentru orice cadru de noduri.

Pentru a instala, executați următoarea comandă:

npm i --save rate-limiter-flexible
yarn add rate-limiter-flexible

Această metodă are o alternativă mai simplă, dar mai primitivă: expres-rate-limit. Singurul lucru pe care îl face este să limiteze solicitările repetate către API-urile publice sau la resetarea parolei.

npm install --save express-rate-limit

7. Controlează accesul utilizatorului

Printre metodele de autentificare, există jetoane, Auth0 și JTW. Să ne concentrăm pe a treia! JTW (JSON Web Tokens) sunt utilizate pentru a transfera date de autentificare în aplicații client-server. Jetoanele sunt create de server, semnate cu o cheie secretă și transferate către un client. Apoi, clientul folosește aceste jetoane pentru a confirma identitatea.

Express-jwt-permissions este un instrument folosit împreună cu expres-jwt pentru a verifica permisiunile unui anumit simbol. Aceste permisiuni sunt o serie de șiruri din interiorul simbolului:

"permissions": [
  "status",
  "user:read",
  "user:write"
]

Pentru a instala instrumentul, executați următoarea comandă:

npm install express-jwt-permissions --save

Pentru a încheia

Aici am enumerat cele mai bune practici esențiale de securitate Express.js și câteva instrumente care pot fi utilizate pe parcurs.

Doar pentru a revizui:

Asigurarea dependențelor

Vă recomand cu tărie să vă asigurați că aplicația dvs. este rezistentă la atacuri rău intenționate. În caz contrar, afacerea dvs. și utilizatorii dvs. pot suferi pierderi semnificative.

Ai o idee pentru proiectul Express.js?

Compania mea KeenEthics are experiență în exprimă dezvoltarea js. În cazul în care aveți nevoie de o estimare gratuită a unui proiect similar, nu ezitați Intrați în legătură.

Dacă v-a plăcut articolul, ar trebui să continuați cu siguranță cu o parte despre siguranța datelor în externalizarea către Ucraina: Echipa KeenEthics de gardă: datele dvs. sunt sigure în Ucraina. Articolul original postat pe blogul KeenEthics poate fi găsit aici: sfaturi de securitate express js.

PS

Un strigăt uriaș către Volodia Andrushchak, Dezvoltator de software Full-Stack @KeenEthics pentru că m-a ajutat cu articolul.

Articolul original postat pe blogul KeenEthics poate fi găsit aici: Sfaturi de securitate Express.js: Salvați-vă aplicația!