Kim Hage created LANG-1748:
------------------------------

             Summary: RandomStringUtils.random() drains the systems entropy 
pool and blocks
                 Key: LANG-1748
                 URL: https://issues.apache.org/jira/browse/LANG-1748
             Project: Commons Lang
          Issue Type: Bug
    Affects Versions: 3.15.0
         Environment: {{*java -version*
openjdk version "17.0.9" 2023-10-17
OpenJDK Runtime Environment Temurin-17.0.9+9 (build 17.0.9+9)
OpenJDK 64-Bit Server VM Temurin-17.0.9+9 (build 17.0.9+9, mixed mode, sharing)

*/proc/version*
Linux version 3.10.0-1160.119.1.el7.x86_64 ([email protected]) 
(gcc version 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) ) #1 SMP Tue Jun 4 
14:43:51 UTC 2024

*/etc/centos-release*
CentOS Linux release 7.9.2009 (Core)

*/sys/devices/virtual/misc/hw_random/rng_available* is empty
}}
            Reporter: Kim Hage


Since we upgraded to Version 3.15 of commons-lang we have experienced 
performance problems and timeout issues during deployments. Our analysis 
suggests that this is due to issues introduced with [this 
change|https://github.com/apache/commons-lang/pull/1250], namely the use of 
{{{}SecureRandom.{}}}{{{}getInstanceStrong(){}}} in 
{{{}src/main/java/org/apache/commons/lang3/RandomUtils.java{}}}. 
SecureRandom.getInstanceStrong() uses /{{{}dev/random{}}} instead of 
{{/dev/urandom}} on linux systems. which leads to terrible performance when 
little entropy is available on the system.

Here is what seems to happen in our case
 * Our deployments use Liquibase for database schema migrations
 * [Liquibase uses RandomStringUtils to generate internal 
identifiers|https://github.com/liquibase/liquibase/blob/e854a6e18c29651da0d51265a28c58f22ef3248b/liquibase-standard/src/main/java/liquibase/Scope.java#L154],
 and it generates quite a few of them. (This might be a strange decision on 
their side as well, but probably not the issue here)
 * Each call to RandomStringUtils.random() takes a few bytes out of the systems 
entropy pool. This can be traced by calling {{{}cat 
/proc/sys/kernel/random/entropy_avai{}}}l on the linux shell.
 * The systems entropy pool gets drained quickly and when it is empty, calls to 
RandomStringUtils.random() will block until new entropy becomes available. 
Since we are running on a virtual machine, new bytes are added very slowly to 
the systems entropy pool (about 3-4 bytes per second)
 * Ultimately, our deployments fail with a timeout because Liquibase was unable 
to finish in time

I am not a security expert, but the general consensus on the internet seems to 
be that using /dev/urandom instead of /dev/random should be equally secure for 
almost all use cases.

Maybe the call to {{SecureRandom.getInstaceStrong()}} in {{RandomUtils}} could 
be replaced with {{{}new SecureRandom(){}}}. Calls to 
RandomStringUtils.random(...) should then be no longer blocking (probably).



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to