Java Security Manager checkExec

Tengo un problema al intentar implementar una comprobación de seguridad en Java Security Manager.

Parece que he entendido mal el propósito del método checkExec () en el administrador de seguridad. Pensé que se llamaría cuando mi aplicación intente invocar otra aplicación Java a través de la línea de comando, pero eso no parece estar sucediendo.

Esto es lo que quiero que suceda: una aplicación de invocación que utiliza mi administrador de seguridad personalizado ejecuta "java SomeApp" en la línea de comandos. El administrador de seguridad verifica si esto está bien y realiza la acción adecuada.

Para tratar de lograr esto, hice lo siguiente:

  1. Creó un administrador de seguridad personalizado que anula el checkExecmétodo. La firma del método es public void checkExec(String cmd).

  2. Creó una clase de prueba, SecurityTest.

  3. SecurityTest asigna mi administrador de seguridad personalizado como su administrador de seguridad.

  4. SecurityTest se ejecuta java InvokeMeen la línea de comando.

  5. El administrador de seguridad personalizado intercepta esto y hace algo.

1 a 4 están bien, pero 5 nunca sucede. Verifiqué que mi administrador de seguridad personalizado es válido, se ha asignado correctamente a SecurityTest y SecurityTest ejecuta InvokeMe con éxito. Sin embargo, a lo mejor de mi capacidad de discernir, nunca se llama al método checkExec () en mi administrador de seguridad personalizado.

¿A dónde me estoy yendo mal? ¿Es posible lo que intento hacer (hacer que el administrador de seguridad haga algo cuando se invoca una aplicación java SomeApp)?

Gracias por tu tiempo.

EDITAR:

Aquí hay algunos códigos y resultados que resultan de ejecutar una prueba. Este es un estilo de prototipo rápido, código de estilo "arranca y limpia más tarde" para que no sea hermoso:

Gerente de seguridad personalizado:

import java.util.*;
import java.io.*;
class DTESecurityManager extends SecurityManager {
    // instance variables

    DTESecurityManager() {
        super();
        //assign a bunch of variables
        System.out.println("TEST 1");
    }

    public void checkExec(String cmd) {
        if (cmd.toLowerCase().startsWith("java ")) {
            if (cmd.matches("(?i).*-djava.security.manager.*")) {
                throw new SecurityException("Cannot assign a security manager to invoked Java applications.");
            }
            StringBuffer intermediateCommand = new StringBuffer(cmd).insert(5, "-Djava.security.manager=DTESecurityManager ");
            String modifiedCommand = new String(intermediateCommand);
            try {
                Runtime rt = Runtime.getRuntime();
                Process pr = rt.exec(modifiedCommand);
            } catch (Exception e) {
                System.err.println("Error: " + e.getMessage());
            }
            try {
                FileWriter fstream = new FileWriter("Verification.txt");
                BufferedWriter out= new BufferedWriter(fstream);
                out.write("I worked.");
                out.close();
            } catch (Exception e) {
                System.err.println("Error: " + e.getMessage());
            }
            throw new SecurityException("Command was executed, but was modified to force invoked application to use this security manager.");
        }
    }
}

Prueba de seguridad:

import java.io.*;

class SecurityTest {

    public static void main(String[] args) {
        try {
            System.setSecurityManager(new DTESecurityManager());
        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
        }
        try {
            System.out.println("If we got this far, we had no problems setting our security manager.");
            System.out.println("Now let's try to invoke another Java application.");
            Runtime rt = Runtime.getRuntime();
            Process pr = rt.exec("java InvokeMe");
            System.out.println("I reached the end of my test without crashing. Now terminating.");
        } catch (Exception e) {
            System.out.println("Exception message: " + e.getMessage());
        }
    }

}

InvokeMe:

import java.io.*;

class InvokeMe {

    public static void main(String[] args) {
        System.out.println("I, InvokeMe, have been invoked successfully.");
        try {
        FileWriter fstream = new FileWriter("InvokeMeWasCalled.txt");
            BufferedWriter out= new BufferedWriter(fstream);
            out.write("It worked.");
            out.close();
        } catch (Exception e) {
            System.err.println("Error: " + e.getMessage());
        }
    }

}

Prueba de salida:

TEST 1
If we got this far, we had no problems setting our security manager.
Now let's try to invoke another Java application.
I reached the end of my test without crashing. Now terminating.

No hay indicios de que se llame a checkExec (): no hay salida de consola y Verification.txt no existe en ningún lugar de mi sistema de archivos. (Por supuesto, no estoy seguro de cómo se supone que es el comportamiento de una subclase de administrador de seguridad cuando se realizan acciones como esta, así que tal vez sea normal. Si ese es el caso, necesito otro método rápido y sucio para probar si yo Estoy llegando a ciertas líneas de código.) InvokeMeWasCalled.txt existe, por lo que esa parte definitivamente funciona.

Respuesta 1

El problema está en la anulación de su gerente de seguridad checkExec. El cmdparámetro pasado checkExecsolo contiene la primera "palabra" en el comando que se está ejecutando, por lo que en su programa, "java" es el cmdparámetro. Como resultado, la cadena no comienza con "java" y checkExecno ejecuta el bloque if, lo que resulta en una verificación "limpia" del administrador de seguridad.

public void checkExec(String cmd) {
    System.out.println(cmd); // prints "java"
    if (cmd.toLowerCase().startsWith("java ") { ... } // is false
    // no security exception is thrown, allowing your command
}

Además, como nota al margen, la ejecución del comando modificado dará como resultado que StackOverflowErrorsolo se pase la primera "palabra" al método.

Respuesta: 2

Hola, estoy escribiendo una prueba unitaria donde necesito afirmar que una lista contiene objetos de varias clases en un orden específico. Quiero hacer esto usando hamcrest. En este momento lo estoy afirmando como ...

He creado una imagen de máquina que tiene algunos lenguajes / frameworks instalados, por ejemplo, Java, Ruby, etc. La idea es que puedo inicializar rápidamente una nueva máquina virtual (por ejemplo, en Amazon EC2 o ...

Tengo un conjunto de datos como este: + --- + ------------------- + ------------------ ----- + | id | tiempo | rango | + --- + ------------------- + ----------------------- + | id1 | 2019-03-11 05:00: ...

Cuando trato de ejecutar un programa en Eclipse Mars, dice algo como: "Se ha producido un error JNI. Compruebe su instalación". Aquí está mi código: paquete java.john.rex.sample.palindrome import ...