|
| 1 | +# Sandboxing tests with Java Security Manager |
| 2 | + |
| 3 | +## What is sandboxing? |
| 4 | + |
| 5 | +Sandboxing is a security technique to find unsafe code fragments and prevent them from being executed. |
| 6 | + |
| 7 | +What do we mean by "unsafe code" in Java? The most common forbidden actions are: |
| 8 | + |
| 9 | +* working with files (read, write, create, delete), |
| 10 | +* connecting to [sockets](https://github.com/UnitTestBot/UTBotJava/issues/792), |
| 11 | +* invoking `System.exit()`, |
| 12 | +* accessing system properties or JVM properties, |
| 13 | +* using reflection. |
| 14 | + |
| 15 | +## Why do we need sandboxing for test generation? |
| 16 | + |
| 17 | +During test generation, UnitTestBot executes the source code with the concrete values. All the fuzzer runs require |
| 18 | +concrete execution and some of the symbolic execution processes invoke it as well. If the source code contains |
| 19 | +potentially unsafe operations, executing them with the concrete values may lead to fatal errors. It is safer to catch |
| 20 | +these operations and break the concrete execution process with `AccessControlException` thrown. |
| 21 | + |
| 22 | +## What do the sandboxed tests look like? |
| 23 | + |
| 24 | +When the source code fragments are suspicious and the corresponding test generation processes are interrupted, the tests with the `@Disabled` annotation and a stack trace appear in the output: |
| 25 | + |
| 26 | + public void testPropertyWithBlankString() { |
| 27 | + SecurityCheck securityCheck = new SecurityCheck(); |
| 28 | + |
| 29 | + /* This test fails because method [com.company.security.SecurityCheck.property] produces [java.security.AccessControlException: access denied ("java.util.PropertyPermission" " " "read")] |
| 30 | + java.security.AccessControlContext.checkPermission(AccessControlContext.java:472) |
| 31 | + java.security.AccessController.checkPermission(AccessController.java:886) |
| 32 | + java.lang.SecurityManager.checkPermission(SecurityManager.java:549) |
| 33 | + java.lang.SecurityManager.checkPropertyAccess(SecurityManager.java:1294) |
| 34 | + java.lang.System.getProperty(System.java:719) |
| 35 | + com.company.security.SecurityCheck.property(SecurityCheck.java:32) */ |
| 36 | + } |
| 37 | + |
| 38 | +## How does UnitTestBot sandbox code execution? |
| 39 | + |
| 40 | +UnitTestBot for Java/Kotlin uses [Java Security Manager](https://docs.oracle.com/javase/tutorial/essential/environment/security.html) for sandboxing. In general, the Security Manager allows applications to implement a security policy. It determines whether an operation is potentially safe or not and interrupts the execution if needed. |
| 41 | + |
| 42 | +In UnitTestBot the **secure mode is enabled by default**: only a small subset of runtime permissions necessary for |
| 43 | +test generation are given (e.g. fields reflection is permitted by default). To extend the list of permissions learn |
| 44 | +[How to handle sandboxing](#How-to-handle-sandboxing). |
| 45 | + |
| 46 | +Java Security Manager monitors [all the code](https://github.com/UnitTestBot/UTBotJava/issues/791) for the risk of performing forbidden operations, including code in _class constructors, private methods, static blocks, [threads](https://github.com/UnitTestBot/UTBotJava/issues/895)_, and combinations of all of the above. |
| 47 | + |
| 48 | +## How to handle sandboxing |
| 49 | + |
| 50 | +You can **add permissions** by creating and editing the `~\.utbot\sandbox.policy` file. Find more about [Policy File and Syntax](https://docs.oracle.com/javase/7/docs/technotes/guides/security/PolicyFiles.html#Examples) and refer to the [Full list of permissions](https://docs.oracle.com/javase/1.5.0/docs/guide/security/spec/security-spec.doc3.html) to choose the proper approach. |
| 51 | + |
| 52 | +If the permission was added but somehow [not recognized](https://github.com/UnitTestBot/UTBotJava/issues/796), the UnitTestBot plugin will fail to start and generate no tests. |
| 53 | + |
| 54 | +If you are sure you want the code to be executed as is (**including the unsafe operations!**) you can **turn sandboxing off**: |
| 55 | + |
| 56 | +* You can add `AllPermission` to `~\.utbot\sandbox.policy`. Be careful! |
| 57 | +* Alternatively, you can add `useSandbox=false` to `~\.utbot\settings.properties`. Create this file manually if you don't have one. Find [more information](https://github.com/UnitTestBot/UTBotJava/pull/857) on how to manage sandboxing to test the UnitTestBot plugin itself. |
| 58 | + |
| 59 | +It is reasonable to regard the `@Disabled` tests just as supplemental information about the source code, not as the tests for actual usage. |
| 60 | + |
| 61 | +## How to improve sandboxing |
| 62 | + |
| 63 | +For now there are several unsolved problems related to sandboxing in UnitTestBot: |
| 64 | + |
| 65 | +1. We need to replace Java Security Manager with our own tool. |
| 66 | + |
| 67 | + [Java Security Manager is deprecated since JDK 17](https://openjdk.org/jeps/411) and is subject to removal in some |
| 68 | + future version. It is still present in JDK 19 but with limited functionality. E.g., in Java 18, a Java application or library is prevented from dynamically installing a Security Manager unless the end user has explicitly opted to allow it. Obviously, we cannot rely upon the deprecated tool and need to create our own one. |
| 69 | + |
| 70 | + |
| 71 | +2. We need to provide a unified and readable description for disabled tests. |
| 72 | + |
| 73 | + UnitTestBot supports three testing frameworks and their annotations are slightly different: |
| 74 | + |
| 75 | +JUnit 4: `@Ignore("<comment>")` |
| 76 | + |
| 77 | +JUnit 5: `@Disabled("<comment>")` |
| 78 | + |
| 79 | +TestNG: `@Ignore` as an alternative to `@Test(enabled=false)` |
| 80 | + |
| 81 | +* How should we unify these annotations? |
| 82 | +* How should we show info in Javadoc comments? |
| 83 | +* Do we need to print a stack trace? |
| 84 | + |
| 85 | + |
| 86 | +3. We need to add emulation for restricted operations (a kind of mocks) |
| 87 | + |
| 88 | + Emulating unsafe operations will allow UnitTestBot to generate useful tests even for the sandboxed code and run them instead of disabling. |
| 89 | + |
| 90 | +4. We need to provide a user with the sandboxing settings. |
| 91 | + |
| 92 | + The UnitTestBot plugin UI provides no information about configuring the behavior of Security Manager. Information on [How to |
| 93 | + handle |
| 94 | +sandboxing](#How-to-handle-sandboxing) is available only on GitHub. |
| 95 | + |
| 96 | +* Should we add Sandboxing (or Security Manager) settings to plugin UI? E.g.: **File operations: Forbidden / Allowed / Emulated in sandbox**. |
| 97 | + |
| 98 | +* Should we add a hyperlink to a piece of related documentation or to the `~\.utbot\sandbox.policy` file? |
| 99 | + |
| 100 | +## How to test sandboxing |
| 101 | + |
| 102 | +See the [short manual testing scenario](https://github.com/UnitTestBot/UTBotJava/pull/625) and the [full manual testing checklist](https://github.com/UnitTestBot/UTBotJava/issues/790). |
| 103 | + |
| 104 | +## Related links |
| 105 | + |
| 106 | +Initial feature request: [Add SecurityManager support to block suspicious code #622](https://github.com/UnitTestBot/UTBotJava/issues/622) |
| 107 | + |
| 108 | +Pull request: [Add SecurityManager support to block suspicious code #622 #625](https://github.com/UnitTestBot/UTBotJava/pull/625) |
| 109 | + |
| 110 | +Improvement request: [Improve sandbox-relative description in generated tests #782](https://github.com/UnitTestBot/UTBotJava/issues/782) |
0 commit comments