Skip to content

seal-sec-demo-2/Java-Example

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Seal Security — Java (Maven) Example

A minimal, intentionally vulnerable Spring Boot application used to demonstrate, end‑to‑end, how Seal Security 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 — 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:

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 — the object‑injection primitive behind CVE‑2022‑1471. A payload naming javax.script.ScriptEngineManager (the entry point of the classic RCE gadget chain) is enough to prove the parser will build any class an attacker names.

Normal request

/?name=alice          →  Welcome, alice!

Exploit request

/?name=!!javax.script.ScriptEngineManager []

The vulnerable SnakeYAML instantiates the attacker‑named class, the app shows a “You've been pwned” page, and the server is then killed (a few seconds later, so the page delivers first). Reload and the app is gone — over ngrok you'll see an “endpoint offline” page. This is the object‑injection primitive; a full exploit chains it (via URLClassLoader) to load and run remote code.


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

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

Open http://localhost:8080/?name=alice (works), then http://localhost:8080/?name=!!javax.script.ScriptEngineManager [] — the app shows "You've been pwned" and the server is killed a few seconds later.


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:

- 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.

Option B — Jenkins (Groovy pipeline)

A single added stage, after dependency resolution and before packaging. See Jenkinsfile:

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.

About

Seal Security example — vulnerable Maven app (SnakeYAML CVE-2022-1471) remediated to sealed versions; GitHub Actions + Jenkins integration

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages