CVE-2021-47966 Overview
CVE-2021-47966 is a SQL injection vulnerability in PHP Timeclock 1.04, an open-source employee time tracking application. The flaw resides in the login_userid parameter of login.php, which fails to sanitize user-supplied input before passing it to SQL queries. Unauthenticated attackers can send crafted POST requests using time-based payloads with SLEEP functions or boolean-based RLIKE conditional statements. Successful exploitation enables extraction of database contents including employee names and credentials. The vulnerability is classified under [CWE-89] (Improper Neutralization of Special Elements used in an SQL Command).
Critical Impact
Unauthenticated attackers can extract sensitive database contents, including employee credentials, by sending crafted POST requests to login.php.
Affected Products
- PHP Timeclock 1.04
- Distributed via the SourceForge Timeclock Project
- Download archive: PHP Timeclock 1.04 release files
Discovery Timeline
- 2026-05-15 - CVE-2021-47966 published to NVD
- 2026-05-18 - Last updated in NVD database
Technical Details for CVE-2021-47966
Vulnerability Analysis
The vulnerability stems from login.php directly concatenating the login_userid POST parameter into a SQL statement without parameterization or input sanitization. Attackers can break out of the intended query context and inject arbitrary SQL syntax. Both time-based blind and boolean-based blind injection techniques are viable, allowing complete extraction of database contents one character at a time. Time-based injection uses MySQL SLEEP() calls to infer data from response delays. Boolean-based injection uses RLIKE regular expression matching to infer data from differential application responses. Because authentication is not required to reach login.php, any attacker with network access to the application can exploit the flaw.
Root Cause
The root cause is improper neutralization of special characters in user-controlled input before it is incorporated into a SQL query. The login_userid parameter is interpolated into the authentication query without using prepared statements or escaping routines. PHP Timeclock 1.04 has not received vendor updates to remediate this issue. See the VulnCheck SQL Injection Advisory for additional context.
Attack Vector
The attack vector is network-based and requires no authentication or user interaction. An attacker sends a POST request to login.php with a malicious login_userid value. A time-based payload such as a SLEEP(5) clause causes the database to pause when the injected condition evaluates true, leaking data through measurable response latency. A boolean-based payload using RLIKE produces distinguishable application responses depending on whether the injected condition matches. Iterating through these payloads enables the attacker to enumerate table names, column names, and row contents such as username and password fields. A proof of concept is published as Exploit-DB #49849.
Detection Methods for CVE-2021-47966
Indicators of Compromise
- POST requests to /login.php containing SQL keywords such as SLEEP, RLIKE, UNION, SELECT, or OR 1=1 within the login_userid parameter.
- Web server access logs showing repeated POST requests to login.php from a single source with abnormally long response times indicative of time-based injection.
- Database query logs containing malformed or unexpected SQL constructs originating from the Timeclock application user.
- Anomalous outbound data volumes from the database host after interaction with the Timeclock front end.
Detection Strategies
- Deploy a web application firewall ruleset that matches SQL injection signatures targeting login form parameters, including SLEEP(, BENCHMARK(, and RLIKE patterns.
- Inspect HTTP request bodies submitted to login.php for non-alphanumeric characters in the login_userid field, which should normally accept only usernames.
- Correlate failed login attempts with response latency spikes to surface time-based blind injection attempts.
- Enable MySQL general query logging on the Timeclock backend and alert on queries containing time-delay functions.
Monitoring Recommendations
- Forward web server, application, and database logs to a centralized analytics platform for correlation and retention.
- Baseline normal login.php request rates and alert on volumetric anomalies from individual source addresses.
- Monitor the application's database account for queries that read from tables outside the authentication workflow.
How to Mitigate CVE-2021-47966
Immediate Actions Required
- Remove PHP Timeclock 1.04 from internet-exposed environments and restrict access to trusted internal networks only.
- Place the application behind a web application firewall configured to block SQL injection payloads in form parameters.
- Rotate all credentials stored in the Timeclock database, as they must be considered compromised if the application has been internet-exposed.
- Audit the Timeclock database for unauthorized read activity and review web server logs for prior exploitation attempts.
Patch Information
No vendor patch is available for PHP Timeclock 1.04. The project on SourceForge has not published a fixed release addressing CVE-2021-47966. Organizations should migrate to a maintained time tracking solution. Refer to the VulnCheck SQL Injection Advisory for the authoritative advisory.
Workarounds
- Decommission PHP Timeclock 1.04 and replace it with a supported, actively maintained alternative.
- If the application must remain in service, restrict network access using firewall rules, VPN-only access, or IP allowlisting.
- Apply a virtual patch at the WAF layer that rejects POST requests to login.php containing SQL metacharacters in the login_userid parameter.
- Enforce least-privilege database permissions for the Timeclock application account to limit data exposure if injection succeeds.
# Example WAF rule (ModSecurity) blocking SQL injection in login_userid
SecRule REQUEST_URI "@endsWith /login.php" \
"id:1000001,phase:2,deny,status:403,\
chain,msg:'PHP Timeclock CVE-2021-47966 SQLi attempt'"
SecRule ARGS:login_userid "@rx (?i)(sleep\s*\(|benchmark\s*\(|rlike|union\s+select|or\s+1=1|--|/\*)" \
"t:none,t:urlDecodeUni"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


