java.lang.security.audit.dangerous-groovy-shell.dangerous-groovy-shell

profile photo of semgrepsemgrep
Author
6,314
Download Count*

A expression is built with a dynamic value. The source of the value(s) should be verified to avoid that unfiltered values fall into this risky code evaluation.

Run Locally

Run in CI

Defintion

rules:
  - id: dangerous-groovy-shell
    patterns:
      - pattern-either:
          - pattern: |
              $SHELL.parse(...)
          - pattern: |
              $SHELL.evaluate(...)
          - pattern: |
              $SHELL.parseClass(...)
      - pattern-either:
          - pattern-inside: |
              groovy.lang.GroovyShell $SHELL = ...;
              ...
          - pattern-inside: |
              groovy.lang.GroovyClassLoader $SHELL = ...;
              ...
      - pattern-not: |
          $SHELL.parse("...",...)
      - pattern-not: |
          $SHELL.evaluate("...",...)
      - pattern-not: |
          $SHELL.parseClass("...",...)
    message: A expression is built with a dynamic value. The source of the value(s)
      should be verified to avoid that unfiltered values fall into this risky
      code evaluation.
    metadata:
      cwe:
        - "CWE-94: Improper Control of Generation of Code ('Code Injection')"
      owasp:
        - A03:2021 - Injection
      source-rule-url: https://find-sec-bugs.github.io/bugs.htm#GROOVY_SHELL
      category: security
      technology:
        - groovy
      references:
        - https://owasp.org/Top10/A03_2021-Injection
      cwe2022-top25: true
      subcategory:
        - audit
      likelihood: LOW
      impact: LOW
      confidence: LOW
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Code Injection
    languages:
      - java
    severity: WARNING

Examples

dangerous-groovy-shell.java

package testcode.groovy;

import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyCodeSource;
import groovy.lang.GroovyShell;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;

public class GroovyShellUsage {

    public static void test1(String uri, String file, String script) throws URISyntaxException, FileNotFoundException {
        GroovyShell shell = new GroovyShell();

        // ruleid:dangerous-groovy-shell
        shell.evaluate(new File(file));
        // ruleid:dangerous-groovy-shell
        shell.evaluate(new InputStreamReader(new FileInputStream(file)), "script1.groovy");
        // ruleid:dangerous-groovy-shell
        shell.evaluate(script);
        // ruleid:dangerous-groovy-shell
        shell.evaluate(script, "script1.groovy", "test");
        // ruleid:dangerous-groovy-shell
        shell.evaluate(new URI(uri));
        // ok:dangerous-groovy-shell
        shell.evaluate("hardcoded script");
    }

    public static void test2(String uri, String file, String script) throws URISyntaxException, FileNotFoundException {
        GroovyShell shell = new GroovyShell();

        // ruleid:dangerous-groovy-shell
        shell.parse(new File(file));
        // ruleid:dangerous-groovy-shell
        shell.parse(new InputStreamReader(new FileInputStream(file)), "test.groovy");
        // ruleid:dangerous-groovy-shell
        shell.parse(new InputStreamReader(new FileInputStream(file)));
        // ruleid:dangerous-groovy-shell
        shell.parse(script);
        // ruleid:dangerous-groovy-shell
        shell.parse(script, "test.groovy");
        // ruleid:dangerous-groovy-shell
        shell.parse(new URI(uri));

        String hardcodedScript = "test.groovy";
        // ok:dangerous-groovy-shell
        shell.parse(hardcodedScript);
    }

    public static void test3(String uri, String file, String script, ClassLoader loader) throws URISyntaxException, FileNotFoundException {
        GroovyClassLoader groovyLoader = (GroovyClassLoader) loader;

        // ruleid:dangerous-groovy-shell
        groovyLoader.parseClass(new GroovyCodeSource(new File(file)),false);
        // ruleid:dangerous-groovy-shell
        groovyLoader.parseClass(new InputStreamReader(new FileInputStream(file)), "test.groovy");
        // ruleid:dangerous-groovy-shell
        groovyLoader.parseClass(script);
        // ruleid:dangerous-groovy-shell
        groovyLoader.parseClass(script,"test.groovy");

        String hardcodedScript = "test.groovy";
        // ok:dangerous-groovy-shell
        shell.parse(hardcodedScript);
    }
}