Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ For adding a library only:
<dependency>
<groupId>com.instancify.scriptify</groupId>
<artifactId>core</artifactId>
<version>1.3.0-SNAPSHOT</version>
<version>1.3.1-SNAPSHOT</version>
</dependency>
```

Expand All @@ -26,12 +26,12 @@ For adding a library with JS for Rhino or GraalVM:
<dependency>
<groupId>com.instancify.scriptify</groupId>
<artifactId>script-js-rhino</artifactId>
<version>1.3.0-SNAPSHOT</version>
<version>1.3.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.instancify.scriptify</groupId>
<artifactId>script-js-graalvm</artifactId>
<version>1.3.0-SNAPSHOT</version>
<version>1.3.1-SNAPSHOT</version>
</dependency>
```
## Gradle
Expand All @@ -45,11 +45,11 @@ maven {

For adding a library only:
```groovy
implementation "com.instancify.scriptify:core:1.3.0-SNAPSHOT"
implementation "com.instancify.scriptify:core:1.3.1-SNAPSHOT"
```

For adding a library with JS for Rhino or GraalVM:
```groovy
implementation "com.instancify.scriptify:script-js-rhino:1.3.0-SNAPSHOT"
implementation "com.instancify.scriptify:script-js-graalvm:1.3.0-SNAPSHOT"
implementation "com.instancify.scriptify:script-js-rhino:1.3.1-SNAPSHOT"
implementation "com.instancify.scriptify:script-js-graalvm:1.3.1-SNAPSHOT"
```
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.instancify.scriptify.api.exception.ScriptFunctionException;
import com.instancify.scriptify.api.script.constant.ScriptConstantManager;
import com.instancify.scriptify.api.script.function.ScriptFunctionManager;
import com.instancify.scriptify.api.script.security.ScriptSecurityManager;

/**
* Defines the structure of a script that can be executed.
Expand Down Expand Up @@ -44,6 +45,14 @@ public interface Script<T> {
*/
void setConstantManager(ScriptConstantManager constantManager);

/**
* Retrieves the security manager associated with this script.
*
* @return The ScriptSecurityManager for this script
* @see ScriptSecurityManager
*/
ScriptSecurityManager getSecurityManager();

/**
* Evaluates and executes this script.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.instancify.scriptify.api.script.security;

import com.instancify.scriptify.api.script.constant.ScriptConstantManager;
import com.instancify.scriptify.api.script.security.exclude.SecurityExclude;

import java.util.Set;

public interface ScriptSecurityManager {

/**
* Gets a current security mode.
*
* @return The boolean associated with security mode state
*/
boolean getSecurityMode();

/**
* Sets the current security mode.
*
* @param securityMode The boolean associated with security mode state
* @see ScriptConstantManager
*/
void setSecurityMode(boolean securityMode);

/**
* Receives security path accessor.
*
* @return Security path accessor
*/
SecurityPathAccessor getPathAccessor();

/**
* Retrieves all existing exclusions for this script.
*
* @return Set with exclusions
*/
Set<SecurityExclude> getExcludes();

/**
* Adds an exclusion for a path or package.
*
* @param exclude The exclusion to be added
*/
void addExclude(SecurityExclude exclude);

/**
* Removes an exclusion for a path or package.
*
* @param exclude The exclusion to remove
*/
void removeExclude(SecurityExclude exclude);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.instancify.scriptify.api.script.security;

import java.util.Set;

/**
* Manages class access based on security constraints, ensuring only allowed classes can be used.
*/
public interface SecurityClassAccessor {

/**
* Retrieves the set of class names that are allowed to be accessed or used.
*
* @return A set of strings representing the names of allowed classes
*/
Set<String> getAllowedClasses();

/**
* Adds a class to the list of allowed classes, which can then be used or accessed.
*
* @param allowedClass The name of the class to be added to the allowed list
*/
void addAllowedClass(String allowedClass);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.instancify.scriptify.api.script.security;

import java.nio.file.Path;

/**
* Manages path access based on security constraints, ensuring only safe paths are accessible.
*/
public interface SecurityPathAccessor {

/**
* Gets a base path for this accessor, which will be used for relative path calculations.
*
* @return The base path to set
*/
Path getBasePath();

/**
* Sets a new base path for this accessor, which will be used for relative path calculations.
*
* @param basePath The new base path to set
*/
void setBasePath(Path basePath);

/**
* Returns a path that is safe to access according to security rules. If the path is not accessible,
* it returns a path relative to the base path with ':' characters removed to prevent potential path traversal attacks.
*
* @param path The path string to be checked and possibly modified
* @return A Path object representing the accessible path or a sanitized version if not accessible
*/
Path getAccessiblePath(String path);

/**
* Checks if the given path is accessible based on the current security settings.
*
* @param path The path to check for access permission
* @return true if the path is accessible, false otherwise
*/
boolean isAccessible(String path);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.instancify.scriptify.api.script.security.exclude;

public class ClassSecurityExclude implements SecurityExclude {

private final Class<?> value;

public ClassSecurityExclude(Class<?> value) {
this.value = value;
}

@Override
public String getValue() {
return value.getName();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.instancify.scriptify.api.script.security.exclude;

public class PathSecurityExclude implements SecurityExclude {

private final String value;

public PathSecurityExclude(String value) {
this.value = value;
}

@Override
public String getValue() {
return value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.instancify.scriptify.api.script.security.exclude;

public interface SecurityExclude {

/**
* Value to be added to the exclusion.
*
* @return The exclusion value
*/
String getValue();

/**
* Checks that the value of path or packet is excluded.
*
* @param value Path or package
* @return True if excluded, otherwise false
*/
default boolean isExcluded(String value) {
// Check that the path starts from the path specified in the exclusion
return value.startsWith(this.getValue());
}

/**
* Creates a new exclusion instance for the class.
*
* @param value A class that will be excluded
* @return A new exclusion instance for the class
*/
static ClassSecurityExclude ofClass(Class<?> value) {
return new ClassSecurityExclude(value);
}

/**
* Creates a new exclusion instance for the path.
*
* @param value A path that will be excluded
* @return A new exclusion instance for the path
*/
static PathSecurityExclude ofPath(String value) {
return new PathSecurityExclude(value);
}
}
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ java {

allprojects {
group = "com.instancify.scriptify"
version = "1.3.1-SNAPSHOT"
version = "1.3.2-SNAPSHOT"
}

subprojects {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

/**
* Represents a function to write the contents of a file
Expand All @@ -27,7 +26,7 @@ public Object invoke(Script<?> script, ScriptFunctionArgument[] args) throws Scr
if (args.length == 2) {
if (args[0].getValue() instanceof String filePath && args[1].getValue() instanceof String fileContent) {
try {
return Files.writeString(Path.of(filePath), fileContent);
return Files.writeString(script.getSecurityManager().getPathAccessor().getAccessiblePath(filePath), fileContent);
} catch (IOException e) {
throw new ScriptFunctionException(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,23 @@ public Object invoke(Script<?> script, ScriptFunctionArgument[] args) throws Scr
if (!(args[0].getValue() instanceof String input)) {
throw new ScriptFunctionArgTypeException(String.class, args[0].getType());
}

try {
Process process = Runtime.getRuntime().exec(input);
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(process.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(process.getErrorStream()));

String message = "";
String buff = null;
while ((buff = stdInput.readLine()) != null) {
message += buff + "\n";
}
while ((buff = stdError.readLine()) != null) {
message += buff + "\n";
}
return message;

StringBuilder message = new StringBuilder();
try (BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {

String line;
while ((line = stdInput.readLine()) != null) {
message.append(line).append("\n");
}
while ((line = stdError.readLine()) != null) {
message.append(line).append("\n");
}
}
return message.toString();
} catch (IOException e) {
throw new ScriptFunctionException(e);
}
Expand Down
Loading
Loading