feat: add event slugs to prevent ID enumeration attacks

Replace sequential event IDs in URLs with unique alphanumeric slugs to prevent enumeration attacks. Event URLs now use format /events/{slug}/chat instead of /events/{id}/chat.

Backend changes:
- Add slug field (VARCHAR 50, unique) to Event model
- Create migration with auto-generated 12-char MD5-based slugs for existing events
- Update GET /api/events/:slug endpoint (changed from :id)
- Update GET /api/events/:slug/messages endpoint (changed from :eventId)
- Modify Socket.IO join_event_room to accept slug parameter
- Update send_event_message to use stored event context instead of passing eventId

Frontend changes:
- Update eventsAPI.getBySlug() method (changed from getById)
- Update eventsAPI.getMessages() to use slug parameter
- Change route from /events/:eventId/chat to /events/:slug/chat
- Update EventsPage to navigate using event.slug
- Update EventChatPage to fetch event data via slug and use slug in socket events

Security impact: Prevents attackers from discovering all events by iterating sequential IDs.
This commit is contained in:
Radosław Gierwiało
2025-11-13 21:43:58 +01:00
parent 20f405cab3
commit b2c2527c46
8 changed files with 127 additions and 37 deletions

View File

@@ -27,8 +27,8 @@ const EventsPage = () => {
fetchEvents();
}, []);
const handleJoinEvent = (eventId) => {
navigate(`/events/${eventId}/chat`);
const handleJoinEvent = (slug) => {
navigate(`/events/${slug}/chat`);
};
if (loading) {
@@ -102,7 +102,7 @@ const EventsPage = () => {
)}
<button
onClick={() => handleJoinEvent(event.id)}
onClick={() => handleJoinEvent(event.slug)}
className="w-full px-4 py-2 bg-primary-600 text-white rounded-md hover:bg-primary-700 transition-colors"
>
{event.isJoined ? 'Open chat' : 'Join chat'}