Dalam landskap digital hari ini, melindungi aplikasi Node.js anda adalah yang terpenting. Daripada pemimpin global seperti Netflix dan Uber, kepada syarikat baru yang membina perkara besar seterusnya, Node.js menguasai beberapa aplikasi yang paling menuntut dan berprestasi tinggi. Walau bagaimanapun, kelemahan dalam aplikasi anda boleh membawa kepada akses tanpa kebenaran, pelanggaran data dan kehilangan kepercayaan pengguna.
Panduan ini menggabungkan amalan keselamatan praktikal dengan konsep utama daripada Panduan Pengujian Keselamatan Web OWASP (WSTG) untuk membantu anda mengukuhkan aplikasi Node.js anda. Sama ada anda mengurus operasi masa nyata atau menskalakan kepada berjuta-juta pengguna, sumber komprehensif ini akan memastikan aplikasi anda kekal selamat, boleh dipercayai dan berdaya tahan.
Pengumpulan Maklumat selalunya merupakan langkah pertama yang diambil oleh penyerang untuk mengetahui lebih lanjut tentang aplikasi anda. Lebih banyak maklumat yang mereka boleh kumpulkan, lebih mudah bagi mereka untuk mengenal pasti dan mengeksploitasi kelemahan.
Secara lalai, Express.js termasuk tetapan yang secara tidak sengaja boleh mendedahkan maklumat tentang pelayan anda. Contoh biasa ialah pengepala HTTP X-Powered-By, yang menunjukkan bahawa aplikasi anda menggunakan Express.
Contoh Kod Rentan:
const express = require('express'); const app = express(); // Your routes here app.listen(3000, () => { console.log('Server is running on port 3000'); });
Dalam persediaan ini, setiap respons HTTP termasuk pengepala X-Powered-By: Express.
Isu:
Mitigasi:
Lumpuhkan pengepala ini untuk menyukarkan penyerang cap jari pelayan anda.
Kod Diperbaik:
const express = require('express'); const app = express(); // Disable the X-Powered-By header app.disable('x-powered-by'); // Your routes here app.listen(3000, () => { console.log('Server is running on port 3000'); });
Tebatan Dipertingkatkan dengan Topi Keledar:
Pendekatan yang lebih baik ialah menggunakan perisian tengah topi keledar, yang menetapkan pelbagai pengepala HTTP untuk meningkatkan keselamatan apl anda.
const express = require('express'); const helmet = require('helmet'); const app = express(); // Use Helmet to secure headers app.use(helmet()); // Your routes here app.listen(3000, () => { console.log('Server is running on port 3000'); });
Kenapa Gunakan Topi Keledar?
Pengurusan konfigurasi dan penggunaan ialah aspek kritikal keselamatan aplikasi. Salah konfigurasi boleh berfungsi sebagai pintu terbuka untuk penyerang.
Menjalankan aplikasi anda dalam mod pembangunan pada pelayan pengeluaran boleh mendedahkan mesej ralat terperinci dan surih tindanan.
Contoh Kod Rentan:
const express = require('express'); const app = express(); // Your routes here app.listen(3000, () => { console.log('Server is running on port 3000'); });
Dalam persediaan ini, mesej ralat terperinci dihantar kepada pelanggan.
Isu:
Mitigasi:
Tetapkan NODE_ENV kepada 'pengeluaran' dan gunakan mesej ralat generik dalam pengeluaran.
Kod Diperbaik:
const express = require('express'); const app = express(); // Disable the X-Powered-By header app.disable('x-powered-by'); // Your routes here app.listen(3000, () => { console.log('Server is running on port 3000'); });
Amalan Terbaik:
Menggunakan bukti kelayakan lalai atau lemah, seperti kunci rahsia ringkas untuk menandatangani JSON Web Token (JWT), ialah kesilapan keselamatan yang biasa.
Contoh Kod Rentan:
const express = require('express'); const helmet = require('helmet'); const app = express(); // Use Helmet to secure headers app.use(helmet()); // Your routes here app.listen(3000, () => { console.log('Server is running on port 3000'); });
Isu:
Mitigasi:
Gunakan kunci rahsia yang kukuh dan selamat dan simpannya dengan selamat.
Kod Diperbaik:
// app.js const express = require('express'); const app = express(); // Error handling middleware app.use((err, req, res, next) => { res.status(500).send(err.stack); // Sends stack trace to the client }); // Your routes here app.listen(3000);
Amalan Terbaik:
Pengurusan identiti adalah penting untuk melindungi akaun pengguna dan menghalang akses tanpa kebenaran.
Membenarkan nama pengguna yang lemah dan menyediakan mesej ralat tertentu boleh membawa kepada serangan penghitungan akaun.
Contoh Kod Rentan:
const express = require('express'); const app = express(); // Your routes here app.listen(3000, () => { console.log('Server is running on port 3000'); });
Isu:
Mitigasi:
Laksanakan pengesahan nama pengguna dan gunakan mesej ralat generik.
Kod Diperbaik:
const express = require('express'); const app = express(); // Disable the X-Powered-By header app.disable('x-powered-by'); // Your routes here app.listen(3000, () => { console.log('Server is running on port 3000'); });
Penjelasan:
Pengesahan adalah penting untuk mengesahkan identiti pengguna dan menghalang akses tanpa kebenaran.
Kekurangan perlindungan membolehkan penyerang meneka kata laluan atau kod 2FA melalui percubaan berulang.
Contoh Kod Rentan:
const express = require('express'); const helmet = require('helmet'); const app = express(); // Use Helmet to secure headers app.use(helmet()); // Your routes here app.listen(3000, () => { console.log('Server is running on port 3000'); });
Isu:
Mitigasi:
Laksanakan pengehadan kadar dan tingkatkan keselamatan 2FA.
Kod Diperbaik:
// app.js const express = require('express'); const app = express(); // Error handling middleware app.use((err, req, res, next) => { res.status(500).send(err.stack); // Sends stack trace to the client }); // Your routes here app.listen(3000);
Langkah Tambahan:
Penjelasan:
Keizinan memastikan pengguna mengakses sumber yang dibenarkan untuk digunakan sahaja, menghalang tindakan yang tidak dibenarkan.
Pengguna boleh mengakses sumber yang tidak dibenarkan dengan memanipulasi pengecam dalam permintaan.
Contoh Kod Rentan:
// app.js const express = require('express'); const app = express(); // Your routes here // Error handling middleware if (app.get('env') === 'production') { // Production error handler app.use((err, req, res, next) => { // Log the error internally console.error(err); res.status(500).send('An unexpected error occurred.'); }); } else { // Development error handler (with stack trace) app.use((err, req, res, next) => { res.status(500).send(`<pre class="brush:php;toolbar:false">${err.stack}`); }); } app.listen(3000);
Isu:
Mitigasi:
Sahkan pemilikan sumber sebelum memberikan akses.
Kod Diperbaik:
const express = require('express'); const app = express(); // Your routes here app.listen(3000, () => { console.log('Server is running on port 3000'); });
Penjelasan:
Pengurusan sesi adalah penting untuk mengekalkan keadaan pengguna dan memastikan interaksi yang selamat.
Token yang tidak pernah luput menimbulkan risiko keselamatan jika ia dikompromi.
Contoh Kod Rentan:
const express = require('express'); const app = express(); // Disable the X-Powered-By header app.disable('x-powered-by'); // Your routes here app.listen(3000, () => { console.log('Server is running on port 3000'); });
Isu:
Mitigasi:
Tetapkan masa tamat tempoh pada token.
Kod Diperbaik:
const express = require('express'); const helmet = require('helmet'); const app = express(); // Use Helmet to secure headers app.use(helmet()); // Your routes here app.listen(3000, () => { console.log('Server is running on port 3000'); });
Penjelasan:
Menyimpan token dalam localStorage mendedahkannya kepada serangan skrip merentas tapak (XSS).
Contoh Kod Rentan:
// app.js const express = require('express'); const app = express(); // Error handling middleware app.use((err, req, res, next) => { res.status(500).send(err.stack); // Sends stack trace to the client }); // Your routes here app.listen(3000);
Isu:
Mitigasi:
Gunakan kuki HTTP sahaja untuk menyimpan token dengan selamat.
Kod Diperbaik:
// app.js const express = require('express'); const app = express(); // Your routes here // Error handling middleware if (app.get('env') === 'production') { // Production error handler app.use((err, req, res, next) => { // Log the error internally console.error(err); res.status(500).send('An unexpected error occurred.'); }); } else { // Development error handler (with stack trace) app.use((err, req, res, next) => { res.status(500).send(`<pre class="brush:php;toolbar:false">${err.stack}`); }); } app.listen(3000);
Penjelasan:
Pengesahan input memastikan data yang diberikan pengguna selamat dan dijangka, menghalang serangan suntikan.
Menerima dan memproses input pengguna tanpa pengesahan boleh membawa kepada kelemahan.
Contoh Kod Rentan:
const express = require('express'); const jwt = require('jsonwebtoken'); const app = express(); // Weak secret key const SECRET_KEY = 'secret'; app.post('/login', (req, res) => { // Authenticate user (authentication logic not shown) const userId = req.body.userId; // Sign the JWT with a weak secret const token = jwt.sign({ userId }, SECRET_KEY); res.json({ token }); }); app.get('/protected', (req, res) => { const token = req.headers['authorization']; try { // Verify the token using the weak secret const decoded = jwt.verify(token, SECRET_KEY); res.send('Access granted to protected data'); } catch (err) { res.status(401).send('Unauthorized'); } }); app.listen(3000, () => { console.log('Server started on port 3000'); });
Isu:
Mitigasi:
Sahkan dan bersihkan semua input pengguna.
Kod Diperbaik:
const express = require('express'); const app = express(); // Your routes here app.listen(3000, () => { console.log('Server is running on port 3000'); });
Penjelasan:
Pengendalian ralat yang betul mengelakkan daripada mendedahkan maklumat sensitif dan meningkatkan pengalaman pengguna.
Mesej ralat terperinci boleh mendedahkan dalaman sistem kepada penyerang.
Contoh Kod Rentan:
const express = require('express'); const app = express(); // Disable the X-Powered-By header app.disable('x-powered-by'); // Your routes here app.listen(3000, () => { console.log('Server is running on port 3000'); });
Isu:
Mitigasi:
Gunakan mesej ralat generik dan log ralat terperinci secara dalaman.
Kod Diperbaik:
const express = require('express'); const helmet = require('helmet'); const app = express(); // Use Helmet to secure headers app.use(helmet()); // Your routes here app.listen(3000, () => { console.log('Server is running on port 3000'); });
Penjelasan:
Kriptografi melindungi data sensitif; menggunakan amalan kriptografi yang lemah menjejaskan keselamatan.
Mencincang kata laluan dengan algoritma lapuk adalah tidak selamat.
Contoh Kod Rentan:
// app.js const express = require('express'); const app = express(); // Error handling middleware app.use((err, req, res, next) => { res.status(500).send(err.stack); // Sends stack trace to the client }); // Your routes here app.listen(3000);
Isu:
Mitigasi:
Gunakan algoritma pencincangan yang kuat direka bentuk untuk kata laluan.
Kod Diperbaik:
// app.js const express = require('express'); const app = express(); // Your routes here // Error handling middleware if (app.get('env') === 'production') { // Production error handler app.use((err, req, res, next) => { // Log the error internally console.error(err); res.status(500).send('An unexpected error occurred.'); }); } else { // Development error handler (with stack trace) app.use((err, req, res, next) => { res.status(500).send(`<pre class="brush:php;toolbar:false">${err.stack}`); }); } app.listen(3000);
Penjelasan:
Menyimpan rahsia secara langsung dalam kod meningkatkan risiko pendedahan.
Contoh Kod Rentan:
const express = require('express'); const jwt = require('jsonwebtoken'); const app = express(); // Weak secret key const SECRET_KEY = 'secret'; app.post('/login', (req, res) => { // Authenticate user (authentication logic not shown) const userId = req.body.userId; // Sign the JWT with a weak secret const token = jwt.sign({ userId }, SECRET_KEY); res.json({ token }); }); app.get('/protected', (req, res) => { const token = req.headers['authorization']; try { // Verify the token using the weak secret const decoded = jwt.verify(token, SECRET_KEY); res.send('Access granted to protected data'); } catch (err) { res.status(401).send('Unauthorized'); } }); app.listen(3000, () => { console.log('Server started on port 3000'); });
Isu:
Mitigasi:
Simpan rahsia dalam pembolehubah persekitaran atau fail konfigurasi selamat.
Kod Diperbaik:
const express = require('express'); const app = express(); // Your routes here app.listen(3000, () => { console.log('Server is running on port 3000'); });
Penjelasan:
Logik perniagaan kerentanan berlaku apabila aliran aplikasi boleh dimanipulasi dengan cara yang tidak diingini.
Operasi data tanpa had boleh membawa kepada isu prestasi atau kebocoran data.
Contoh Kod Rentan:
const express = require('express'); const app = express(); // Disable the X-Powered-By header app.disable('x-powered-by'); // Your routes here app.listen(3000, () => { console.log('Server is running on port 3000'); });
Isu:
Mitigasi:
Laksanakan penomboran dan kawalan akses.
Kod Diperbaik:
const express = require('express'); const helmet = require('helmet'); const app = express(); // Use Helmet to secure headers app.use(helmet()); // Your routes here app.listen(3000, () => { console.log('Server is running on port 3000'); });
Penjelasan:
Melindungi daripada kelemahan pihak pelanggan adalah penting untuk melindungi pengguna daripada serangan seperti Skrip Silang Tapak (XSS).
Pengendalian input pengguna yang tidak betul dalam skrip sebelah klien boleh menyebabkan serangan XSS.
Contoh Kod Rentan:
// app.js const express = require('express'); const app = express(); // Error handling middleware app.use((err, req, res, next) => { res.status(500).send(err.stack); // Sends stack trace to the client }); // Your routes here app.listen(3000);
Isu:
Mitigasi:
Gunakan perpustakaan xss untuk membersihkan input pengguna sebelum membuat persembahan.
Kod Diperbaik:
// app.js const express = require('express'); const app = express(); // Your routes here // Error handling middleware if (app.get('env') === 'production') { // Production error handler app.use((err, req, res, next) => { // Log the error internally console.error(err); res.status(500).send('An unexpected error occurred.'); }); } else { // Development error handler (with stack trace) app.use((err, req, res, next) => { res.status(500).send(`<pre class="brush:php;toolbar:false">${err.stack}`); }); } app.listen(3000);
Penjelasan:
Amalan Terbaik:
const express = require('express'); const app = express(); // Your routes here app.listen(3000, () => { console.log('Server is running on port 3000'); });
Melindungi titik akhir API adalah penting untuk mengelakkan kebocoran data dan akses tanpa kebenaran.
Membiarkan introspeksi GraphQL didayakan dalam pengeluaran mendedahkan skema API anda.
Contoh Kod Rentan:
const express = require('express'); const app = express(); // Disable the X-Powered-By header app.disable('x-powered-by'); // Your routes here app.listen(3000, () => { console.log('Server is running on port 3000'); });
Isu:
Mitigasi:
Lumpuhkan introspeksi dalam persekitaran pengeluaran.
Kod Diperbaik:
const express = require('express'); const helmet = require('helmet'); const app = express(); // Use Helmet to secure headers app.use(helmet()); // Your routes here app.listen(3000, () => { console.log('Server is running on port 3000'); });
Penjelasan:
Pertanyaan yang sangat bersarang atau rumit boleh menghabiskan sumber pelayan.
Contoh Kod Rentan:
// app.js const express = require('express'); const app = express(); // Error handling middleware app.use((err, req, res, next) => { res.status(500).send(err.stack); // Sends stack trace to the client }); // Your routes here app.listen(3000);
Isu:
Mitigasi:
Hadkan kedalaman dan kerumitan pertanyaan.
Kod Diperbaik:
// app.js const express = require('express'); const app = express(); // Your routes here // Error handling middleware if (app.get('env') === 'production') { // Production error handler app.use((err, req, res, next) => { // Log the error internally console.error(err); res.status(500).send('An unexpected error occurred.'); }); } else { // Development error handler (with stack trace) app.use((err, req, res, next) => { res.status(500).send(`<pre class="brush:php;toolbar:false">${err.stack}`); }); } app.listen(3000);
Penjelasan:
Melindungi aplikasi Node.js anda melibatkan pendekatan berbilang lapisan:
Dengan menyepadukan amalan ini, anda meningkatkan keselamatan aplikasi anda, melindungi data pengguna dan mengekalkan kepercayaan.
Nota: Panduan ini menyediakan cadangan umum. Untuk kebimbangan keselamatan khusus, rujuk profesional.
Atas ialah kandungan terperinci Melindungi Aplikasi Node.js Anda: Panduan Komprehensif. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!