Posting here before logging a defect as requested on the Jira page.
There are various issues in Lucee’s handling of standard-compliant, but not happy-path responses from NTP servers when “use time server” is checked in the “Regional” settings (as is the default). This leads to vastly incorrect dates being returned by Lucee. This issue exists from Lucee 4 - 6 at least.
Below are some examples of how Lucee mishandles NTP server responses. No matter what, if Lucee receives a parse-able response from the NTP server it will use the offset (/core/src/main/java/lucee/runtime/net/ntp/NtpClient.java) given, even if it is obviously incorrect (and the NTP server is trying to communicate not to use the data).
NTP messages have various effective headers in their responses. The two of reference here are the stratum
indicating what the source of the time information is and the leap indicator
indicating if a leap second will be happening in the next day.
While the original NTP specification said that having a stratum of 0 had unspecified behavior (reference (rfc2030#section-4)) the updated RFC (rfc4330) specifies that a stratum of 0 means it is a “kiss-of-death” message defined later (rfc4330#section-8) in the document. One of the common usages of a kiss-of-death response is as a rate limit.
Simply put, a stratum of 0 should not be processed as a legitimate response.
Of note, as discussed here(https://www.ntp.org/documentation/4.2.8-series/rate/) “In order to make sure the client notices the KoD [Kiss of Death] packet, the server sets the receive and transmit timestamps to the transmit timestamp of the client packet. Thus, even if the client ignores all except the timestamps, it cannot do any useful time computations.”
What this means for Lucee is that it sends the NTP server the time it thinks it is, the NTP server responds with a kiss of death including an offset identical to the timestamp sent which Lucee adds to System.currentTimeMillis()
which leads to Lucee believing the time is basically 1/1/1900. This can cause huge data integrity issues.
Another condition ignored is when the leap indicator is 3 which indicates an alarm condition where the clock is not synchronized (reference(rfc4330#section-4))
“The most
important indicator of an unhealthy server is the LI [leap indicator] field, in which
a value of 3 indicates an unsynchronized condition. When this value
is displayed, clients should discard the server message, regardless
of the contents of other fields.” (rfc2030#section-6))
I implemented an example NTP server (GitHub - kylec32/RateLimitedNtp: Example repo that always responds with a rate limited response to NTP requests) that always responds with a rate limit response. You can run it and point to it in Lucee, and after a restart, you will see that <cfdump var="#now()#"/>
returns as a very early 1/1/1900 timestamp.
I tried to be more helpful with links to the appropriate section but am limited to two links as a new user.