fortify / FortifyVulnerabilityExporter

Export Fortify vulnerability data to GitHub, GitLab, SonarQube and more
Other
24 stars 8 forks source link

Errors with SSC that uses self signed certs #19

Closed hopenbr closed 3 years ago

hopenbr commented 3 years ago

When trying to export SSC SAST to Gitlab, and our SSC is using a self-signed cert you get the below error

to see jobs details look at https://github.com/fortify/FortifyVulnerabilityExporter/issues/18

Using docker image sha256:68b7979a3875576df43e76e90b483634102afc63bc2cd5df21e737079514e7b5 for docker.jfrog.lfg.com/fortifydocker/fortify-vulnerability-exporter:latest_rc with digest docker.jfrog.lfg.com/fortifydocker/fortify-vulnerability-exporter@sha256:cbdc3a54cc2d8f4c7ed4b97adac35cb6c875b74f449904d58cc909f18e81bd13 ...
01:36:24.003 [main] DEBUG com.fortify.util.spring.boot.container.PopulateContainerDirs - Populate container directories enabled: true
01:36:24.007 [main] DEBUG com.fortify.util.spring.boot.container.PopulateContainerDirs - Checking whether container directories need to be initialized
01:36:24.013 [main] DEBUG com.fortify.util.spring.boot.container.PopulateContainerDirs - Target path /config is present: true
  ______         _   _  __                                  
 |  ____|       | | (_)/ _|                                 
 | |__ ___  _ __| |_ _| |_ _   _                            
 |  __/ _ \| '__| __| |  _| | | |                           
 | | | (_) | |  | |_| | | | |_| |                           
 |_|  \___/|_|   \__|_|_|  \__, |                           
 __      __    _            __/ |     _     _ _ _ _         
 \ \    / /   | |          |___/     | |   (_) (_) |        
  \ \  / /   _| |_ __   ___ _ __ __ _| |__  _| |_| |_ _   _ 
   \ \/ / | | | | '_ \ / _ \ '__/ _` | '_ \| | | | __| | | |
    \  /| |_| | | | | |  __/ | | (_| | |_) | | | | |_| |_| |
     \/  \__,_|_|_| |_|\___|_|  \__,_|_.__/|_|_|_|\__|\__, |
  ______                       _                       __/ |
 |  ____|                     | |                     |___/ 
 | |__  __  ___ __   ___  _ __| |_ ___ _ __                 
 |  __| \ \/ / '_ \ / _ \| '__| __/ _ \ '__|                
 | |____ >  <| |_) | (_) | |  | ||  __/ |                   
 |______/_/\_\ .__/ \___/|_|   \__\___|_|                   
             | |                                            
             |_|                                            
2021-04-14 01:36:24.697  INFO 1 --- [           main] e.p.PluginConfigEnvironmentPostProcessor : Loaded 11 plugin configuration files
2021-04-14 01:36:24.701  INFO 1 --- [           main] c.f.v.FortifyVulnerabilityExporter       : Starting FortifyVulnerabilityExporter v0.20210413.113124-dev_main using Java 11.0.10 on runner-w42yknzx-project-11312-concurrent-0 with PID 1 (/app/classpath/FortifyVulnerabilityExporter-0.20210413.113124-dev_main.jar started by root in /)
2021-04-14 01:36:24.702  INFO 1 --- [           main] c.f.v.FortifyVulnerabilityExporter       : The following profiles are active: default
2021-04-14 01:36:25.467  INFO 1 --- [           main] c.f.v.FortifyVulnerabilityExporter       : Started FortifyVulnerabilityExporter in 1.255 seconds (JVM running for 1.687)
2021-04-14 01:36:26.783 ERROR 1 --- [           main] o.s.boot.SpringApplication               : Application run failed
java.lang.IllegalStateException: Failed to execute CommandLineRunner
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:809) ~[spring-boot-2.4.4.jar:2.4.4]
    at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:790) ~[spring-boot-2.4.4.jar:2.4.4]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:333) ~[spring-boot-2.4.4.jar:2.4.4]
    at com.fortify.vulnexport.FortifyVulnerabilityExporter.main(FortifyVulnerabilityExporter.java:39) ~[FortifyVulnerabilityExporter-0.20210413.113124-dev_main.jar:0.20210413.113124-dev_main]
Caused by: java.lang.RuntimeException: Exception in call() method
    at com.fortify.util.log4j.LogMaskingHelper$AbstractMasker.on(LogMaskingHelper.java:117) ~[common-log-5.10.jar:na]
    at com.fortify.client.ssc.connection.SSCTokenFactoryUserCredentials.performTokenRequest(SSCTokenFactoryUserCredentials.java:111) ~[FortifyVulnerabilityExporter-plugin-from-ssc.jar:na]
    at com.fortify.client.ssc.connection.SSCTokenFactoryUserCredentials.getToken(SSCTokenFactoryUserCredentials.java:98) ~[FortifyVulnerabilityExporter-plugin-from-ssc.jar:na]
    at com.fortify.client.ssc.connection.SSCAuthenticatingRestConnection.updateBuilder(SSCAuthenticatingRestConnection.java:92) ~[FortifyVulnerabilityExporter-plugin-from-ssc.jar:na]
    at com.fortify.util.rest.connection.AbstractRestConnection.executeRequest(AbstractRestConnection.java:222) ~[common-rest-5.10.jar:na]
    at com.fortify.util.rest.connection.AbstractRestConnection.executeRequestWithFinalizedWebTarget(AbstractRestConnection.java:186) ~[common-rest-5.10.jar:na]
    at com.fortify.util.rest.connection.AbstractRestConnection.executeRequest(AbstractRestConnection.java:167) ~[common-rest-5.10.jar:na]
    at com.fortify.util.rest.connection.AbstractRestConnection.executeRequest(AbstractRestConnection.java:152) ~[common-rest-5.10.jar:na]
    at com.fortify.util.rest.query.AbstractRestConnectionQuery.executeRequest(AbstractRestConnectionQuery.java:141) ~[common-rest-5.10.jar:na]
    at com.fortify.util.rest.query.AbstractRestConnectionQuery.processSingleRequest(AbstractRestConnectionQuery.java:209) ~[common-rest-5.10.jar:na]
    at com.fortify.util.rest.query.AbstractRestConnectionQuery.processAll(AbstractRestConnectionQuery.java:200) ~[common-rest-5.10.jar:na]
    at com.fortify.util.rest.query.AbstractRestConnectionQuery.processAll(AbstractRestConnectionQuery.java:90) ~[common-rest-5.10.jar:na]
    at com.fortify.util.rest.query.AbstractRestConnectionQuery.processAll(AbstractRestConnectionQuery.java:95) ~[common-rest-5.10.jar:na]
    at com.fortify.vulnexport.from.ssc.FromSSCVulnerabilityLoader$_FromSSCVulnerabilityLoader.run(FromSSCVulnerabilityLoader.java:105) ~[FortifyVulnerabilityExporter-plugin-from-ssc.jar:na]
    at com.fortify.vulnexport.from.ssc.FromSSCVulnerabilityLoader.run(FromSSCVulnerabilityLoader.java:81) ~[FortifyVulnerabilityExporter-plugin-from-ssc.jar:na]
    at com.fortify.vulnexport.FortifyVulnerabilityExporterRunnerFactory.runActiveVulnerabilityLoader(FortifyVulnerabilityExporterRunnerFactory.java:91) ~[FortifyVulnerabilityExporter-0.20210413.113124-dev_main.jar:0.20210413.113124-dev_main]
    at com.fortify.util.spring.boot.scheduler.RunOrSchedule.runOnce(RunOrSchedule.java:68) ~[FortifyVulnerabilityExporter-0.20210413.113124-dev_main.jar:0.20210413.113124-dev_main]
    at com.fortify.util.spring.boot.scheduler.RunOrSchedule.run(RunOrSchedule.java:47) ~[FortifyVulnerabilityExporter-0.20210413.113124-dev_main.jar:0.20210413.113124-dev_main]
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:806) ~[spring-boot-2.4.4.jar:2.4.4]
    ... 3 common frames omitted
Caused by: javax.ws.rs.ProcessingException: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at org.glassfish.jersey.apache.connector.ApacheConnector.apply(ApacheConnector.java:531) ~[jersey-apache-connector-2.33.jar:na]
    at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:297) ~[jersey-client-2.33.jar:na]
    at org.glassfish.jersey.client.JerseyInvocation.lambda$invoke$0(JerseyInvocation.java:630) ~[jersey-client-2.33.jar:na]
    at org.glassfish.jersey.client.JerseyInvocation.call(JerseyInvocation.java:665) ~[jersey-client-2.33.jar:na]
    at org.glassfish.jersey.client.JerseyInvocation.lambda$runInScope$3(JerseyInvocation.java:659) ~[jersey-client-2.33.jar:na]
    at org.glassfish.jersey.internal.Errors.process(Errors.java:292) ~[jersey-common-2.33.jar:na]
    at org.glassfish.jersey.internal.Errors.process(Errors.java:274) ~[jersey-common-2.33.jar:na]
    at org.glassfish.jersey.internal.Errors.process(Errors.java:205) ~[jersey-common-2.33.jar:na]
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:390) ~[jersey-common-2.33.jar:na]
    at org.glassfish.jersey.client.JerseyInvocation.runInScope(JerseyInvocation.java:659) ~[jersey-client-2.33.jar:na]
    at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:629) ~[jersey-client-2.33.jar:na]
    at com.fortify.util.rest.connection.AbstractRestConnection.executeRequest(AbstractRestConnection.java:223) ~[common-rest-5.10.jar:na]
    at com.fortify.client.ssc.connection.SSCTokenFactoryUserCredentials.lambda$performTokenRequest$0(SSCTokenFactoryUserCredentials.java:112) ~[FortifyVulnerabilityExporter-plugin-from-ssc.jar:na]
    at com.fortify.util.log4j.LogMaskingHelper$AbstractMasker.on(LogMaskingHelper.java:115) ~[common-log-5.10.jar:na]
    ... 21 common frames omitted
Caused by: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at java.base/sun.security.ssl.Alert.createSSLException(Unknown Source) ~[na:na]
    at java.base/sun.security.ssl.TransportContext.fatal(Unknown Source) ~[na:na]
    at java.base/sun.security.ssl.TransportContext.fatal(Unknown Source) ~[na:na]
    at java.base/sun.security.ssl.TransportContext.fatal(Unknown Source) ~[na:na]
    at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(Unknown Source) ~[na:na]
    at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.onCertificate(Unknown Source) ~[na:na]
    at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.consume(Unknown Source) ~[na:na]
    at java.base/sun.security.ssl.SSLHandshake.consume(Unknown Source) ~[na:na]
    at java.base/sun.security.ssl.HandshakeContext.dispatch(Unknown Source) ~[na:na]
    at java.base/sun.security.ssl.HandshakeContext.dispatch(Unknown Source) ~[na:na]
    at java.base/sun.security.ssl.TransportContext.dispatch(Unknown Source) ~[na:na]
    at java.base/sun.security.ssl.SSLTransport.decode(Unknown Source) ~[na:na]
    at java.base/sun.security.ssl.SSLSocketImpl.decode(Unknown Source) ~[na:na]
    at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(Unknown Source) ~[na:na]
    at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source) ~[na:na]
    at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source) ~[na:na]
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:436) ~[httpclient-4.5.13.jar:4.5.13]
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:384) ~[httpclient-4.5.13.jar:4.5.13]
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142) ~[httpclient-4.5.13.jar:4.5.13]
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:376) ~[httpclient-4.5.13.jar:4.5.13]
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:393) ~[httpclient-4.5.13.jar:4.5.13]
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236) ~[httpclient-4.5.13.jar:4.5.13]
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186) ~[httpclient-4.5.13.jar:4.5.13]
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89) ~[httpclient-4.5.13.jar:4.5.13]
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) ~[httpclient-4.5.13.jar:4.5.13]
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185) ~[httpclient-4.5.13.jar:4.5.13]
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:72) ~[httpclient-4.5.13.jar:4.5.13]
    at org.glassfish.jersey.apache.connector.ApacheConnector.apply(ApacheConnector.java:483) ~[jersey-apache-connector-2.33.jar:na]
    ... 34 common frames omitted
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at java.base/sun.security.validator.PKIXValidator.doBuild(Unknown Source) ~[na:na]
    at java.base/sun.security.validator.PKIXValidator.engineValidate(Unknown Source) ~[na:na]
    at java.base/sun.security.validator.Validator.validate(Unknown Source) ~[na:na]
    at java.base/sun.security.ssl.X509TrustManagerImpl.validate(Unknown Source) ~[na:na]
    at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(Unknown Source) ~[na:na]
    at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source) ~[na:na]
    ... 58 common frames omitted
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at java.base/sun.security.provider.certpath.SunCertPathBuilder.build(Unknown Source) ~[na:na]
    at java.base/sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source) ~[na:na]
    at java.base/java.security.cert.CertPathBuilder.build(Unknown Source) ~[na:na]
    ... 64 common frames omitted
rsenden commented 3 years ago

At the moment, FortifyVulnerabilityExporter doesn't provide any functionality to configure which certificates are to be trusted. Usually you would just add the certificate to the cacerts file of your JRE, but this is a bit more complicated with a Docker image.

We could potentially add configuration options to FortifyVulnerabilityExporter to handle situations like these, like specifying the path to a certificate to be trusted, or options to disable certificate checks (which would not recommended for a production environment). It may take some time though for us to implement such configuration options, if at all.

Possibly one of the ideas listed below is sufficient to handle self-signed certificates and custom/proprietary root certificates. Please let us know whether any of the options below work for you, we can then add this information to the documentation.

System Properties Set the following environment variable while running the fortifydocker/fortify-vulnerability-exporter image:

JAVA_OPTS=-Djavax.net.ssl.trustStore=/path/to/alternative/cacerts -Djavax.net.ssl.trustStorePassword=changeit

The trust store at /path/to/alternative/cacerts should of course contain your self-signed certificate or proprietary root certificate. For example, this could point to a cacerts file in your GitLab workspace or a standard cacerts file on your GitLab Runner.

Custom Docker Image This option is similar to the traditional method of adding a custom certificate to the cacerts file used by the JRE in the Docker image. You will need to build a custom Docker image and reference this custom image in your pipelines rather than the standard fortifydocker/fortify-vulnerability-exporter image.

Following is an example Dockerfile; your mycert.cer needs to be located in the same directory as your Dockerfile when building the image:

FROM fortifydocker/fortify-vulnerability-exporter:latest_rc
COPY mycert.cer /tmp/mycert.cer
RUN keytool -importcert -cacerts -storepass changeit -noprompt -alias mycert -file /tmp/mycert.cer

Note that this example only works for latest_rc and future releases; older versions require the full path to keytool to be specified and use the Java 8 keytool syntax.

Volume Mapping I don't think this is applicable for a GitLab environment (unless you change your workflow to invoke docker manually to run the image), but you could use something like the following to override the cacerts file included with the Docker image:

docker run -v /path/to/host/cacerts:opt/java/openjdk/lib/security/cacerts fortifydocker/fortify-vulnerability-exporter:latest_rc

Note that if the System properties option listed above works, I think that would be a much better option for specifying an alternative trust store at runtime. The System properties option can be used when you cannot customize volume mappings, and you don't need to know the location of the cacerts file in the Docker image.

hopenbr commented 3 years ago

sorry I missed your message and had to start working hight priority issues at work.

I will get back on this,

hopenbr commented 3 years ago

Okay I got a clean export to gitlab SAST json, by creating our own image that images calls

Custom Docker Image process explained above

next I will trying to get Sonar to work