Skip to content

Commit

Permalink
✨ add support for checking commands invoked with ProcessBuilder
Browse files Browse the repository at this point in the history
  • Loading branch information
ryandens committed Mar 22, 2024
1 parent b673e7e commit 749807d
Showing 1 changed file with 48 additions and 0 deletions.
48 changes: 48 additions & 0 deletions src/main/java/io/github/pixee/security/SystemCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,41 @@ public static Set<SystemCommandRestrictions> defaultRestrictions() {
SystemCommandRestrictions.PREVENT_ARGUMENTS_TARGETING_SENSITIVE_FILES);
}

/**
* Does the same as {@link ProcessBuilder#start()}, but adds restrictions on what types of commands
* will be allowed. Will throw a {@link SecurityException} if any of the restrictions may be
* violated by the command found. Note that the method of detecting violations is based on
* semantic analysis of the command, and so is vulnerable to impedance mismatches between the
* analysis we perform and whatever shell is interpreting the command. Either way, it's a lot
* safer.
*
* @param processBuilder the system command about to be run
* @param restrictions the set of restrictions to run with
* @return the {@link Process} that results from the hardened {@link ProcessBuilder#start()} call
* @throws SecurityException if multiple commands are found
* @throws IllegalArgumentException if restriction is null
* @throws IOException from the wrapped system process invocation call
*/
public static Process runProcessBuilder(
final ProcessBuilder processBuilder,
final Set<SystemCommandRestrictions> restrictions)
throws IOException {
runChecks(processBuilder.command(), restrictions);
return processBuilder.start();
}

/**
* Delegates to {@link SystemCommand#runProcessBuilder(ProcessBuilder, Set)} with default
* restrictions.
*
* @param processBuilder the system command about to be run
* @return the {@link Process} that results from the hardened {@link ProcessBuilder#start()} call
* @throws IOException from the wrapped system process invocation call
*/
public static Process runProcessBuilder(final ProcessBuilder processBuilder) throws IOException {
return runProcessBuilder(processBuilder, defaultRestrictions());
}

/**
* Does the same as {@link Runtime#exec(String)}, but adds restrictions on what types of commands
* will be allowed. Will throw a {@link SecurityException} if any of the restrictions may be
Expand Down Expand Up @@ -275,6 +310,19 @@ private static void runChecks(
}
}

/**
* Helper method similar to {@link #runChecks(String[], Set)} but avoids the need to convert a {@link List} to an array.
* @param command to be checked
* @param restrictions to be checked against
*/
private static void runChecks(final List<String> command, final Set<SystemCommandRestrictions> restrictions) {
final CommandLine parsedCommandLine = new CommandLine(command.get(0));
for (int i = 1; i < command.size(); i++) {
parsedCommandLine.addArgument(command.get(i));
}
runChecks(parsedCommandLine, restrictions);
}

private static void runChecks(
final String[] command, final Set<SystemCommandRestrictions> restrictions) {
final CommandLine parsedCommandLine = new CommandLine(command[0]);
Expand Down

0 comments on commit 749807d

Please sign in to comment.