•
7:50 p.m. 17 Tháng 5, 2026
Dự án bảo vệ chương trình 1
MỤC TIÊU
Thành viên cần:
- Tìm lỗi bảo mật.
- Giải thích nguyên nhân.
- Debug hệ thống.
- Vá lỗ hổng.
- Đề xuất cách phòng tránh.
NHIỆM VỤ THÀNH VIÊN
Nhiệm vụ 1 — Kiểm tra đăng nhập
Tìm các vấn đề trong hệ thống login:
- Password yếu.
- Không mã hóa password.
- Kiểm tra đăng nhập chưa an toàn.
Yêu cầu:
- Giải thích vì sao nguy hiểm.
- Đề xuất cách sửa.
Nhiệm vụ 2 — Kiểm tra quyền truy cập
Phân tích route:
JavaScript
GET /admin-data
Yêu cầu:
- Giải thích vì sao user thường vẫn xem được dữ liệu admin.
- Thêm cơ chế kiểm tra quyền.
Nhiệm vụ 3 — Tìm lỗi XSS
Kiểm tra chức năng bình luận.
Yêu cầu:
- Tìm vị trí gây XSS.
- Giải thích cách hacker có thể lợi dụng.
- Sửa code để tránh XSS.
Nhiệm vụ 4 — Phòng thủ hệ thống
Hãy đề xuất:
- Password mạnh.
- Session/token an toàn.
- Kiểm tra dữ liệu đầu vào.
- Phân quyền server.
- Cách chống spam request.
Nhiệm vụ 5 — Viết báo cáo
Báo cáo gồm:
- Lỗi tìm được.
- Mức độ nguy hiểm.
- Cách sửa.
- Đoạn code đã sửa.
- Điều học được.
LUẬT BÀI TẬP
- Chỉ chạy localhost.
- Không dùng trên website thật.
- Không thử tấn công hệ thống bên ngoài.
- Mục tiêu là học phòng thủ và bảo mật.
THANG ĐIỂM
| Nội dung | Điểm |
|---|---|
| Tìm đúng lỗi | 30 |
| Giải thích nguyên nhân | 20 |
| Vá lỗi | 30 |
| Báo cáo | 20 |
Dự án giả lập: “Bảo Vệ Hệ Thống”
Mục tiêu bài tập
Thành viên sẽ:
- Nhận biết các lỗi bảo mật cơ bản.
- Debug và vá lỗ hổng.
- Hiểu cách hoạt động của các kiểu tấn công phổ biến ở mức an toàn.
- Thực hành viết code phòng thủ.
Dự án này chỉ dùng trong môi trường học tập nội bộ, không dùng trên hệ thống thật hoặc internet công khai.
Tổng quan dự án
Tạo một web app nhỏ bằng HTML + JavaScript + Node.js.
Ứng dụng có chủ đích chứa:
- Lỗi đăng nhập yếu.
- XSS cơ bản.
- SQL Injection giả lập.
- Logic bug.
- Kiểm tra quyền sai.
Nhiệm vụ thành viên:
- Tìm lỗi.
- Giải thích lỗi.
- Vá lỗi.
- Viết báo cáo ngắn.
Cấu trúc dự án
bao-ve-he-thong/
│
├── server.js
├── package.json
├── database.json
├── public/
│ ├── index.html
│ ├── login.html
│ ├── dashboard.html
│ └── app.js
│
└── README.md
1. Khởi tạo project
Cài đặt
Bash
npm init -y
npm install express body-parser
2. File server.js
JavaScript
const express = require('express');
const bodyParser = require('body-parser');
const fs = require('fs');
const path = require('path');
const app = express();
app.use(bodyParser.json());
app.use(express.static('public'));
const users = [
{
username: 'admin',
password: '123456',
role: 'admin'
},
{
username: 'student',
password: 'abc123',
role: 'user'
}
];
// Đăng nhập có chủ đích yếu
app.post('/login', (req, res) => {
const { username, password } = req.body;
const user = users.find(
u => u.username == username && u.password == password
);
if(user){
res.json({
success: true,
role: user.role
});
} else {
res.json({
success: false
});
}
});
// Route admin không kiểm tra token
app.get('/admin-data', (req, res) => {
res.json({
secret: 'TOP_SECRET_DATA'
});
});
// API chứa XSS
app.post('/comment', (req, res) => {
const { text } = req.body;
res.json({
saved: true,
text
});
});
app.listen(3000, () => {
console.log('Server running at http://localhost:3000');
});
3. login.html
HTML
<!DOCTYPE html>
<html>
<head>
<title>Login</title>
</head>
<body>
<h1>Đăng nhập</h1>
<input id="username" placeholder="Username">
<input id="password" type="password" placeholder="Password">
<button onclick="login()">Login</button>
<script>
async function login(){
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
const res = await fetch('/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ username, password })
});
const data = await res.json();
if(data.success){
localStorage.setItem('role', data.role);
window.location.href = '/dashboard.html';
} else {
alert('Sai tài khoản');
}
}
</script>
</body>
</html>
4. dashboard.html
HTML
<!DOCTYPE html>
<html>
<head>
<title>Dashboard</title>
</head>
<body>
<h1>Dashboard</h1>
<button onclick="getAdminData()">
Lấy dữ liệu admin
</button>
<hr>
<h2>Bình luận</h2>
<input id="comment">
<button onclick="sendComment()">Gửi</button>
<div id="comments"></div>
<script>
async function getAdminData(){
const res = await fetch('/admin-data');
const data = await res.json();
alert(data.secret);
}
async function sendComment(){
const text = document.getElementById('comment').value;
const res = await fetch('/comment', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ text })
});
const data = await res.json();
// XSS intentional
document.getElementById('comments').innerHTML += `
<p>${data.text}</p>
`;
}
</script>
</body>
</html>
Nhiệm vụ thành viên
Mức 1 — Tìm lỗi
Thành viên phải xác định:
- Vì sao password yếu.
- Vì sao dùng localStorage nguy hiểm.
- Vì sao innerHTML gây XSS.
- Vì sao route admin bị lộ.
Mức 2 — Vá lỗi
Yêu cầu thành viên:
Vá XSS
Gợi ý:
JavaScript
const p = document.createElement('p');
p.innerText = data.text;
document.getElementById('comments').appendChild(p);
Vá route admin
Yêu cầu:
- Kiểm tra role.
- Không cho user thường truy cập.
Ví dụ:
JavaScript
app.get('/admin-data', (req, res) => {
const role = req.headers.role;
if(role !== 'admin'){
return res.status(403).json({
error: 'Forbidden'
});
}
res.json({
secret: 'TOP_SECRET_DATA'
});
});
Vá password
Yêu cầu:
- Đổi password mạnh.
- Giải thích hash password.
Câu hỏi thảo luận
- Vì sao không nên tin dữ liệu từ client?
- XSS có thể gây hậu quả gì?
- Nếu website thật bị lỗi này sẽ nguy hiểm thế nào?
- Vì sao cần kiểm tra quyền ở server?
- Điều gì xảy ra nếu hacker lấy được token?
...Xem thêm