Our Server Vulnerability Scan gave below vulnerability:
Weak SSL/TLS Key Exchange on port 443
Weak Cipher Names: DHE-RSA-AES256-GCM-SHA384, DHE-RSA-AES128-GCM-SHA256, DHE-RSA-AES256-SHA256, DHE-RSA-AES128-SHA256, DHE-RSA-AES256-SHA, DHE-RSA-AES128-SHA
KEY-SIZE: 1024 QUANTUM-STRENGTH: low
Technology stack: Java 8, SpringBoot 2.3.8.RELEASE, Windows Server 2019, Wildfly 14, apache httpclient 4.5.10
To resolve the reported Vulnerability, applied below 2 changes
$JAVA_HOME/jre/lib/security/java.security file: jdk.tls.disabledAlgorithms changed DH keySize < 1024 to DH keySize < 2048
Wildfly standalone.xml: Added enabled-cipher-suite parameter to the https-listener tag
<https-listener name="https" socket-binding="https" disallowed-methods="HEAD OPTIONS TRACE" security-realm="ApplicationRealm" enabled-cipher-suites="TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384" enabled-protocols="TLSv1.2" enable-http2="true"/>
After these changes, no vulnerabilities were reported in Server scan.
But application started throwing below 2 Exceptions intermittently in RestTemplate api calls.
I/O error on POST request for "https://example.com/api": Software caused connection abort: socket write error; nested exception is javax.net.ssl.SSLException: Software caused connection abort: socket write error
I/O error on POST request for "https://example.com/api": url:443 failed to respond; nested exception is org.apache.http.NoHttpResponseException: url:443 failed to respond
Above exceptions are coming on GET and POST methods
After 5 days when the above mentioned changes were rolled back, these 2 Exceptions have stopped getting generated
RestTemplate Configuration Code:
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder)
throws NoSuchAlgorithmException, KeyManagementException {
RequestConfig requestConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD_STRICT).build();
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
}
}};
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
CloseableHttpClient httpClient = HttpClients.custom()
.setSSLContext(sslContext)
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.setDefaultRequestConfig(requestConfig)
.build();
HttpComponentsClientHttpRequestFactory customRequestFactory = new HttpComponentsClientHttpRequestFactory();
customRequestFactory.setHttpClient(httpClient);
RestTemplate restTemplate = builder
.requestFactory(
() -> customRequestFactory)
.build();
return restTemplate;
}
RestTemplate code to make api calls. Exception occurs on restTemplate.exchange line
ResponseEntity<String> result = null;
parametersMap.add("Configuration", configuration);
parametersMap.add("MultipartFiles", new FileSystemResource(path));
HttpEntity<?> entity = new HttpEntity<Object>(parametersMap, headers);
result = restTemplate.exchange(saveAttURL, HttpMethod.POST, entity, String.class);
SSLException Stacktrace:
ERROR c.c.s.service.RestServiceImpl - I/O error on POST request for "https://example.com/testapp/app/examplecall": Software caused connection abort: socket write error; nested exception is javax.net.ssl.SSLException: Software caused connection abort: socket write error
org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://example.com/testapp/app/examplecall": Software caused connection abort: socket write error; nested exception is javax.net.ssl.SSLException: Software caused connection abort: socket write error
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:785)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:711)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:602)
at com.company.scheduler.service.RestServiceImpl.saveAttachmentDocuments(RestServiceImpl.java:691)
at com.company.scheduler.service.RestServiceImpl.moveSftpFilesToS3(RestServiceImpl.java:654)
at com.company.scheduler.service.RestServiceImpl$$FastClassBySpringCGLIB$$c0b64f17.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763)
at org.springframework.retry.interceptor.RetryOperationsInterceptor$1.doWithRetry(RetryOperationsInterceptor.java:97)
at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:329)
at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:225)
at org.springframework.retry.interceptor.RetryOperationsInterceptor.invoke(RetryOperationsInterceptor.java:122)
at org.springframework.retry.annotation.AnnotationAwareRetryOperationsInterceptor.invoke(AnnotationAwareRetryOperationsInterceptor.java:160)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708)
at com.company.scheduler.service.RestServiceImpl$$EnhancerBySpringCGLIB$$efca1c4f.moveSftpFilesToS3(<generated>)
at com.company.scheduler.service.IntroServiceImpl.callService(IntroServiceImpl.java:245)
at com.company.scheduler.service.IntroServiceImpl.start(IntroServiceImpl.java:86)
at com.company.scheduler.service.IntroServiceImpl.startService(IntroServiceImpl.java:72)
at com.company.IntroServiceApplication.cronEmailIntroService(IntroServiceApplication.java:49)
at sun.reflect.GeneratedMethodAccessor66.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:95)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: javax.net.ssl.SSLException: Software caused connection abort: socket write error
at sun.security.ssl.Alert.createSSLException(Alert.java:127)
at sun.security.ssl.TransportContext.fatal(TransportContext.java:324)
at sun.security.ssl.TransportContext.fatal(TransportContext.java:267)
at sun.security.ssl.TransportContext.fatal(TransportContext.java:262)
at sun.security.ssl.SSLSocketImpl$AppOutputStream.write(SSLSocketImpl.java:979)
at org.apache.http.impl.io.SessionOutputBufferImpl.streamWrite(SessionOutputBufferImpl.java:124)
at org.apache.http.impl.io.SessionOutputBufferImpl.write(SessionOutputBufferImpl.java:160)
at org.apache.http.impl.io.ContentLengthOutputStream.write(ContentLengthOutputStream.java:113)
at org.apache.http.entity.ByteArrayEntity.writeTo(ByteArrayEntity.java:112)
at org.apache.http.impl.DefaultBHttpClientConnection.sendRequestEntity(DefaultBHttpClientConnection.java:156)
at org.apache.http.impl.conn.CPoolProxy.sendRequestEntity(CPoolProxy.java:152)
at org.apache.http.protocol.HttpRequestExecutor.doSendRequest(HttpRequestExecutor.java:238)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:123)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
at org.springframework.http.client.HttpComponentsClientHttpRequest.executeInternal(HttpComponentsClientHttpRequest.java:87)
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:66)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:776)
... 35 common frames omitted
Suppressed: java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111)
at java.net.SocketOutputStream.write(SocketOutputStream.java:155)
at sun.security.ssl.SSLSocketOutputRecord.encodeAlert(SSLSocketOutputRecord.java:81)
at sun.security.ssl.TransportContext.fatal(TransportContext.java:355)
... 57 common frames omitted
Caused by: java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111)
at java.net.SocketOutputStream.write(SocketOutputStream.java:155)
at sun.security.ssl.SSLSocketOutputRecord.deliver(SSLSocketOutputRecord.java:319)
at sun.security.ssl.SSLSocketImpl$AppOutputStream.write(SSLSocketImpl.java:974)
... 54 common frames omitted
NoHttpResponseException Stacktrace:
POST request for "https://example.com/testapp/app/eform/examplecall": example.com:443 failed to respond; nested exception is org.apache.http.NoHttpResponseException: example.com:443 failed to respond
2023-06-12 12:25:48,090 300986130 [scheduling-1] ERROR c.c.s.service.IntroServiceImpl - Cannot locate recovery method; nested exception is java.lang.Exception: org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://example.com/testapp/app/eform/examplecall": example.com:443 failed to respond; nested exception is org.apache.http.NoHttpResponseException: example.com:443 failed to respond
org.springframework.retry.ExhaustedRetryException: Cannot locate recovery method; nested exception is java.lang.Exception: org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://example.com/testapp/app/eform/examplecall": example.com:443 failed to respond; nested exception is org.apache.http.NoHttpResponseException: example.com:443 failed to respond
at org.springframework.retry.annotation.RecoverAnnotationRecoveryHandler.recover(RecoverAnnotationRecoveryHandler.java:76)
at org.springframework.retry.interceptor.RetryOperationsInterceptor$ItemRecovererCallback.recover(RetryOperationsInterceptor.java:157)
at org.springframework.retry.support.RetryTemplate.handleRetryExhausted(RetryTemplate.java:539)
at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:387)
at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:225)
at org.springframework.retry.interceptor.RetryOperationsInterceptor.invoke(RetryOperationsInterceptor.java:122)
at org.springframework.retry.annotation.AnnotationAwareRetryOperationsInterceptor.invoke(AnnotationAwareRetryOperationsInterceptor.java:160)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708)
at com.company.scheduler.service.RestServiceImpl$$EnhancerBySpringCGLIB$$efca1c4f.introduceWI(<generated>)
at com.company.scheduler.service.IntroServiceImpl.callApi(IntroServiceImpl.java:743)
at com.company.scheduler.service.IntroServiceImpl.callService(IntroServiceImpl.java:239)
at com.company.scheduler.service.IntroServiceImpl.start(IntroServiceImpl.java:86)
at com.company.scheduler.service.IntroServiceImpl.startService(IntroServiceImpl.java:72)
at com.company.IntroServiceApplication.cronEmailIntroService(IntroServiceApplication.java:49)
at sun.reflect.GeneratedMethodAccessor66.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:95)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.Exception: org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://example.com/testapp/app/eform/examplecall": example.com:443 failed to respond; nested exception is org.apache.http.NoHttpResponseException: example.com:443 failed to respond
at com.company.scheduler.service.RestServiceImpl.introduceWI(RestServiceImpl.java:602)
at com.company.scheduler.service.RestServiceImpl$$FastClassBySpringCGLIB$$c0b64f17.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763)
at org.springframework.retry.interceptor.RetryOperationsInterceptor$1.doWithRetry(RetryOperationsInterceptor.java:97)
at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:329)
... 25 common frames omitted
Caused by: org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://example.com/testapp/app/eform/examplecall": example.com:443 failed to respond; nested exception is org.apache.http.NoHttpResponseException: example.com:443 failed to respond
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:785)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:711)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:602)
at com.company.scheduler.service.RestServiceImpl.introduceWI(RestServiceImpl.java:583)
... 32 common frames omitted
Caused by: org.apache.http.NoHttpResponseException: example.com:443 failed to respond
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:141)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:56)
at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259)
at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163)
at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:157)
at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
at org.springframework.http.client.HttpComponentsClientHttpRequest.executeInternal(HttpComponentsClientHttpRequest.java:87)
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:66)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:776)
... 35 common frames omitted
- What can cause intermittent exceptions after enabling cipher suites in Wildfly and is there a way to resolve the Exceptions by changing code/configuration.
- Is there any other way (without changing java code/Wildfly configuration) to resolve the vulnerability: Weak SSL/TLS Key Exchange on port 443
Thank You