This commit is contained in:
m0rph3us1987
2026-02-05 23:08:53 +01:00
parent a1e32fa8d3
commit b0206e58e0

View File

@@ -40,6 +40,13 @@ const dbAll = (sql, params = []) => new Promise((resolve, reject) => {
});
});
const dbGet = (sql, params = []) => new Promise((resolve, reject) => {
db.get(sql, params, (err, row) => {
if (err) reject(err);
else resolve(row);
});
});
// Setup Storage
const uploadDir = path.join(__dirname, 'uploads');
if (!fs.existsSync(uploadDir)) fs.mkdirSync(uploadDir);
@@ -172,8 +179,23 @@ apiRouter.post('/auth/login', (req, res) => {
});
});
apiRouter.get('/state', (req, res) => {
apiRouter.get('/state', async (req, res) => {
const state = { isStarted: false, teams: [], challenges: [], solves: [], blogs: [], config: {} };
// Security Check: Identify requester and admin status
const authHeader = req.headers.authorization;
const teamId = authHeader ? authHeader.replace('Bearer mock-token-', '') : null;
let isAdmin = false;
if (teamId) {
try {
const team = await dbGet("SELECT isAdmin FROM teams WHERE id = ?", [teamId]);
isAdmin = team && team.isAdmin === 1;
} catch (err) {
console.error("Auth verify failed in state API:", err);
}
}
db.all("SELECT key, value FROM config", (err, configRows) => {
if (err) return res.status(500).json({ error: 'Failed to fetch config' });
configRows.forEach(row => { state.config[row.key] = row.value; });
@@ -189,11 +211,18 @@ apiRouter.get('/state', (req, res) => {
if (err) return res.status(500).json({ error: 'Failed to fetch blogs' });
state.solves = solves || [];
state.blogs = blogs || [];
state.challenges = (challenges || []).map(c => ({
...c,
files: JSON.parse(c.files || '[]'),
solves: state.solves.filter(s => s.challengeId === c.id).map(s => s.teamId)
}));
state.challenges = (challenges || []).map(c => {
const enriched = {
...c,
files: JSON.parse(c.files || '[]'),
solves: state.solves.filter(s => s.challengeId === c.id).map(s => s.teamId)
};
// CRITICAL SECURITY FIX: Hide flag if not admin
if (!isAdmin) {
delete enriched.flag;
}
return enriched;
});
res.json(state);
});
});
@@ -392,3 +421,4 @@ if (fs.existsSync(distPath)) {
app.get('*', (req, res) => { if (!req.path.startsWith('/api') && !req.path.startsWith('/files')) res.sendFile(path.join(distPath, 'index.html')); else res.status(404).json({ error: 'Not found' }); });
}
app.listen(port, '0.0.0.0', () => console.log(`CTF Backend running on port ${port}`));