You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@hc.apache.org by Joseph Simone <js...@aip.com> on 2022/02/02 22:36:56 UTC

SHA-1 vulnerabilty

In which version of httpclient would
'SHA-1' hash algorithm used at SSLContextBuilder.java
Be fixed?
Thanks.


Re: SHA-1 vulnerabilty

Posted by Gary Gregory <ga...@gmail.com>.
This information is useless :-(

Pay close notice to:

The code:
org.infoarmor.application.config.HttpClientConfiguration#sslContext(), line
170
...obtained a handle to the hashing algorithm seen here, which is
considered insecure:
digest = java.security.MessageDigest.getInstance("SHA-1")


What does this have to do with our project? Is org.infoarmor your own code?
Another library? Whose?

Gary


On Thu, Feb 3, 2022 at 12:57 PM Joseph Simone <js...@aip.com> wrote:

> Hi Gary,
> Thanks for replying.  Let me explain in more detail.
>
> We are using Contrast Security (see https://www.contrastsecurity.com/ )
> to scan our API service for security vulnerabilities.
> Contrast Security is reporting a vulnerability pointing into the  http
> client library at the class SSLContextBuilder.
>
> This is what Contrast Security is reporting:
> ----------------------
> The code:
> org.infoarmor.application.config.HttpClientConfiguration#sslContext(),
> line 170
> ...obtained a handle to the hashing algorithm seen here, which is
> considered insecure:
> digest = java.security.MessageDigest.getInstance("SHA-1")
>
> What's the risk?
> The hashing algorithm used, SHA-1, has been found by researchers to be
> unsafe for protecting sensitive data with today's technology.
> ----------------------
>
> I have tried using httpclient 4.5.13 throughout all our dependency tree
> but am still seeing the vulnerability reported.
> My next attempt was to exclude all references to the version 4 code and
> include only version 5.1.3 code (GA latest).  The problem I encountered,
> because we are using Spring Boot 2.2.13 - an old version - was to get the
> http configuration code we have to compile with the new version 5 of
> httpclient (org.apache.hc.client5.http.* ).  I can't get it to compile.
> Why?  The Spring boot class HttpComponentsMessageSender is looking for the
> version 4 httpclient and not the version 5.
>
> So back to httpclient 4.5.13 as a dependency.  At least that compiles and
> executes.
>
> So now I am thinking --- How can I tell the http client 4 code to just use
> SHA-2 as a hashing algorithm instead of SHA-1?   There should be a way to
> specify that in the security.properties file.
>
> Is this the correct way to proceed or should I set the SHA-2 hashing
> algorithm in out config code?  Why would SHA-1 be the default in 4.5.13 if
> it is insecure?
>
> Thanks for your help.  It is greatly appreciated.
>
> Joe
>
>
>
> On 2/2/22, 6:44 PM, "Gary Gregory" <ga...@gmail.com> wrote:
>
>     Can you be more specific?
>
>     Gary
>
>     On Wed, Feb 2, 2022, 17:37 Joseph Simone <js...@aip.com> wrote:
>
>     > In which version of httpclient would
>     > 'SHA-1' hash algorithm used at SSLContextBuilder.java
>     > Be fixed?
>     > Thanks.
>     >
>     >
>
>

Re: SHA-1 vulnerabilty

Posted by Joseph Simone <js...@aip.com>.
Thanks for your assistance Shawn.  I will follow-up on the cert and see where that leads.
Regards,
joe

On 2/5/22, 12:23 AM, "Shawn Heisey" <ap...@elyograg.org> wrote:

    On 2/4/2022 1:15 PM, Joseph Simone wrote:
    > Maybe we got started off with the wrong details here.
    > How or where can I set the MessageDigest to SHA-256 ...
    > 
    > MessageDigest safeDigester = MessageDigest.getInstance("SHA-256"); // Safe!
    > 
    > Whatever the default is, it seems to be insecure.  I think the problem is a simple matter on my side of missing an httpclient  configuration setting.

    If I'm not mistaken (and I very well could be) ... that refers to the 
    details in the SSL certificate.  Chances are that the certificate on the 
    website you're contacting is using the less secure hashing algorithm. 
    Therefore the code that uses the certificate will also be using SHA1.

    First hit on a google search.  I have no personal connection to 
    digicert, though I do have a friend who works there:

    https://urldefense.com/v3/__https://www.digicert.com/faq/sha2/transitioning-to-sha-2.htm__;!!P0m1g9ywEA!cYv40Oqe8S7kqE3gpGpGXMALs9duRN3kHNjeo6vWDQ_8hNZ4Ghbb3HTfBxE$ 

    If the certificate is not within your control, then you need to talk to 
    whoever manages the website and ask them to fix their cert.

    If the cert IS under your control:  In some cases, the hashing algorithm 
    of the final certificate will be determined from a certificate signing 
    request that you provide to the CA.  But I think that most public CAs 
    these days do not pay attention to anything in a CSR except the public 
    key, and if that is the case, the hashing algorithm will be entirely up 
    to the CA.

    If this is a client cert and not a server cert, then chances are that it 
    is under your control.  If you run your own CA, you should talk to the 
    vendor or project for that software about how to have it issue SHA-2 
    certificates.  If you use a public CA for client certs, ask them how to 
    obtain upgraded certs.

    Thanks,
    Shawn

    ---------------------------------------------------------------------
    To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
    For additional commands, e-mail: dev-help@hc.apache.org



Re: SHA-1 vulnerabilty

Posted by Mark Mielke <ma...@gmail.com>.
Also, SHA-1 is not automatically "unsafe", and SHA-256 automatically
"safe". Everything has a context, and the context is missing here.
Shawn provides a context, that likely shows that SHA-1 is in use, and
providing better than no security, and less than latest
recommendations, which is the reality of much of the web today. So you
can dislike that things aren't perfect, but it takes more than a
one-line code change to fix such a problem. In the context of
HttpComponents, there is no evidence provided that HttpComponents is
doing anything wrong. It's doing what it is supposed to, or if not -
the original reporter should propose what they think the problem is,
and why they think it should be fixed. This will likely be rejected,
as once the discussion gets into the real problem, the problem is
likely outside the HttpComponents project entirely, as Shawn helpfully
describes.

On Sat, Feb 5, 2022 at 12:23 AM Shawn Heisey <ap...@elyograg.org> wrote:
> On 2/4/2022 1:15 PM, Joseph Simone wrote:
> > Maybe we got started off with the wrong details here.
> > How or where can I set the MessageDigest to SHA-256 ...
> >
> > MessageDigest safeDigester = MessageDigest.getInstance("SHA-256"); // Safe!
> >
> > Whatever the default is, it seems to be insecure.  I think the problem is a simple matter on my side of missing an httpclient  configuration setting.
>
> If I'm not mistaken (and I very well could be) ... that refers to the
> details in the SSL certificate.  Chances are that the certificate on the
> website you're contacting is using the less secure hashing algorithm.
> Therefore the code that uses the certificate will also be using SHA1.
>
> First hit on a google search.  I have no personal connection to
> digicert, though I do have a friend who works there:
>
> https://www.digicert.com/faq/sha2/transitioning-to-sha-2.htm
>
> If the certificate is not within your control, then you need to talk to
> whoever manages the website and ask them to fix their cert.
>
> If the cert IS under your control:  In some cases, the hashing algorithm
> of the final certificate will be determined from a certificate signing
> request that you provide to the CA.  But I think that most public CAs
> these days do not pay attention to anything in a CSR except the public
> key, and if that is the case, the hashing algorithm will be entirely up
> to the CA.
>
> If this is a client cert and not a server cert, then chances are that it
> is under your control.  If you run your own CA, you should talk to the
> vendor or project for that software about how to have it issue SHA-2
> certificates.  If you use a public CA for client certs, ask them how to
> obtain upgraded certs.

-- 
Mark Mielke <ma...@gmail.com>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org


Re: SHA-1 vulnerabilty

Posted by Shawn Heisey <ap...@elyograg.org>.
On 2/4/2022 1:15 PM, Joseph Simone wrote:
> Maybe we got started off with the wrong details here.
> How or where can I set the MessageDigest to SHA-256 ...
> 
> MessageDigest safeDigester = MessageDigest.getInstance("SHA-256"); // Safe!
> 
> Whatever the default is, it seems to be insecure.  I think the problem is a simple matter on my side of missing an httpclient  configuration setting.

If I'm not mistaken (and I very well could be) ... that refers to the 
details in the SSL certificate.  Chances are that the certificate on the 
website you're contacting is using the less secure hashing algorithm. 
Therefore the code that uses the certificate will also be using SHA1.

First hit on a google search.  I have no personal connection to 
digicert, though I do have a friend who works there:

https://www.digicert.com/faq/sha2/transitioning-to-sha-2.htm

If the certificate is not within your control, then you need to talk to 
whoever manages the website and ask them to fix their cert.

If the cert IS under your control:  In some cases, the hashing algorithm 
of the final certificate will be determined from a certificate signing 
request that you provide to the CA.  But I think that most public CAs 
these days do not pay attention to anything in a CSR except the public 
key, and if that is the case, the hashing algorithm will be entirely up 
to the CA.

If this is a client cert and not a server cert, then chances are that it 
is under your control.  If you run your own CA, you should talk to the 
vendor or project for that software about how to have it issue SHA-2 
certificates.  If you use a public CA for client certs, ask them how to 
obtain upgraded certs.

Thanks,
Shawn

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org


Re: SHA-1 vulnerabilty

Posted by Michael Osipov <mi...@apache.org>.
Am 2022-02-04 um 21:15 schrieb Joseph Simone:
> Maybe we got started off with the wrong details here.
> How or where can I set the MessageDigest to SHA-256 ...
> 
> MessageDigest safeDigester = MessageDigest.getInstance("SHA-256"); // Safe!
> 
> Whatever the default is, it seems to be insecure.  I think the problem is a simple matter on my side of missing an httpclient  configuration setting.

You are still wrong here, there is no viable code in Core or Client 
which uses any MessageDigest. I don't understand your expectation here.

M

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org


Re: SHA-1 vulnerabilty

Posted by Joseph Simone <js...@aip.com>.
Maybe we got started off with the wrong details here.
How or where can I set the MessageDigest to SHA-256 ...

MessageDigest safeDigester = MessageDigest.getInstance("SHA-256"); // Safe!

Whatever the default is, it seems to be insecure.  I think the problem is a simple matter on my side of missing an httpclient  configuration setting.

Here is my httpclient 4.5.13 configuration code:

Any help is greatly appreciated.
Joe

-------------------------------------------------------------------------------------------------------------

@Configuration
public class HttpClientConfiguration {

    private final Integer connectionTimeout;
    private final Integer connectionRequestTimeout;
    private final Integer socketTimeout;
    private final Boolean sslVerifyHostname;
    private final String sslKeyStorePassword;
    private final String sslKeyPassword;
    private final String sslTrustStorePassword;
    private final String username;
    private final String password;
    private final String transunionSslKeyStoreBytes;
    private final String transunionSslKeyStoreCertFileName;
    private final String transunionSslTrustStoreBytes;
    private final String transunionSslTrustStoreCertFileName;
    private final boolean sslMutualAuth;
    private final String sslKeyStore;
    private final String sslTrustStore;

    public HttpClientConfiguration(
        @Value("${broker.operation.connection-timeout:${transunion.api.connection-timeout:60000}}")
            Integer connectionTimeout,
        @Value("${broker.operation.connection-request-timeout:${transunion.api.connection-request-timeout:60000}}")
            Integer connectionRequestTimeout,
        @Value("${broker.operation.socket-timeout:${transunion.api.socket-timeout:60000}}")
            Integer socketTimeout,
        @Value("${broker.operation.client.ssl.verify-hostname:${transunion.api.ssl.verify-hostname:false}}")
            Boolean sslVerifyHostname,
        @Value("${broker.operation.client.ssl.key-store-password:${transunion.api.ssl.key-store-password:}}")
            String sslKeyStorePassword,
        @Value("${broker.operation.client.ssl.key-password:${transunion.api.ssl.key-password:}}")
            String sslKeyPassword,
        @Value("${broker.operation.client.ssl.trust-store-password:${transunion.api.ssl.trust-store-password:}}")
            String sslTrustStorePassword,
        @Value("${transunion.api.username}")
            String username,
        @Value("${transunion.api.password}")
            String password,
        @Value("${broker.operation.client.ssl.key-store-bytes:${transunion.api.ssl.key-store:}}")
            String transunionSslKeyStoreBytes,
        @Value("${broker.operation.client.ssl.key-store-name:${transunion.api.ssl.key-store-name:}}")
            String transunionSslKeyStoreCertFileName,
        @Value("${broker.operation.client.ssl.trust-store-bytes:${transunion.api.ssl.trust-store:}}")
            String transunionSslTrustStoreBytes,
        @Value("${broker.operation.client.ssl.trust-store-name:${transunion.api.ssl.trust-store-name:}}")
            String transunionSslTrustStoreCertFileName,
        @Value("${broker.operation.client.ssl.mutual-auth:${transunion.api.ssl.mutual-auth:false}}")
            boolean sslMutualAuth) {
        this.connectionTimeout = connectionTimeout;
        this.connectionRequestTimeout = connectionRequestTimeout;
        this.socketTimeout = socketTimeout;
        this.sslVerifyHostname = sslVerifyHostname;
        this.sslKeyStorePassword = sslKeyStorePassword;
        this.sslKeyPassword = sslKeyPassword;
        this.sslTrustStorePassword = sslTrustStorePassword;
        this.username = username;
        this.password = password;
        this.transunionSslKeyStoreBytes = transunionSslKeyStoreBytes;
        this.transunionSslKeyStoreCertFileName = transunionSslKeyStoreCertFileName;
        this.transunionSslTrustStoreBytes = transunionSslTrustStoreBytes;
        this.transunionSslTrustStoreCertFileName = transunionSslTrustStoreCertFileName;
        this.sslMutualAuth = sslMutualAuth;
        this.sslKeyStore = transunionSslKeyStore();
        this.sslTrustStore = transunionSslTrustStore();
    }

    public HttpComponentsMessageSender httpComponentsMessageSender() {
        HttpComponentsMessageSender httpComponentsMessageSender = new HttpComponentsMessageSender();

        try {
            httpComponentsMessageSender.setHttpClient(httpClient());
        } catch (Exception exception) {
            LogHelper.logError(exception, "DIP issued an Error! HTTP Client Handshake failed.",
                HttpClientConfiguration.class);
            throw new RuntimeException(exception);
        }

        return httpComponentsMessageSender;
    }

    public HttpClient httpClient() throws Exception {

        RequestConfig requestConfig = RequestConfig.custom()
            .setConnectTimeout(connectionTimeout)
            .setConnectionRequestTimeout(connectionRequestTimeout)
            .setSocketTimeout(socketTimeout).build();

        if (sslMutualAuth) {
            return HttpClientBuilder.create()
                .setSSLSocketFactory(sslConnectionSocketFactory())
                .setDefaultRequestConfig(requestConfig)
                .setDefaultCredentialsProvider(credentialsProvider())
                .addInterceptorFirst(new HttpRequestInterceptor() {

                    @Override
                    public void process(HttpRequest request, HttpContext context) throws HttpException, IOException {
                        request.removeHeaders(HttpHeaders.CONTENT_LENGTH);
                        request.removeHeaders(HttpHeaders.TRANSFER_ENCODING);
                        LogHelper.logDebug("Http Request Headers= " + Arrays.toString(request.getAllHeaders()),
                            HttpClientConfiguration.class);
                    }
                })
                .build();
        }

        return HttpClientBuilder.create()
            .setDefaultRequestConfig(requestConfig)
            .setDefaultCredentialsProvider(credentialsProvider())
            .addInterceptorFirst(new HttpRequestInterceptor() {

                @Override
                public void process(HttpRequest request, HttpContext context) throws HttpException, IOException {
                    request.removeHeaders(HttpHeaders.CONTENT_LENGTH);
                    request.removeHeaders(HttpHeaders.TRANSFER_ENCODING);
                    LogHelper.logDebug("Http Request Headers= " + Arrays.toString(request.getAllHeaders()),
                        HttpClientConfiguration.class);
                }
            })
            .build();
    }

    @ConditionalOnExpression(" '${broker.operation.client.ssl.mutual-auth:${transunion.api.ssl.mutual-auth:false}}'.equals('true') ")
    public SSLConnectionSocketFactory sslConnectionSocketFactory() throws Exception {

        if (sslVerifyHostname) {
            return new SSLConnectionSocketFactory(sslContext());
        } else {
            // Turn off host-name verification
            return new SSLConnectionSocketFactory(sslContext(), NoopHostnameVerifier.INSTANCE);
        }
    }

    @ConditionalOnExpression(" '${broker.operation.client.ssl.mutual-auth:${transunion.api.ssl.mutual-auth:false}}'.equals('true') ")
    public SSLContext sslContext() throws Exception {
        return SSLContextBuilder.create()
            .loadKeyMaterial(ResourceUtils.getFile(sslKeyStore), sslKeyStorePassword.toCharArray(), sslKeyPassword.toCharArray())
            .loadTrustMaterial(ResourceUtils.getFile(sslTrustStore), sslTrustStorePassword.toCharArray()).build();
    }

    public CredentialsProvider credentialsProvider() {

        BasicCredentialsProvider basicCredentialsProvider = new BasicCredentialsProvider();
        basicCredentialsProvider.setCredentials(AuthScope.ANY, usernamePasswordCredentials());
        return basicCredentialsProvider;
    }

    public UsernamePasswordCredentials usernamePasswordCredentials() {
        return new UsernamePasswordCredentials(username, password);
    }

    public String transunionSslKeyStore() {
        return createCertAndGetPath(transunionSslKeyStoreBytes, transunionSslKeyStoreCertFileName);
    }

    public String transunionSslTrustStore() {
        return createCertAndGetPath(transunionSslTrustStoreBytes, transunionSslTrustStoreCertFileName);
    }

    private String createCertAndGetPath(String trustStoreCert, String certName) {
        if (!sslMutualAuth) {
            return "";
        }
        String path = null;
        if (trustStoreCert != null && !"".equals(trustStoreCert.trim())) {
            try {
                File certFile = File.createTempFile(certName, ".jks");
                FileOutputStream writer = new FileOutputStream(certFile);
                writer.write(Base64.getDecoder().decode(trustStoreCert.replaceAll(System.lineSeparator(), "")));
                writer.close();
                path = certFile.getAbsolutePath();
                LogHelper.logInfo("Path created successfully: " + path, HttpClientConfiguration.class);
            } catch (IOException e) {
                LogHelper.logError("Method: trustStoreCertFile path. Error: " + Arrays.toString(e.getStackTrace()),
                    HttpClientConfiguration.class);
                throw new RuntimeException();
            }
        }
        LogHelper.logInfo("Method: trustStoreCertFile path. Path: " + path, HttpClientConfiguration.class);
        return path;
    }

}



    ---------------------------------------------------------------------
    To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
    For additional commands, e-mail: dev-help@hc.apache.org



Re: SHA-1 vulnerabilty

Posted by Michael Osipov <mi...@apache.org>.
Am 2022-02-03 um 18:56 schrieb Joseph Simone:
> Hi Gary,
> Thanks for replying.  Let me explain in more detail.
> 
> We are using Contrast Security (see https://www.contrastsecurity.com/ ) to scan our API service for security vulnerabilities.
> Contrast Security is reporting a vulnerability pointing into the  http client library at the class SSLContextBuilder.
> 
> This is what Contrast Security is reporting:
> ----------------------
> The code:
> org.infoarmor.application.config.HttpClientConfiguration#sslContext(), line 170
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Wrong forum, pal. This is not our software.


Because crappy security makes a contrast!

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org


Re: SHA-1 vulnerabilty

Posted by Joseph Simone <js...@aip.com>.
Hi Gary,
Thanks for replying.  Let me explain in more detail.

We are using Contrast Security (see https://www.contrastsecurity.com/ ) to scan our API service for security vulnerabilities.
Contrast Security is reporting a vulnerability pointing into the  http client library at the class SSLContextBuilder.

This is what Contrast Security is reporting:
----------------------
The code:
org.infoarmor.application.config.HttpClientConfiguration#sslContext(), line 170
...obtained a handle to the hashing algorithm seen here, which is considered insecure:
digest = java.security.MessageDigest.getInstance("SHA-1")

What's the risk?
The hashing algorithm used, SHA-1, has been found by researchers to be unsafe for protecting sensitive data with today's technology.
----------------------

I have tried using httpclient 4.5.13 throughout all our dependency tree but am still seeing the vulnerability reported.
My next attempt was to exclude all references to the version 4 code and include only version 5.1.3 code (GA latest).  The problem I encountered, because we are using Spring Boot 2.2.13 - an old version - was to get the http configuration code we have to compile with the new version 5 of httpclient (org.apache.hc.client5.http.* ).  I can't get it to compile.  Why?  The Spring boot class HttpComponentsMessageSender is looking for the version 4 httpclient and not the version 5.

So back to httpclient 4.5.13 as a dependency.  At least that compiles and executes.

So now I am thinking --- How can I tell the http client 4 code to just use SHA-2 as a hashing algorithm instead of SHA-1?   There should be a way to specify that in the security.properties file.

Is this the correct way to proceed or should I set the SHA-2 hashing algorithm in out config code?  Why would SHA-1 be the default in 4.5.13 if it is insecure?

Thanks for your help.  It is greatly appreciated.

Joe



On 2/2/22, 6:44 PM, "Gary Gregory" <ga...@gmail.com> wrote:

    Can you be more specific?

    Gary

    On Wed, Feb 2, 2022, 17:37 Joseph Simone <js...@aip.com> wrote:

    > In which version of httpclient would
    > 'SHA-1' hash algorithm used at SSLContextBuilder.java
    > Be fixed?
    > Thanks.
    >
    >


Re: SHA-1 vulnerabilty

Posted by Gary Gregory <ga...@gmail.com>.
Can you be more specific?

Gary

On Wed, Feb 2, 2022, 17:37 Joseph Simone <js...@aip.com> wrote:

> In which version of httpclient would
> 'SHA-1' hash algorithm used at SSLContextBuilder.java
> Be fixed?
> Thanks.
>
>