diff --git a/README.md b/README.md index af5d887e63..d30441ed9b 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,7 @@ The buildpack supports extension through the use of Git repository forking. The * [SkyWalking Agent](docs/framework-sky_walking_agent.md) ([Configuration](docs/framework-sky_walking_agent.md#configuration)) * [Takipi Agent](docs/framework-takipi_agent.md) ([Configuration](docs/framework-takipi_agent.md#configuration)) * [YourKit Profiler](docs/framework-your_kit_profiler.md) ([Configuration](docs/framework-your_kit_profiler.md#configuration)) + * [Checkmarx IAST Agent](docs/framework-checkmarx_iast_agent.md) ([Configuration](docs/framework-checkmarx_iast_agent.md#configuration)) * Standard JREs * [Azul Zulu](docs/jre-zulu_jre.md) ([Configuration](docs/jre-zulu_jre.md#configuration)) * [GraalVM](docs/jre-graal_vm_jre.md) ([Configuration](docs/jre-graal_vm_jre.md#configuration)) diff --git a/config/components.yml b/config/components.yml index 660135685b..3aa2e6ce74 100644 --- a/config/components.yml +++ b/config/components.yml @@ -74,4 +74,5 @@ frameworks: - "JavaBuildpack::Framework::YourKitProfiler" - "JavaBuildpack::Framework::TakipiAgent" - "JavaBuildpack::Framework::JavaSecurity" + - "JavaBuildpack::Framework::CheckmarxIastAgent" - "JavaBuildpack::Framework::JavaOpts" diff --git a/docs/framework-checkmarx_iast_agent.md b/docs/framework-checkmarx_iast_agent.md new file mode 100644 index 0000000000..45a938def6 --- /dev/null +++ b/docs/framework-checkmarx_iast_agent.md @@ -0,0 +1,22 @@ +# Checkmarx IAST Agent Framework +The Checkmarx IAST Agent Framework causes an application to be automatically configured to work with a bound [Checkmarx IAST Service][]. + + + + + +
Detection CriterionExistence of a bound Checkmarx IAST service. The existence of an Checkmarx IAST service is defined by the VCAP_SERVICES payload containing a service named checkmarx-iast. +
+ +## User-Provided Service +When binding Checkmarx IAST using a user-provided service, it must have the name `checkmarx-iast` and the credential payload must include the following entry: + +| Name | Description +| ---- | ----------- +| `server` | The IAST Manager URL + +## Configuration +For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][]. + +[Checkmarx IAST Service]: https://www.checkmarx.com/products/interactive-application-security-testing +[Configuration and Extension]: ../README.md#configuration-and-extension diff --git a/lib/java_buildpack/framework/checkmarx_iast_agent.rb b/lib/java_buildpack/framework/checkmarx_iast_agent.rb new file mode 100644 index 0000000000..e398b57444 --- /dev/null +++ b/lib/java_buildpack/framework/checkmarx_iast_agent.rb @@ -0,0 +1,94 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2020 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'java_buildpack/framework' + +module JavaBuildpack + module Framework + + # Encapsulates the functionality for running with Checkmarx IAST Agent + class CheckmarxIastAgent < JavaBuildpack::Component::BaseComponent + include JavaBuildpack::Util + + # Creates an instance. In addition to the functionality inherited from +BaseComponent+, +@version+ and +@uri+ + # instance variables are exposed. + # + # @param [Hash] context a collection of utilities used by components + def initialize(context) + super(context) + + # Save the IAST server URL in server, if found + service = @application.services.find_service(FILTER, 'server') + @server = service['credentials']['server'].chomp '/' if service + end + + # (see JavaBuildpack::Component::BaseComponent#detect) + def detect + @server + end + + # (see JavaBuildpack::Component::BaseComponent#compile) + def compile + # Download and extract the agent from the IAST server + FileUtils.mkdir_p @droplet.sandbox + # curl --insecure: most IAST servers will use self-signed SSL + shell 'curl --fail --insecure --silent --show-error ' \ + "#{@server}/iast/compilation/download/JAVA -o #{@droplet.sandbox}/cx-agent.zip" + shell "unzip #{@droplet.sandbox}/cx-agent.zip -d #{@droplet.sandbox}" + + # Disable cache (no point, when running in a container) + File.open("#{@droplet.sandbox}/#{OVERRIDE_CONFIG}", 'a') do |file| + file.write("\nenableWeavedClassCache=false\n") + end + end + + # (see JavaBuildpack::Component::BaseComponent#release) + def release + # Default cxAppTag to application name if not set as an env var + app_tag = ENV['cxAppTag'] || application_name + # Default team to CxServer if not set as env var + team = ENV['cxTeam'] || 'CxServer' + + javaagent = "-javaagent:#{qualify_path(@droplet.sandbox + JAVA_AGENT_JAR, @droplet.root)}" + @droplet.java_opts + .add_preformatted_options(javaagent) + .add_preformatted_options('-Xverify:none') + .add_system_property('cx.logToConsole', 'true') + .add_system_property('cx.appName', application_name) + .add_system_property('cxAppTag', app_tag) + .add_system_property('cxTeam', team) + end + + private + + JAVA_AGENT_JAR = 'cx-launcher.jar' + + OVERRIDE_CONFIG = 'cx_agent.override.properties' + + FILTER = /^checkmarx-iast$/.freeze + + private_constant :JAVA_AGENT_JAR, :FILTER, :OVERRIDE_CONFIG + + def application_name + @application.details['application_name'] || 'ROOT' + end + + end + + end + +end diff --git a/spec/java_buildpack/framework/checkmarx_iast_agent_spec.rb b/spec/java_buildpack/framework/checkmarx_iast_agent_spec.rb new file mode 100644 index 0000000000..3f3a1191d8 --- /dev/null +++ b/spec/java_buildpack/framework/checkmarx_iast_agent_spec.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2020 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'component_helper' +require 'java_buildpack/framework/checkmarx_iast_agent' + +describe JavaBuildpack::Framework::CheckmarxIastAgent do + include_context 'with component help' + + it 'does not detect without checkmarx-iast service' do + expect(component.detect).to be_nil + end + + context do + + before do + allow(services).to receive(:one_service?).with(/^checkmarx-iast$/, 'server').and_return(true) + allow(services).to receive(:find_service).and_return('credentials' => { 'server' => 'http://iast-server:8080/' }) + end + + it 'detects with checkmarx-iast service' do + expect(component.detect).to eq('http://iast-server:8080') + end + + it 'updates JAVA_OPTS' do + component.release + + puts java_opts + expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/checkmarx_iast_agent/cx-launcher.jar') + expect(java_opts).to include('-Dcx.logToConsole=true') + expect(java_opts).to include('-Dcx.appName=test-application-name') + expect(java_opts).to include('-DcxAppTag=test-application-name') + expect(java_opts).to include('-DcxTeam=CxServer') + end + + end + +end