diff --git a/openapi.yaml b/openapi.yaml deleted file mode 100644 index 8348b4e..0000000 --- a/openapi.yaml +++ /dev/null @@ -1,2080 +0,0 @@ -openapi: 3.0.0 -info: - title: ProjectHub API - description: | - ProjectHub is a project management web application API. - - **⚠️ WARNING: This API is intentionally designed with security vulnerabilities for educational and security testing purposes only. DO NOT use in production environments.** - - This API demonstrates common security vulnerabilities including: - - SQL Injection - - Broken Authentication - - Sensitive Data Exposure - - Broken Access Control (IDOR) - - XSS vulnerabilities - - Insecure file uploads - version: 1.0.0 - contact: - name: ProjectHub Security Demo - email: security-demo@projecthub.com - -servers: - - url: http://172.35.1.192 - description: Production server - - url: http://localhost:5000/api - description: Local development server - -tags: - - name: Authentication - description: User authentication and authorization endpoints - - name: Projects - description: Project management endpoints - - name: Tasks - description: Task management endpoints - - name: Documents - description: Document upload and management endpoints - - name: Messages - description: Messaging and communication endpoints - - name: Analytics - description: Analytics and reporting endpoints - -paths: - /auth/register: - post: - tags: - - Authentication - summary: Register a new user - description: Create a new user account. No rate limiting or CAPTCHA protection. - operationId: register - requestBody: - required: true - content: - application/json: - schema: - type: object - required: - - username - - email - - password - properties: - username: - type: string - example: johndoe - email: - type: string - format: email - example: john@example.com - password: - type: string - format: password - example: password123 - responses: - '201': - description: User registered successfully - content: - application/json: - schema: - type: object - properties: - message: - type: string - token: - type: string - user: - $ref: '#/components/schemas/User' - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /auth/login: - post: - tags: - - Authentication - summary: User login - description: Authenticate user and receive JWT token. No rate limiting or MFA. - operationId: login - requestBody: - required: true - content: - application/json: - schema: - type: object - required: - - username - - password - properties: - username: - type: string - example: johndoe - password: - type: string - format: password - example: password123 - responses: - '200': - description: Login successful - content: - application/json: - schema: - type: object - properties: - message: - type: string - token: - type: string - user: - $ref: '#/components/schemas/User' - '401': - description: Invalid credentials - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /auth/logout: - post: - tags: - - Authentication - summary: User logout - description: Logout current user. Note: Tokens are stateless and never expire. - operationId: logout - security: - - bearerAuth: [] - responses: - '200': - description: Logged out successfully - content: - application/json: - schema: - type: object - properties: - message: - type: string - - /auth/me: - get: - tags: - - Authentication - summary: Get current user information - description: Retrieve information about the currently authenticated user. - operationId: getCurrentUser - security: - - bearerAuth: [] - responses: - '200': - description: User information - content: - application/json: - schema: - type: object - properties: - user: - $ref: '#/components/schemas/User' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /auth/reset-password: - post: - tags: - - Authentication - summary: Reset user password - description: Reset password for a user. Vulnerable to broken authentication - no token validation or email verification. - operationId: resetPassword - requestBody: - required: true - content: - application/json: - schema: - type: object - required: - - email - - new_password - properties: - email: - type: string - format: email - example: john@example.com - new_password: - type: string - format: password - example: newpassword123 - responses: - '200': - description: Password reset successfully - content: - application/json: - schema: - type: object - properties: - message: - type: string - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '404': - description: User not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /projects: - get: - tags: - - Projects - summary: List all projects - description: Get a list of all projects. Vulnerable to SQL injection in search parameter. - operationId: listProjects - security: - - bearerAuth: [] - parameters: - - name: search - in: query - description: Search term for project name or description (vulnerable to SQL injection) - schema: - type: string - - name: status - in: query - description: Filter by status - schema: - type: string - responses: - '200': - description: List of projects - content: - application/json: - schema: - type: object - properties: - projects: - type: array - items: - $ref: '#/components/schemas/Project' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - post: - tags: - - Projects - summary: Create a new project - description: Create a new project. No input validation or sanitization. - operationId: createProject - security: - - bearerAuth: [] - requestBody: - required: true - content: - application/json: - schema: - type: object - required: - - name - properties: - name: - type: string - example: My New Project - description: - type: string - example: Project description - is_public: - type: boolean - default: false - responses: - '201': - description: Project created successfully - content: - application/json: - schema: - type: object - properties: - message: - type: string - project: - $ref: '#/components/schemas/Project' - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /projects/{projectId}: - get: - tags: - - Projects - summary: Get project by ID - description: Retrieve a specific project. Vulnerable to IDOR. - operationId: getProject - security: - - bearerAuth: [] - parameters: - - name: projectId - in: path - required: true - schema: - type: integer - responses: - '200': - description: Project details - content: - application/json: - schema: - type: object - properties: - project: - $ref: '#/components/schemas/Project' - '404': - description: Project not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - put: - tags: - - Projects - summary: Update project - description: Update project details. Vulnerable to broken access control. - operationId: updateProject - security: - - bearerAuth: [] - parameters: - - name: projectId - in: path - required: true - schema: - type: integer - requestBody: - content: - application/json: - schema: - type: object - properties: - name: - type: string - description: - type: string - is_public: - type: boolean - responses: - '200': - description: Project updated successfully - content: - application/json: - schema: - type: object - properties: - message: - type: string - project: - $ref: '#/components/schemas/Project' - '404': - description: Project not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - delete: - tags: - - Projects - summary: Delete project - description: Delete a project. Vulnerable to broken access control. - operationId: deleteProject - security: - - bearerAuth: [] - parameters: - - name: projectId - in: path - required: true - schema: - type: integer - responses: - '200': - description: Project deleted successfully - content: - application/json: - schema: - type: object - properties: - message: - type: string - '404': - description: Project not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /projects/{projectId}/dashboard: - get: - tags: - - Projects - summary: Get project dashboard - description: Get project dashboard with tasks and documents. Vulnerable to IDOR. - operationId: getProjectDashboard - security: - - bearerAuth: [] - parameters: - - name: projectId - in: path - required: true - schema: - type: integer - responses: - '200': - description: Project dashboard data - content: - application/json: - schema: - type: object - properties: - project: - $ref: '#/components/schemas/Project' - tasks: - type: array - items: - $ref: '#/components/schemas/Task' - documents: - type: array - items: - $ref: '#/components/schemas/Document' - stats: - type: object - properties: - total_tasks: - type: integer - total_documents: - type: integer - '404': - description: Project not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /projects/{projectId}/tasks: - get: - tags: - - Projects - summary: Get project tasks - description: Get all tasks for a project. Vulnerable to SQL injection in search parameter. - operationId: getProjectTasks - security: - - bearerAuth: [] - parameters: - - name: projectId - in: path - required: true - schema: - type: integer - - name: search - in: query - description: Search term (vulnerable to SQL injection) - schema: - type: string - - name: status - in: query - schema: - type: string - enum: [pending, in_progress, completed] - responses: - '200': - description: List of tasks - content: - application/json: - schema: - type: object - properties: - tasks: - type: array - items: - $ref: '#/components/schemas/Task' - '404': - description: Project not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /tasks: - get: - tags: - - Tasks - summary: List all tasks - description: Get a list of tasks. Vulnerable to SQL injection and broken access control. - operationId: listTasks - security: - - bearerAuth: [] - parameters: - - name: project_id - in: query - schema: - type: integer - - name: status - in: query - schema: - type: string - enum: [pending, in_progress, completed] - - name: search - in: query - description: Search term (vulnerable to SQL injection) - schema: - type: string - - name: assigned_to - in: query - schema: - type: integer - responses: - '200': - description: List of tasks - content: - application/json: - schema: - type: object - properties: - tasks: - type: array - items: - $ref: '#/components/schemas/Task' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - post: - tags: - - Tasks - summary: Create a new task - description: Create a new task. No input validation or sanitization. - operationId: createTask - security: - - bearerAuth: [] - requestBody: - required: true - content: - application/json: - schema: - type: object - required: - - title - - project_id - properties: - title: - type: string - example: Complete project documentation - description: - type: string - example: Task description - project_id: - type: integer - assigned_to: - type: integer - priority: - type: string - enum: [low, medium, high] - default: medium - due_date: - type: string - format: date-time - responses: - '201': - description: Task created successfully - content: - application/json: - schema: - type: object - properties: - message: - type: string - task: - $ref: '#/components/schemas/Task' - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /tasks/{taskId}: - get: - tags: - - Tasks - summary: Get task by ID - description: Retrieve a specific task. Vulnerable to IDOR. - operationId: getTask - security: - - bearerAuth: [] - parameters: - - name: taskId - in: path - required: true - schema: - type: integer - responses: - '200': - description: Task details - content: - application/json: - schema: - type: object - properties: - task: - $ref: '#/components/schemas/Task' - '404': - description: Task not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - put: - tags: - - Tasks - summary: Update task - description: Update task details. Vulnerable to broken access control. - operationId: updateTask - security: - - bearerAuth: [] - parameters: - - name: taskId - in: path - required: true - schema: - type: integer - requestBody: - content: - application/json: - schema: - type: object - properties: - title: - type: string - description: - type: string - status: - type: string - enum: [pending, in_progress, completed] - assigned_to: - type: integer - priority: - type: string - enum: [low, medium, high] - due_date: - type: string - format: date-time - responses: - '200': - description: Task updated successfully - content: - application/json: - schema: - type: object - properties: - message: - type: string - task: - $ref: '#/components/schemas/Task' - '404': - description: Task not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - delete: - tags: - - Tasks - summary: Delete task - description: Delete a task. Vulnerable to broken access control. - operationId: deleteTask - security: - - bearerAuth: [] - parameters: - - name: taskId - in: path - required: true - schema: - type: integer - responses: - '200': - description: Task deleted successfully - content: - application/json: - schema: - type: object - properties: - message: - type: string - '404': - description: Task not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /tasks/{taskId}/comments: - get: - tags: - - Tasks - summary: Get task comments - description: Get all comments for a task. Vulnerable to IDOR and XSS. - operationId: getTaskComments - security: - - bearerAuth: [] - parameters: - - name: taskId - in: path - required: true - schema: - type: integer - responses: - '200': - description: List of comments - content: - application/json: - schema: - type: object - properties: - comments: - type: array - items: - $ref: '#/components/schemas/Comment' - '404': - description: Task not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - post: - tags: - - Tasks - summary: Create task comment - description: Add a comment to a task. Vulnerable to XSS and IDOR. - operationId: createTaskComment - security: - - bearerAuth: [] - parameters: - - name: taskId - in: path - required: true - schema: - type: integer - requestBody: - required: true - content: - application/json: - schema: - type: object - required: - - content - properties: - content: - type: string - example: This is a comment - responses: - '201': - description: Comment created successfully - content: - application/json: - schema: - type: object - properties: - message: - type: string - comment: - $ref: '#/components/schemas/Comment' - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /documents: - get: - tags: - - Documents - summary: List all documents - description: Get a list of documents. Vulnerable to IDOR and broken access control. - operationId: listDocuments - security: - - bearerAuth: [] - parameters: - - name: project_id - in: query - schema: - type: integer - responses: - '200': - description: List of documents - content: - application/json: - schema: - type: object - properties: - documents: - type: array - items: - $ref: '#/components/schemas/Document' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - post: - tags: - - Documents - summary: Upload document - description: Upload a document. Vulnerable to XXE, insecure file upload, and no validation. - operationId: uploadDocument - security: - - bearerAuth: [] - requestBody: - required: true - content: - multipart/form-data: - schema: - type: object - required: - - file - properties: - file: - type: string - format: binary - project_id: - type: integer - is_public: - type: boolean - default: false - responses: - '201': - description: Document uploaded successfully - content: - application/json: - schema: - type: object - properties: - message: - type: string - document: - $ref: '#/components/schemas/Document' - metadata: - type: object - description: File metadata extracted from the document - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /documents/{documentId}: - get: - tags: - - Documents - summary: Get document by ID - description: Retrieve document information. Vulnerable to IDOR. - operationId: getDocument - security: - - bearerAuth: [] - parameters: - - name: documentId - in: path - required: true - schema: - type: integer - responses: - '200': - description: Document details - content: - application/json: - schema: - type: object - properties: - document: - $ref: '#/components/schemas/Document' - '404': - description: Document not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - delete: - tags: - - Documents - summary: Delete document - description: Delete a document. Vulnerable to broken access control. - operationId: deleteDocument - security: - - bearerAuth: [] - parameters: - - name: documentId - in: path - required: true - schema: - type: integer - responses: - '200': - description: Document deleted successfully - content: - application/json: - schema: - type: object - properties: - message: - type: string - '404': - description: Document not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /documents/{documentId}/download: - get: - tags: - - Documents - summary: Download document - description: Download a document file. Vulnerable to path traversal and IDOR. - operationId: downloadDocument - security: - - bearerAuth: [] - parameters: - - name: documentId - in: path - required: true - schema: - type: integer - responses: - '200': - description: Document file - content: - application/octet-stream: - schema: - type: string - format: binary - '404': - description: Document not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /documents/{documentId}/metadata: - get: - tags: - - Documents - summary: Get document metadata - description: Retrieve document metadata information. Vulnerable to IDOR. - operationId: getDocumentMetadata - security: - - bearerAuth: [] - parameters: - - name: documentId - in: path - required: true - schema: - type: integer - responses: - '200': - description: Document metadata - content: - application/json: - schema: - type: object - properties: - document: - $ref: '#/components/schemas/Document' - metadata: - type: object - description: File metadata extracted from the document - '404': - description: Document not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /messages: - get: - tags: - - Messages - summary: List messages - description: Get a list of messages. Vulnerable to IDOR and broken access control. Supports pagination. - operationId: listMessages - security: - - bearerAuth: [] - parameters: - - name: sender_id - in: query - schema: - type: integer - - name: receiver_id - in: query - schema: - type: integer - - name: page - in: query - description: Page number for pagination - schema: - type: integer - default: 1 - - name: per_page - in: query - description: Number of items per page - schema: - type: integer - default: 10 - responses: - '200': - description: List of messages - content: - application/json: - schema: - type: object - properties: - messages: - type: array - items: - $ref: '#/components/schemas/Message' - pagination: - type: object - properties: - page: - type: integer - per_page: - type: integer - total: - type: integer - pages: - type: integer - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - post: - tags: - - Messages - summary: Send message - description: Send a message to another user. Vulnerable to XSS and no input validation. - operationId: sendMessage - security: - - bearerAuth: [] - requestBody: - required: true - content: - application/json: - schema: - type: object - required: - - receiver_id - - content - properties: - receiver_id: - type: integer - subject: - type: string - example: Message subject - content: - type: string - example: Message content - responses: - '201': - description: Message sent successfully - content: - application/json: - schema: - type: object - properties: - message: - type: string - message_data: - $ref: '#/components/schemas/Message' - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /messages/{messageId}: - get: - tags: - - Messages - summary: Get message by ID - description: Retrieve a specific message. Vulnerable to IDOR and XSS. - operationId: getMessage - security: - - bearerAuth: [] - parameters: - - name: messageId - in: path - required: true - schema: - type: integer - responses: - '200': - description: Message details - content: - application/json: - schema: - type: object - properties: - message: - $ref: '#/components/schemas/Message' - '404': - description: Message not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - delete: - tags: - - Messages - summary: Delete message - description: Delete a message. Vulnerable to broken access control. - operationId: deleteMessage - security: - - bearerAuth: [] - parameters: - - name: messageId - in: path - required: true - schema: - type: integer - responses: - '200': - description: Message deleted successfully - content: - application/json: - schema: - type: object - properties: - message: - type: string - '404': - description: Message not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /messages/search: - get: - tags: - - Messages - summary: Search messages - description: Search messages by content or subject. Vulnerable to SQL injection. - operationId: searchMessages - security: - - bearerAuth: [] - parameters: - - name: q - in: query - required: true - description: Search query (vulnerable to SQL injection) - schema: - type: string - responses: - '200': - description: Search results - content: - application/json: - schema: - type: object - properties: - query: - type: string - results: - type: array - items: - $ref: '#/components/schemas/Message' - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /v1/projects: - get: - tags: - - Projects - summary: List all projects (v1 API) - description: Get a list of all projects. No authentication required. Vulnerable to SQL injection. - operationId: listProjectsV1 - parameters: - - name: search - in: query - description: Search term (vulnerable to SQL injection) - schema: - type: string - - name: status - in: query - schema: - type: string - responses: - '200': - description: List of projects - content: - application/json: - schema: - type: object - properties: - projects: - type: array - items: - $ref: '#/components/schemas/Project' - - /v1/projects/{projectId}: - get: - tags: - - Projects - summary: Get project by ID (v1 API) - description: Retrieve a specific project. No authentication required. Vulnerable to IDOR. - operationId: getProjectV1 - parameters: - - name: projectId - in: path - required: true - schema: - type: integer - responses: - '200': - description: Project details - content: - application/json: - schema: - type: object - properties: - project: - $ref: '#/components/schemas/Project' - '404': - description: Project not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /v1/projects/{projectId}/tasks: - get: - tags: - - Tasks - summary: Get project tasks (v1 API) - description: Get tasks for a project. No authentication required. Vulnerable to SQL injection and IDOR. - operationId: getProjectTasksV1 - parameters: - - name: projectId - in: path - required: true - schema: - type: integer - - name: search - in: query - description: Search term (vulnerable to SQL injection) - schema: - type: string - - name: status - in: query - schema: - type: string - responses: - '200': - description: List of tasks - content: - application/json: - schema: - type: object - properties: - tasks: - type: array - items: - $ref: '#/components/schemas/Task' - - /v1/tasks: - get: - tags: - - Tasks - summary: List all tasks (v1 API) - description: Get a list of tasks. No authentication required. Vulnerable to SQL injection. - operationId: listTasksV1 - parameters: - - name: search - in: query - description: Search term (vulnerable to SQL injection) - schema: - type: string - - name: project_id - in: query - schema: - type: integer - - name: assigned_to - in: query - schema: - type: integer - responses: - '200': - description: List of tasks - content: - application/json: - schema: - type: object - properties: - tasks: - type: array - items: - $ref: '#/components/schemas/Task' - - /v1/tasks/{taskId}: - get: - tags: - - Tasks - summary: Get task by ID (v1 API) - description: Retrieve a specific task. No authentication required. Vulnerable to IDOR. - operationId: getTaskV1 - parameters: - - name: taskId - in: path - required: true - schema: - type: integer - responses: - '200': - description: Task details - content: - application/json: - schema: - type: object - properties: - task: - $ref: '#/components/schemas/Task' - '404': - description: Task not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /v1/tasks/{taskId}/comments: - get: - tags: - - Tasks - summary: Get task comments (v1 API) - description: Get all comments for a task. No authentication required. Vulnerable to IDOR and XSS. - operationId: getTaskCommentsV1 - parameters: - - name: taskId - in: path - required: true - schema: - type: integer - responses: - '200': - description: List of comments - content: - application/json: - schema: - type: object - properties: - comments: - type: array - items: - $ref: '#/components/schemas/Comment' - - /v1/documents: - get: - tags: - - Documents - summary: List all documents (v1 API) - description: Get a list of documents. No authentication required. Vulnerable to IDOR. - operationId: listDocumentsV1 - parameters: - - name: project_id - in: query - schema: - type: integer - responses: - '200': - description: List of documents - content: - application/json: - schema: - type: object - properties: - documents: - type: array - items: - $ref: '#/components/schemas/Document' - - /v1/documents/{documentId}: - get: - tags: - - Documents - summary: Get document by ID (v1 API) - description: Retrieve document information. No authentication required. Vulnerable to IDOR. - operationId: getDocumentV1 - parameters: - - name: documentId - in: path - required: true - schema: - type: integer - responses: - '200': - description: Document details - content: - application/json: - schema: - type: object - properties: - document: - $ref: '#/components/schemas/Document' - '404': - description: Document not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /v1/messages: - get: - tags: - - Messages - summary: List all messages (v1 API) - description: Get a list of messages. No authentication required. Vulnerable to IDOR and XSS. - operationId: listMessagesV1 - parameters: - - name: sender_id - in: query - schema: - type: integer - - name: receiver_id - in: query - schema: - type: integer - responses: - '200': - description: List of messages - content: - application/json: - schema: - type: object - properties: - messages: - type: array - items: - $ref: '#/components/schemas/Message' - - /v1/messages/{messageId}: - get: - tags: - - Messages - summary: Get message by ID (v1 API) - description: Retrieve a specific message. No authentication required. Vulnerable to IDOR and XSS. - operationId: getMessageV1 - parameters: - - name: messageId - in: path - required: true - schema: - type: integer - responses: - '200': - description: Message details - content: - application/json: - schema: - type: object - properties: - message: - $ref: '#/components/schemas/Message' - '404': - description: Message not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /analytics/stats: - get: - tags: - - Analytics - summary: Get application statistics - description: Get application-wide statistics. Requires authentication. - operationId: getAnalyticsStats - security: - - bearerAuth: [] - responses: - '200': - description: Application statistics - content: - application/json: - schema: - type: object - properties: - user_count: - type: integer - project_count: - type: integer - task_count: - type: integer - document_count: - type: integer - message_count: - type: integer - comment_count: - type: integer - current_time: - type: string - format: date-time - timestamp: - type: number - request_id: - type: string - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /analytics/search: - get: - tags: - - Analytics - summary: Search across users and projects - description: Search across users and projects. Requires authentication. - operationId: analyticsSearch - security: - - bearerAuth: [] - parameters: - - name: q - in: query - required: true - description: Search query - schema: - type: string - responses: - '200': - description: Search results - content: - application/json: - schema: - type: object - properties: - query: - type: string - users: - type: array - items: - $ref: '#/components/schemas/User' - projects: - type: array - items: - $ref: '#/components/schemas/Project' - search_time: - type: string - format: date-time - request_id: - type: string - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /analytics/user/{userId}: - get: - tags: - - Analytics - summary: Get user analytics - description: Get user details and analytics. Requires authentication. Vulnerable to IDOR. - operationId: getUserAnalytics - security: - - bearerAuth: [] - parameters: - - name: userId - in: path - required: true - schema: - type: integer - responses: - '200': - description: User analytics - content: - application/json: - schema: - type: object - properties: - user: - $ref: '#/components/schemas/User' - fetched_at: - type: string - format: date-time - request_id: - type: string - '404': - description: User not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - '401': - description: Unauthorized - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /v1/users: - get: - tags: - - Projects - summary: List all users (v1 API) - description: Get a list of all users. No authentication required. Vulnerable to SQL injection in search parameter. - operationId: listUsersV1 - parameters: - - name: search - in: query - description: Search term (vulnerable to SQL injection) - schema: - type: string - responses: - '200': - description: List of users - content: - application/json: - schema: - type: object - properties: - users: - type: array - items: - $ref: '#/components/schemas/User' - request_id: - type: string - count: - type: integer - - post: - tags: - - Projects - summary: Create user (v1 API) - description: Create a new user. Requires authentication. Vulnerable to broken access control. - operationId: createUserV1 - security: - - bearerAuth: [] - requestBody: - required: true - content: - application/json: - schema: - type: object - required: - - username - - email - - password - properties: - username: - type: string - email: - type: string - format: email - password: - type: string - format: password - role: - type: string - enum: [admin, project_manager, team_member] - default: team_member - responses: - '201': - description: User created successfully - content: - application/json: - schema: - type: object - properties: - message: - type: string - user: - $ref: '#/components/schemas/User' - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /v1/users/{userId}: - get: - tags: - - Projects - summary: Get user by ID (v1 API) - description: Retrieve a specific user. No authentication required. Vulnerable to IDOR. - operationId: getUserV1 - parameters: - - name: userId - in: path - required: true - schema: - type: integer - responses: - '200': - description: User details - content: - application/json: - schema: - type: object - properties: - user: - $ref: '#/components/schemas/User' - '404': - description: User not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - put: - tags: - - Projects - summary: Update user (v1 API) - description: Update user details. Requires authentication. Vulnerable to broken access control. - operationId: updateUserV1 - security: - - bearerAuth: [] - parameters: - - name: userId - in: path - required: true - schema: - type: integer - requestBody: - content: - application/json: - schema: - type: object - properties: - username: - type: string - email: - type: string - format: email - password: - type: string - format: password - role: - type: string - enum: [admin, project_manager, team_member] - responses: - '200': - description: User updated successfully - content: - application/json: - schema: - type: object - properties: - message: - type: string - user: - $ref: '#/components/schemas/User' - '404': - description: User not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - delete: - tags: - - Projects - summary: Delete user (v1 API) - description: Delete a user. Requires authentication. Vulnerable to broken access control. - operationId: deleteUserV1 - security: - - bearerAuth: [] - parameters: - - name: userId - in: path - required: true - schema: - type: integer - responses: - '200': - description: User deleted successfully - content: - application/json: - schema: - type: object - properties: - message: - type: string - '404': - description: User not found - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - - /v1/stats: - get: - tags: - - Projects - summary: Get statistics (v1 API) - description: Get application statistics. No authentication required. - operationId: getStatsV1 - responses: - '200': - description: Application statistics - content: - application/json: - schema: - type: object - properties: - total_users: - type: integer - total_projects: - type: integer - total_tasks: - type: integer - total_documents: - type: integer - total_messages: - type: integer - generated_at: - type: string - format: date-time - request_id: - type: string - - /v1/search: - get: - tags: - - Projects - summary: Global search (v1 API) - description: Global search across users, projects, and tasks. No authentication required. Vulnerable to SQL injection. - operationId: globalSearchV1 - parameters: - - name: q - in: query - required: true - description: Search query (vulnerable to SQL injection) - schema: - type: string - responses: - '200': - description: Search results - content: - application/json: - schema: - type: object - properties: - query: - type: string - users: - type: array - items: - $ref: '#/components/schemas/User' - projects: - type: array - items: - $ref: '#/components/schemas/Project' - tasks: - type: array - items: - $ref: '#/components/schemas/Task' - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - -components: - securitySchemes: - bearerAuth: - type: http - scheme: bearer - bearerFormat: JWT - description: JWT token authentication. Tokens never expire. - - schemas: - User: - type: object - properties: - id: - type: integer - username: - type: string - email: - type: string - format: email - password_hash: - type: string - description: Should not be exposed in production - role: - type: string - enum: [admin, project_manager, team_member] - api_key: - type: string - description: Should not be exposed in production - created_at: - type: string - format: date-time - last_login: - type: string - format: date-time - - Project: - type: object - properties: - id: - type: integer - name: - type: string - description: - type: string - owner_id: - type: integer - is_public: - type: boolean - created_at: - type: string - format: date-time - updated_at: - type: string - format: date-time - - Task: - type: object - properties: - id: - type: integer - title: - type: string - description: - type: string - project_id: - type: integer - assigned_to: - type: integer - nullable: true - created_by: - type: integer - status: - type: string - enum: [pending, in_progress, completed] - priority: - type: string - enum: [low, medium, high] - due_date: - type: string - format: date-time - nullable: true - created_at: - type: string - format: date-time - updated_at: - type: string - format: date-time - - Comment: - type: object - properties: - id: - type: integer - task_id: - type: integer - user_id: - type: integer - content: - type: string - created_at: - type: string - format: date-time - - Document: - type: object - properties: - id: - type: integer - filename: - type: string - original_filename: - type: string - file_size: - type: integer - file_type: - type: string - project_id: - type: integer - nullable: true - uploaded_by: - type: integer - is_public: - type: boolean - created_at: - type: string - format: date-time - - Message: - type: object - properties: - id: - type: integer - sender_id: - type: integer - receiver_id: - type: integer - subject: - type: string - nullable: true - content: - type: string - is_read: - type: boolean - created_at: - type: string - format: date-time - - Error: - type: object - properties: - error: - type: string - required: - - error - diff --git a/swagger.yaml b/swagger.yaml index 5d6a929..8348b4e 100644 --- a/swagger.yaml +++ b/swagger.yaml @@ -1,32 +1,101 @@ openapi: 3.0.0 info: - title: Bank of Checkmarx API + title: ProjectHub API description: | - API for the Bank of Checkmarx demo application + ProjectHub is a project management web application API. - ## Authentication - This API uses JWT Bearer token authentication. To authenticate: - 1. Use the `/api/v1/login` endpoint with your username and password - 2. Include the returned token in the Authorization header as `Bearer ` + **⚠️ WARNING: This API is intentionally designed with security vulnerabilities for educational and security testing purposes only. DO NOT use in production environments.** - ## Security Notice - This is a demo application with intentionally vulnerable endpoints for security testing purposes. + This API demonstrates common security vulnerabilities including: + - SQL Injection + - Broken Authentication + - Sensitive Data Exposure + - Broken Access Control (IDOR) + - XSS vulnerabilities + - Insecure file uploads version: 1.0.0 contact: - name: Bank of Checkmarx - email: support@bankofcheckmarx.com + name: ProjectHub Security Demo + email: security-demo@projecthub.com servers: - - url: http://172.35.1.192:8000 + - url: http://172.35.1.192 description: Production server + - url: http://localhost:5000/api + description: Local development server + +tags: + - name: Authentication + description: User authentication and authorization endpoints + - name: Projects + description: Project management endpoints + - name: Tasks + description: Task management endpoints + - name: Documents + description: Document upload and management endpoints + - name: Messages + description: Messaging and communication endpoints + - name: Analytics + description: Analytics and reporting endpoints paths: - /api/v1/login: + /auth/register: + post: + tags: + - Authentication + summary: Register a new user + description: Create a new user account. No rate limiting or CAPTCHA protection. + operationId: register + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - username + - email + - password + properties: + username: + type: string + example: johndoe + email: + type: string + format: email + example: john@example.com + password: + type: string + format: password + example: password123 + responses: + '201': + description: User registered successfully + content: + application/json: + schema: + type: object + properties: + message: + type: string + token: + type: string + user: + $ref: '#/components/schemas/User' + '400': + description: Bad request + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /auth/login: post: - summary: User login - description: Authenticate user and return JWT token tags: - Authentication + summary: User login + description: Authenticate user and receive JWT token. No rate limiting or MFA. + operationId: login requestBody: required: true content: @@ -39,12 +108,11 @@ paths: properties: username: type: string - description: User's username - example: "john.doe" + example: johndoe password: type: string - description: User's password - example: "password123" + format: password + example: password123 responses: '200': description: Login successful @@ -53,59 +121,72 @@ paths: schema: type: object properties: - access_token: + message: type: string - description: JWT access token - example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." - '400': - description: Invalid request data + token: + type: string + user: + $ref: '#/components/schemas/User' '401': description: Invalid credentials + content: + application/json: + schema: + $ref: '#/components/schemas/Error' - /api/v1/accounts/{account_id}: - get: - summary: Get account by ID - description: Retrieve account details by account ID + /auth/logout: + post: tags: - - Accounts - parameters: - - name: account_id - in: path - required: true - description: Account ID - schema: - type: string - example: "ACC123456" + - Authentication + summary: User logout + description: Logout current user. Note: Tokens are stateless and never expire. + operationId: logout security: - bearerAuth: [] responses: '200': - description: Account details retrieved successfully + description: Logged out successfully content: application/json: schema: type: object properties: - account_id: + message: type: string - example: "ACC123456" - balance: - type: number - format: float - example: 1000.00 - '401': - description: Unauthorized - Invalid or missing token - '404': - description: Account not found - /api/v1/process-file: - post: - summary: Process file content - description: Read and return the contents of a file from the server + /auth/me: + get: tags: - - File Operations + - Authentication + summary: Get current user information + description: Retrieve information about the currently authenticated user. + operationId: getCurrentUser security: - bearerAuth: [] + responses: + '200': + description: User information + content: + application/json: + schema: + type: object + properties: + user: + $ref: '#/components/schemas/User' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /auth/reset-password: + post: + tags: + - Authentication + summary: Reset user password + description: Reset password for a user. Vulnerable to broken authentication - no token validation or email verification. + operationId: resetPassword requestBody: required: true content: @@ -113,35 +194,85 @@ paths: schema: type: object required: - - file_path + - email + - new_password properties: - file_path: + email: type: string - description: Path to the file to process - example: "/etc/passwd" + format: email + example: john@example.com + new_password: + type: string + format: password + example: newpassword123 responses: '200': - description: File content retrieved successfully + description: Password reset successfully content: application/json: schema: type: object properties: - result: + message: type: string - description: File content - example: "root:x:0:0:root:/root:/bin/bash..." + '400': + description: Bad request + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '404': + description: User not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /projects: + get: + tags: + - Projects + summary: List all projects + description: Get a list of all projects. Vulnerable to SQL injection in search parameter. + operationId: listProjects + security: + - bearerAuth: [] + parameters: + - name: search + in: query + description: Search term for project name or description (vulnerable to SQL injection) + schema: + type: string + - name: status + in: query + description: Filter by status + schema: + type: string + responses: + '200': + description: List of projects + content: + application/json: + schema: + type: object + properties: + projects: + type: array + items: + $ref: '#/components/schemas/Project' '401': - description: Unauthorized - Invalid or missing token - '500': - description: Error processing file + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/Error' - /api/v1/ping: post: - summary: Ping network host - description: Execute ping command against a specified host tags: - - Network Operations + - Projects + summary: Create a new project + description: Create a new project. No input validation or sanitization. + operationId: createProject security: - bearerAuth: [] requestBody: @@ -150,129 +281,1800 @@ paths: application/json: schema: type: object + required: + - name properties: - host: + name: type: string - description: Host to ping - default: "localhost" - example: "google.com" + example: My New Project + description: + type: string + example: Project description + is_public: + type: boolean + default: false responses: - '200': - description: Ping executed successfully + '201': + description: Project created successfully content: application/json: schema: type: object properties: - result: + message: type: string - description: Ping command output - example: "PING google.com (142.250.191.78) 56(84) bytes of data..." - '401': - description: Unauthorized - Invalid or missing token - '500': - description: Error executing ping command + project: + $ref: '#/components/schemas/Project' + '400': + description: Bad request + content: + application/json: + schema: + $ref: '#/components/schemas/Error' - /api/v1/comment: - post: - summary: Add comment - description: Store and return a user comment + /projects/{projectId}: + get: + tags: + - Projects + summary: Get project by ID + description: Retrieve a specific project. Vulnerable to IDOR. + operationId: getProject + security: + - bearerAuth: [] + parameters: + - name: projectId + in: path + required: true + schema: + type: integer + responses: + '200': + description: Project details + content: + application/json: + schema: + type: object + properties: + project: + $ref: '#/components/schemas/Project' + '404': + description: Project not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + put: tags: - - User Content + - Projects + summary: Update project + description: Update project details. Vulnerable to broken access control. + operationId: updateProject security: - bearerAuth: [] + parameters: + - name: projectId + in: path + required: true + schema: + type: integer requestBody: - required: true content: application/json: schema: type: object - required: - - comment properties: - comment: + name: type: string - description: User comment to store - example: "This is a test comment" + description: + type: string + is_public: + type: boolean responses: '200': - description: Comment stored successfully + description: Project updated successfully content: application/json: schema: type: object properties: - comment: + message: + type: string + project: + $ref: '#/components/schemas/Project' + '404': + description: Project not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + delete: + tags: + - Projects + summary: Delete project + description: Delete a project. Vulnerable to broken access control. + operationId: deleteProject + security: + - bearerAuth: [] + parameters: + - name: projectId + in: path + required: true + schema: + type: integer + responses: + '200': + description: Project deleted successfully + content: + application/json: + schema: + type: object + properties: + message: type: string - description: The stored comment - example: "This is a test comment" + '404': + description: Project not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /projects/{projectId}/dashboard: + get: + tags: + - Projects + summary: Get project dashboard + description: Get project dashboard with tasks and documents. Vulnerable to IDOR. + operationId: getProjectDashboard + security: + - bearerAuth: [] + parameters: + - name: projectId + in: path + required: true + schema: + type: integer + responses: + '200': + description: Project dashboard data + content: + application/json: + schema: + type: object + properties: + project: + $ref: '#/components/schemas/Project' + tasks: + type: array + items: + $ref: '#/components/schemas/Task' + documents: + type: array + items: + $ref: '#/components/schemas/Document' + stats: + type: object + properties: + total_tasks: + type: integer + total_documents: + type: integer + '404': + description: Project not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /projects/{projectId}/tasks: + get: + tags: + - Projects + summary: Get project tasks + description: Get all tasks for a project. Vulnerable to SQL injection in search parameter. + operationId: getProjectTasks + security: + - bearerAuth: [] + parameters: + - name: projectId + in: path + required: true + schema: + type: integer + - name: search + in: query + description: Search term (vulnerable to SQL injection) + schema: + type: string + - name: status + in: query + schema: + type: string + enum: [pending, in_progress, completed] + responses: + '200': + description: List of tasks + content: + application/json: + schema: + type: object + properties: + tasks: + type: array + items: + $ref: '#/components/schemas/Task' + '404': + description: Project not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /tasks: + get: + tags: + - Tasks + summary: List all tasks + description: Get a list of tasks. Vulnerable to SQL injection and broken access control. + operationId: listTasks + security: + - bearerAuth: [] + parameters: + - name: project_id + in: query + schema: + type: integer + - name: status + in: query + schema: + type: string + enum: [pending, in_progress, completed] + - name: search + in: query + description: Search term (vulnerable to SQL injection) + schema: + type: string + - name: assigned_to + in: query + schema: + type: integer + responses: + '200': + description: List of tasks + content: + application/json: + schema: + type: object + properties: + tasks: + type: array + items: + $ref: '#/components/schemas/Task' '401': - description: Unauthorized - Invalid or missing token + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/Error' - /api/v1/upload: post: - summary: Upload file - description: Handle file upload and return filename tags: - - File Operations + - Tasks + summary: Create a new task + description: Create a new task. No input validation or sanitization. + operationId: createTask security: - bearerAuth: [] requestBody: required: true content: - multipart/form-data: + application/json: schema: type: object required: - - file + - title + - project_id properties: - file: + title: type: string - format: binary - description: File to upload + example: Complete project documentation + description: + type: string + example: Task description + project_id: + type: integer + assigned_to: + type: integer + priority: + type: string + enum: [low, medium, high] + default: medium + due_date: + type: string + format: date-time responses: - '200': - description: File uploaded successfully + '201': + description: Task created successfully content: application/json: schema: type: object properties: - filename: + message: type: string - description: Name of the uploaded file - example: "document.pdf" - '401': - description: Unauthorized - Invalid or missing token + task: + $ref: '#/components/schemas/Task' '400': - description: No file provided - -components: - securitySchemes: - bearerAuth: - type: http - scheme: bearer - bearerFormat: JWT - description: | - JWT Bearer token authentication. - Include the token in the Authorization header as: `Bearer ` - - To obtain a token, use the `/api/v1/login` endpoint with your username and password. - - schemas: - Error: - type: object - properties: - error: - type: string - description: Error message - example: "Invalid credentials" + description: Bad request + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /tasks/{taskId}: + get: + tags: + - Tasks + summary: Get task by ID + description: Retrieve a specific task. Vulnerable to IDOR. + operationId: getTask + security: + - bearerAuth: [] + parameters: + - name: taskId + in: path + required: true + schema: + type: integer + responses: + '200': + description: Task details + content: + application/json: + schema: + type: object + properties: + task: + $ref: '#/components/schemas/Task' + '404': + description: Task not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + put: + tags: + - Tasks + summary: Update task + description: Update task details. Vulnerable to broken access control. + operationId: updateTask + security: + - bearerAuth: [] + parameters: + - name: taskId + in: path + required: true + schema: + type: integer + requestBody: + content: + application/json: + schema: + type: object + properties: + title: + type: string + description: + type: string + status: + type: string + enum: [pending, in_progress, completed] + assigned_to: + type: integer + priority: + type: string + enum: [low, medium, high] + due_date: + type: string + format: date-time + responses: + '200': + description: Task updated successfully + content: + application/json: + schema: + type: object + properties: + message: + type: string + task: + $ref: '#/components/schemas/Task' + '404': + description: Task not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + delete: + tags: + - Tasks + summary: Delete task + description: Delete a task. Vulnerable to broken access control. + operationId: deleteTask + security: + - bearerAuth: [] + parameters: + - name: taskId + in: path + required: true + schema: + type: integer + responses: + '200': + description: Task deleted successfully + content: + application/json: + schema: + type: object + properties: + message: + type: string + '404': + description: Task not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /tasks/{taskId}/comments: + get: + tags: + - Tasks + summary: Get task comments + description: Get all comments for a task. Vulnerable to IDOR and XSS. + operationId: getTaskComments + security: + - bearerAuth: [] + parameters: + - name: taskId + in: path + required: true + schema: + type: integer + responses: + '200': + description: List of comments + content: + application/json: + schema: + type: object + properties: + comments: + type: array + items: + $ref: '#/components/schemas/Comment' + '404': + description: Task not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + post: + tags: + - Tasks + summary: Create task comment + description: Add a comment to a task. Vulnerable to XSS and IDOR. + operationId: createTaskComment + security: + - bearerAuth: [] + parameters: + - name: taskId + in: path + required: true + schema: + type: integer + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - content + properties: + content: + type: string + example: This is a comment + responses: + '201': + description: Comment created successfully + content: + application/json: + schema: + type: object + properties: + message: + type: string + comment: + $ref: '#/components/schemas/Comment' + '400': + description: Bad request + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /documents: + get: + tags: + - Documents + summary: List all documents + description: Get a list of documents. Vulnerable to IDOR and broken access control. + operationId: listDocuments + security: + - bearerAuth: [] + parameters: + - name: project_id + in: query + schema: + type: integer + responses: + '200': + description: List of documents + content: + application/json: + schema: + type: object + properties: + documents: + type: array + items: + $ref: '#/components/schemas/Document' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + post: + tags: + - Documents + summary: Upload document + description: Upload a document. Vulnerable to XXE, insecure file upload, and no validation. + operationId: uploadDocument + security: + - bearerAuth: [] + requestBody: + required: true + content: + multipart/form-data: + schema: + type: object + required: + - file + properties: + file: + type: string + format: binary + project_id: + type: integer + is_public: + type: boolean + default: false + responses: + '201': + description: Document uploaded successfully + content: + application/json: + schema: + type: object + properties: + message: + type: string + document: + $ref: '#/components/schemas/Document' + metadata: + type: object + description: File metadata extracted from the document + '400': + description: Bad request + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /documents/{documentId}: + get: + tags: + - Documents + summary: Get document by ID + description: Retrieve document information. Vulnerable to IDOR. + operationId: getDocument + security: + - bearerAuth: [] + parameters: + - name: documentId + in: path + required: true + schema: + type: integer + responses: + '200': + description: Document details + content: + application/json: + schema: + type: object + properties: + document: + $ref: '#/components/schemas/Document' + '404': + description: Document not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + delete: + tags: + - Documents + summary: Delete document + description: Delete a document. Vulnerable to broken access control. + operationId: deleteDocument + security: + - bearerAuth: [] + parameters: + - name: documentId + in: path + required: true + schema: + type: integer + responses: + '200': + description: Document deleted successfully + content: + application/json: + schema: + type: object + properties: + message: + type: string + '404': + description: Document not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /documents/{documentId}/download: + get: + tags: + - Documents + summary: Download document + description: Download a document file. Vulnerable to path traversal and IDOR. + operationId: downloadDocument + security: + - bearerAuth: [] + parameters: + - name: documentId + in: path + required: true + schema: + type: integer + responses: + '200': + description: Document file + content: + application/octet-stream: + schema: + type: string + format: binary + '404': + description: Document not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /documents/{documentId}/metadata: + get: + tags: + - Documents + summary: Get document metadata + description: Retrieve document metadata information. Vulnerable to IDOR. + operationId: getDocumentMetadata + security: + - bearerAuth: [] + parameters: + - name: documentId + in: path + required: true + schema: + type: integer + responses: + '200': + description: Document metadata + content: + application/json: + schema: + type: object + properties: + document: + $ref: '#/components/schemas/Document' + metadata: + type: object + description: File metadata extracted from the document + '404': + description: Document not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /messages: + get: + tags: + - Messages + summary: List messages + description: Get a list of messages. Vulnerable to IDOR and broken access control. Supports pagination. + operationId: listMessages + security: + - bearerAuth: [] + parameters: + - name: sender_id + in: query + schema: + type: integer + - name: receiver_id + in: query + schema: + type: integer + - name: page + in: query + description: Page number for pagination + schema: + type: integer + default: 1 + - name: per_page + in: query + description: Number of items per page + schema: + type: integer + default: 10 + responses: + '200': + description: List of messages + content: + application/json: + schema: + type: object + properties: + messages: + type: array + items: + $ref: '#/components/schemas/Message' + pagination: + type: object + properties: + page: + type: integer + per_page: + type: integer + total: + type: integer + pages: + type: integer + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + post: + tags: + - Messages + summary: Send message + description: Send a message to another user. Vulnerable to XSS and no input validation. + operationId: sendMessage + security: + - bearerAuth: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - receiver_id + - content + properties: + receiver_id: + type: integer + subject: + type: string + example: Message subject + content: + type: string + example: Message content + responses: + '201': + description: Message sent successfully + content: + application/json: + schema: + type: object + properties: + message: + type: string + message_data: + $ref: '#/components/schemas/Message' + '400': + description: Bad request + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /messages/{messageId}: + get: + tags: + - Messages + summary: Get message by ID + description: Retrieve a specific message. Vulnerable to IDOR and XSS. + operationId: getMessage + security: + - bearerAuth: [] + parameters: + - name: messageId + in: path + required: true + schema: + type: integer + responses: + '200': + description: Message details + content: + application/json: + schema: + type: object + properties: + message: + $ref: '#/components/schemas/Message' + '404': + description: Message not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + delete: + tags: + - Messages + summary: Delete message + description: Delete a message. Vulnerable to broken access control. + operationId: deleteMessage + security: + - bearerAuth: [] + parameters: + - name: messageId + in: path + required: true + schema: + type: integer + responses: + '200': + description: Message deleted successfully + content: + application/json: + schema: + type: object + properties: + message: + type: string + '404': + description: Message not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /messages/search: + get: + tags: + - Messages + summary: Search messages + description: Search messages by content or subject. Vulnerable to SQL injection. + operationId: searchMessages + security: + - bearerAuth: [] + parameters: + - name: q + in: query + required: true + description: Search query (vulnerable to SQL injection) + schema: + type: string + responses: + '200': + description: Search results + content: + application/json: + schema: + type: object + properties: + query: + type: string + results: + type: array + items: + $ref: '#/components/schemas/Message' + '400': + description: Bad request + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /v1/projects: + get: + tags: + - Projects + summary: List all projects (v1 API) + description: Get a list of all projects. No authentication required. Vulnerable to SQL injection. + operationId: listProjectsV1 + parameters: + - name: search + in: query + description: Search term (vulnerable to SQL injection) + schema: + type: string + - name: status + in: query + schema: + type: string + responses: + '200': + description: List of projects + content: + application/json: + schema: + type: object + properties: + projects: + type: array + items: + $ref: '#/components/schemas/Project' + + /v1/projects/{projectId}: + get: + tags: + - Projects + summary: Get project by ID (v1 API) + description: Retrieve a specific project. No authentication required. Vulnerable to IDOR. + operationId: getProjectV1 + parameters: + - name: projectId + in: path + required: true + schema: + type: integer + responses: + '200': + description: Project details + content: + application/json: + schema: + type: object + properties: + project: + $ref: '#/components/schemas/Project' + '404': + description: Project not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /v1/projects/{projectId}/tasks: + get: + tags: + - Tasks + summary: Get project tasks (v1 API) + description: Get tasks for a project. No authentication required. Vulnerable to SQL injection and IDOR. + operationId: getProjectTasksV1 + parameters: + - name: projectId + in: path + required: true + schema: + type: integer + - name: search + in: query + description: Search term (vulnerable to SQL injection) + schema: + type: string + - name: status + in: query + schema: + type: string + responses: + '200': + description: List of tasks + content: + application/json: + schema: + type: object + properties: + tasks: + type: array + items: + $ref: '#/components/schemas/Task' + + /v1/tasks: + get: + tags: + - Tasks + summary: List all tasks (v1 API) + description: Get a list of tasks. No authentication required. Vulnerable to SQL injection. + operationId: listTasksV1 + parameters: + - name: search + in: query + description: Search term (vulnerable to SQL injection) + schema: + type: string + - name: project_id + in: query + schema: + type: integer + - name: assigned_to + in: query + schema: + type: integer + responses: + '200': + description: List of tasks + content: + application/json: + schema: + type: object + properties: + tasks: + type: array + items: + $ref: '#/components/schemas/Task' + + /v1/tasks/{taskId}: + get: + tags: + - Tasks + summary: Get task by ID (v1 API) + description: Retrieve a specific task. No authentication required. Vulnerable to IDOR. + operationId: getTaskV1 + parameters: + - name: taskId + in: path + required: true + schema: + type: integer + responses: + '200': + description: Task details + content: + application/json: + schema: + type: object + properties: + task: + $ref: '#/components/schemas/Task' + '404': + description: Task not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /v1/tasks/{taskId}/comments: + get: + tags: + - Tasks + summary: Get task comments (v1 API) + description: Get all comments for a task. No authentication required. Vulnerable to IDOR and XSS. + operationId: getTaskCommentsV1 + parameters: + - name: taskId + in: path + required: true + schema: + type: integer + responses: + '200': + description: List of comments + content: + application/json: + schema: + type: object + properties: + comments: + type: array + items: + $ref: '#/components/schemas/Comment' + + /v1/documents: + get: + tags: + - Documents + summary: List all documents (v1 API) + description: Get a list of documents. No authentication required. Vulnerable to IDOR. + operationId: listDocumentsV1 + parameters: + - name: project_id + in: query + schema: + type: integer + responses: + '200': + description: List of documents + content: + application/json: + schema: + type: object + properties: + documents: + type: array + items: + $ref: '#/components/schemas/Document' + + /v1/documents/{documentId}: + get: + tags: + - Documents + summary: Get document by ID (v1 API) + description: Retrieve document information. No authentication required. Vulnerable to IDOR. + operationId: getDocumentV1 + parameters: + - name: documentId + in: path + required: true + schema: + type: integer + responses: + '200': + description: Document details + content: + application/json: + schema: + type: object + properties: + document: + $ref: '#/components/schemas/Document' + '404': + description: Document not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /v1/messages: + get: + tags: + - Messages + summary: List all messages (v1 API) + description: Get a list of messages. No authentication required. Vulnerable to IDOR and XSS. + operationId: listMessagesV1 + parameters: + - name: sender_id + in: query + schema: + type: integer + - name: receiver_id + in: query + schema: + type: integer + responses: + '200': + description: List of messages + content: + application/json: + schema: + type: object + properties: + messages: + type: array + items: + $ref: '#/components/schemas/Message' + + /v1/messages/{messageId}: + get: + tags: + - Messages + summary: Get message by ID (v1 API) + description: Retrieve a specific message. No authentication required. Vulnerable to IDOR and XSS. + operationId: getMessageV1 + parameters: + - name: messageId + in: path + required: true + schema: + type: integer + responses: + '200': + description: Message details + content: + application/json: + schema: + type: object + properties: + message: + $ref: '#/components/schemas/Message' + '404': + description: Message not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /analytics/stats: + get: + tags: + - Analytics + summary: Get application statistics + description: Get application-wide statistics. Requires authentication. + operationId: getAnalyticsStats + security: + - bearerAuth: [] + responses: + '200': + description: Application statistics + content: + application/json: + schema: + type: object + properties: + user_count: + type: integer + project_count: + type: integer + task_count: + type: integer + document_count: + type: integer + message_count: + type: integer + comment_count: + type: integer + current_time: + type: string + format: date-time + timestamp: + type: number + request_id: + type: string + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /analytics/search: + get: + tags: + - Analytics + summary: Search across users and projects + description: Search across users and projects. Requires authentication. + operationId: analyticsSearch + security: + - bearerAuth: [] + parameters: + - name: q + in: query + required: true + description: Search query + schema: + type: string + responses: + '200': + description: Search results + content: + application/json: + schema: + type: object + properties: + query: + type: string + users: + type: array + items: + $ref: '#/components/schemas/User' + projects: + type: array + items: + $ref: '#/components/schemas/Project' + search_time: + type: string + format: date-time + request_id: + type: string + '400': + description: Bad request + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /analytics/user/{userId}: + get: + tags: + - Analytics + summary: Get user analytics + description: Get user details and analytics. Requires authentication. Vulnerable to IDOR. + operationId: getUserAnalytics + security: + - bearerAuth: [] + parameters: + - name: userId + in: path + required: true + schema: + type: integer + responses: + '200': + description: User analytics + content: + application/json: + schema: + type: object + properties: + user: + $ref: '#/components/schemas/User' + fetched_at: + type: string + format: date-time + request_id: + type: string + '404': + description: User not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /v1/users: + get: + tags: + - Projects + summary: List all users (v1 API) + description: Get a list of all users. No authentication required. Vulnerable to SQL injection in search parameter. + operationId: listUsersV1 + parameters: + - name: search + in: query + description: Search term (vulnerable to SQL injection) + schema: + type: string + responses: + '200': + description: List of users + content: + application/json: + schema: + type: object + properties: + users: + type: array + items: + $ref: '#/components/schemas/User' + request_id: + type: string + count: + type: integer + + post: + tags: + - Projects + summary: Create user (v1 API) + description: Create a new user. Requires authentication. Vulnerable to broken access control. + operationId: createUserV1 + security: + - bearerAuth: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - username + - email + - password + properties: + username: + type: string + email: + type: string + format: email + password: + type: string + format: password + role: + type: string + enum: [admin, project_manager, team_member] + default: team_member + responses: + '201': + description: User created successfully + content: + application/json: + schema: + type: object + properties: + message: + type: string + user: + $ref: '#/components/schemas/User' + '400': + description: Bad request + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /v1/users/{userId}: + get: + tags: + - Projects + summary: Get user by ID (v1 API) + description: Retrieve a specific user. No authentication required. Vulnerable to IDOR. + operationId: getUserV1 + parameters: + - name: userId + in: path + required: true + schema: + type: integer + responses: + '200': + description: User details + content: + application/json: + schema: + type: object + properties: + user: + $ref: '#/components/schemas/User' + '404': + description: User not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + put: + tags: + - Projects + summary: Update user (v1 API) + description: Update user details. Requires authentication. Vulnerable to broken access control. + operationId: updateUserV1 + security: + - bearerAuth: [] + parameters: + - name: userId + in: path + required: true + schema: + type: integer + requestBody: + content: + application/json: + schema: + type: object + properties: + username: + type: string + email: + type: string + format: email + password: + type: string + format: password + role: + type: string + enum: [admin, project_manager, team_member] + responses: + '200': + description: User updated successfully + content: + application/json: + schema: + type: object + properties: + message: + type: string + user: + $ref: '#/components/schemas/User' + '404': + description: User not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + delete: + tags: + - Projects + summary: Delete user (v1 API) + description: Delete a user. Requires authentication. Vulnerable to broken access control. + operationId: deleteUserV1 + security: + - bearerAuth: [] + parameters: + - name: userId + in: path + required: true + schema: + type: integer + responses: + '200': + description: User deleted successfully + content: + application/json: + schema: + type: object + properties: + message: + type: string + '404': + description: User not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /v1/stats: + get: + tags: + - Projects + summary: Get statistics (v1 API) + description: Get application statistics. No authentication required. + operationId: getStatsV1 + responses: + '200': + description: Application statistics + content: + application/json: + schema: + type: object + properties: + total_users: + type: integer + total_projects: + type: integer + total_tasks: + type: integer + total_documents: + type: integer + total_messages: + type: integer + generated_at: + type: string + format: date-time + request_id: + type: string + + /v1/search: + get: + tags: + - Projects + summary: Global search (v1 API) + description: Global search across users, projects, and tasks. No authentication required. Vulnerable to SQL injection. + operationId: globalSearchV1 + parameters: + - name: q + in: query + required: true + description: Search query (vulnerable to SQL injection) + schema: + type: string + responses: + '200': + description: Search results + content: + application/json: + schema: + type: object + properties: + query: + type: string + users: + type: array + items: + $ref: '#/components/schemas/User' + projects: + type: array + items: + $ref: '#/components/schemas/Project' + tasks: + type: array + items: + $ref: '#/components/schemas/Task' + '400': + description: Bad request + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + +components: + securitySchemes: + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + description: JWT token authentication. Tokens never expire. + + schemas: + User: + type: object + properties: + id: + type: integer + username: + type: string + email: + type: string + format: email + password_hash: + type: string + description: Should not be exposed in production + role: + type: string + enum: [admin, project_manager, team_member] + api_key: + type: string + description: Should not be exposed in production + created_at: + type: string + format: date-time + last_login: + type: string + format: date-time + + Project: + type: object + properties: + id: + type: integer + name: + type: string + description: + type: string + owner_id: + type: integer + is_public: + type: boolean + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + + Task: + type: object + properties: + id: + type: integer + title: + type: string + description: + type: string + project_id: + type: integer + assigned_to: + type: integer + nullable: true + created_by: + type: integer + status: + type: string + enum: [pending, in_progress, completed] + priority: + type: string + enum: [low, medium, high] + due_date: + type: string + format: date-time + nullable: true + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + + Comment: + type: object + properties: + id: + type: integer + task_id: + type: integer + user_id: + type: integer + content: + type: string + created_at: + type: string + format: date-time + + Document: + type: object + properties: + id: + type: integer + filename: + type: string + original_filename: + type: string + file_size: + type: integer + file_type: + type: string + project_id: + type: integer + nullable: true + uploaded_by: + type: integer + is_public: + type: boolean + created_at: + type: string + format: date-time + + Message: + type: object + properties: + id: + type: integer + sender_id: + type: integer + receiver_id: + type: integer + subject: + type: string + nullable: true + content: + type: string + is_read: + type: boolean + created_at: + type: string + format: date-time + + Error: + type: object + properties: + error: + type: string + required: + - error - Success: - type: object - properties: - message: - type: string - description: Success message - example: "Operation completed successfully" -