Stabilise the Ares 2 test suite and CI#101
Conversation
Before this change all file-system SecurityExceptions had the same generic form with no indication of *why* the access was blocked. This made debugging and policy development extremely difficult. Two new message keys are introduced: - security.advice.denial.reason.no.allowlist → no allow rule at all - security.advice.denial.reason.not.in.allowlist → path outside allowlist A buildDenialReason(String[] allowedPaths) helper is added to both JavaInstrumentationAdviceAbstractToolbox (for Byte Buddy mode) and JavaAspectJAbstractAdviceDefinitions (for AspectJ mode). The three SecurityException throw-sites in each file-system toolbox now append the reason after a ' | ' separator, e.g.: ... tried to illegally read File /path/secret.txt via Files.readString | Reason: No allow rule configured for this resource type. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extend the file-system denial-reason suffix to the network, command and thread subsystems, in both the Byte Buddy instrumentation and the AspectJ back-ends. Each subsystem derives its own "no allow rule configured" flag from its allow-lists and appends " | " + buildDenialReason(...) at every SecurityException throw-site. buildDenialReason now takes a boolean. Tests: - End-to-end NOT_PERMITTED coverage (DenialReasonAccessTest) for file, command and thread across all four ArchUnit/WALA x AspectJ/Instrumentation runners, and for network on the AspectJ runners (new SocketConnectMain subject plus two PolicyOneNetworkConnectionAllowed policies). - Toolbox-level NO_ALLOWLIST and NOT_PERMITTED coverage for command, thread and file; the network toolbox already covered both. The NO_ALLOWLIST reason is asserted only at toolbox level, because with an empty policy the static architecture layer (ArchUnit/WALA) blocks the capability before the runtime AOP layer adds the reason. Network is tested end-to-end under AspectJ only, since the instrumentation path does not intercept java.net.Socket connections.
The top-level ares/ directory was a stray, partial copy of source files already under src/main/java/de/tum/cit/ase/ares. It was never part of the Maven build (only src/main/java and src/test/java are compiled), nothing referenced it, and several of its files carried invalid "package .ares..." declarations that could not compile. Its non-corrupted files were exact duplicates of their real counterparts, so nothing unique is lost.
…hitecture analysis getJavaClasses now skips classes whose path contains /ares/api/ via an import filter, so Ares's own infrastructure (reflection, class loading, System.getProperty) is not flagged by the architecture rules. Student attack subjects under /ares/integration/ remain in scope.
…ssing keys Replace the bare combining-diaeresis escape that corrupted 'zurueck' in dynamics.method.return, and add the nine keys present in the English bundle but missing from German (file.tools.*, the new security.architecture.* categories, security.instrumentation.field.not.found), restoring de/en key-set parity.
…M module-access args Add timeout-minutes to build-and-test so the suite fails fast with a readable log instead of the runner losing communication after ~1h; add forkedProcessTimeoutInSeconds and -Xmx to surefire; carry the JVM --add-opens/--add-exports args the AOP advice needs.
Remove the @Userbased integration.FileSystemAccessTest, its FileSystemAccessUser, and the monolithic FileSystemAccessPenguin subject whose whole-class architecture scan cross-contaminated unrelated read tests. These scenarios are covered by the per-method aop.allowed and architecture.forbidden suites. Drop the three now-orphaned root policy files used only by the removed suite.
…ead/overwrite policies Add de.tum.cit.ase.ares.integration.aop.allowed.FileSystemAccessTest to theFollowingClassesAreTestClasses across the read and overwrite policy matrices, so the harness's fixture setup writes are not policed as student code. Without this, allowed read/overwrite operations were wrongly blocked.
JavaArchitectureTestCaseSupportedTest expects the six static cases getStatic now returns; SecurityPolicyJavaDirectorTest expects the default builder for a null policy rather than an NPE; JavaCreatorTest expects the lazily-supplied call graph (no eager getCallGraph); WalaRuleTest expects ArchUnit source-form signatures and that paths through project test helpers fire.
…eadTest assertions Add @uselocale("en") to the aop SystemAccessTest base classes, aop.allowed.FileSystemAccessTest, and ThreadTest so they run under English (matching CI). Update ThreadTest.assertThreadErrorMessage to match the current Ares message ('Ares Security Error', ThreadPenguin, 'create Thread', 'blocked by Ares') instead of obsolete substrings.
… to @Policy The @WhitelistPath/@AddTrustedPackage/@WhitelistClass annotations no longer affect AOP enforcement. Replace them with @Policy(activated=false): StructuralUser (incl. nested InvalidConfigurations) exercises ClassNameScanner correctness, and TrustedClassesUser exercised a removed trust feature, so neither needs runtime enforcement active.
…VM server Per AGENTS.md, a sandboxed test JVM must not start its own server. connectLocallyAllowed targets the external echo server on the loopback and skips when it is absent; an Ares block of an explicitly allowed connection remains a real failure.
…reation subjects Remove the try/catch that wrapped forbidden thread-creation calls in RuntimeException, so the Ares SecurityException reaches the test directly as expected.
Add trusteddir/trusted.txt (aop.allowed) and nottrusteddir/nottrusted.txt (aop.forbidden) fixtures for the file-system delete tests.
Document that sandboxed test JVMs must use an external echo server rather than spinning up an in-process server, and that an Ares block of an explicitly allowed connection is always a real failure.
The previous topical commits were made without a clean 'mvn spotless:apply' pass, so 'mvn spotless:check' (the first CI step) failed on these files. These are pure formatting changes (indentation and line wrapping); no behaviour is affected.
The legacy Ares 1 annotations (@WhitelistPath, @blacklistpath, @AllowThreads, @AllowLocalPort, @TrustedThreads, @WhitelistClass/@WhitelistPackage, @BlacklistPackage, @AddTrustedPackage) are inert under the Ares 2 enforcement path: only @Policy drives the architecture and AOP analysis. Remove every such usage from the integration test users and replace it with an active @Policy that captures the former intent, scanned against the benign HelloWorld subject. The annotation definitions themselves and the AresSecurityConfiguration unit test that exercises them are intentionally left untouched.
…ed calls - Bind java.awt.Desktop interception to the file-read check only (previously bound to read, overwrite, execute and delete simultaneously, so the reported verb was nondeterministic across AspectJ and instrumentation). Applied symmetrically in both enforcement layers. - Remove java.net.URL.openStream from the network-connect map so a content read via ClassLoader.getResourceAsStream is classified as a file read, not a network connection (openConnection stays in the network map). - Remove java.net.URI.create and the pure-parsing URI constructors from the ArchUnit network method list; URI parsing performs no network access. - Exempt JDK-internal reads under java.home (e.g. JceSecurity reading the crypto jurisdiction-policy files) from the file-system checks, mirroring the existing native-library-load exemption, in both layers. - Update the AspectJ copy-config placeholder count to match the edited advice source so the precompile flow stays consistent.
…ityException When the static initialiser's disk-cache read runs inside an active Ares policy boundary, the read (and even the isRegularFile probe, which sat outside the try) is intercepted and throws a SecurityException. That escaped the initialiser as an ExceptionInInitializerError, poisoning JavaWalaTestCase with NoClassDefFoundError for the whole JVM and breaking every subsequent WALA test in the run. Wrap the entire best-effort load in the try and add SecurityException to the multicatch (load and save); on any failure the in-memory cache simply starts empty and outcomes are rebuilt.
…sertions - Fix stale within-path constants in the read tests (the subjects live under read/oldMethods/...), so ArchUnit imports the subject classes and flags the forbidden access. - Add a 3-arg assertAresSecurityExceptionDelete overload and point the WALA delete assertions at the subject's actual deleted path (delete/nottrusteddir/nottrusted.txt); two of them wrongly asserted 'read'. - Point the third-party overwrite assertions at the penguin's actual path and align the lone inconsistent BufferedWriter assertion with its siblings. These classes pass in isolation (200 run, 0 failures); some still fail in the full single-JVM run due to a separate WALA cross-test contamination issue tracked separately.
PrecompileTest invoked writeTestCases(Path.of("")), emitting the generated
architecture/AOP scaffold, localisation resources and Phobos files into the
repository working directory on every run. Write into a JUnit @tempdir instead,
nested deeply enough that the localisation sibling-resources folder and the
Phobos parent climbs both resolve inside the temp directory, which is removed
automatically. Add a .gitignore safety net for the generated paths.
📝 WalkthroughWalkthroughThis change set adds denial-reason messaging and related allowlist handling across AspectJ and instrumentation checks, updates tests and policies to expect the new messages, and removes several legacy architecture/test support classes and templates. ChangesSecurity policy and denial-reason migration
Sequence Diagram(s)Not applicable. Estimated review effort🎯 5 (Critical) | ⏱️ ~90+ minutes Possibly related PRs
Suggested reviewers
Poem
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
|
There was a problem hiding this comment.
Pull request overview
This PR is a broad stabilization effort for Ares 2’s Maven CI and (currently still-red) test suite, combining production fixes in AOP/instrumentation + architecture enforcement with a large migration/realignment of integration tests and @Policy YAML fixtures.
Changes:
- Stabilize Maven CI/build gates (Spotless, timeouts, JVM/module-access args) to reduce flakiness and hard failures.
- Fix/adjust production enforcement behavior (AOP + instrumentation toolboxes, WALA cache resilience, network/FS classification, improved SecurityException denial reasons + i18n).
- Migrate and realign integration tests/fixtures/policies to active
@PolicyYAMLs (including external echo-server network testing and updated FS delete fixtures).
Reviewed changes
Copilot reviewed 138 out of 141 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/PolicyOnePathAllowedRead.yaml | Delete legacy top-level policy YAML (superseded by java/maven variants). |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/PolicyOnePathAllowedExecuteOneCommandExecutionAllowed.yaml | Delete legacy top-level policy YAML (superseded by java/maven variants). |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/wala/instrumentation/PolicyOnePathAllowedReadOverwriteDelete.yaml | Expand allowed FS delete paths for WALA+instrumentation policy. |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/wala/instrumentation/PolicyOnePathAllowedRead.yaml | Include FileSystemAccessTest in WALA+instrumentation read policy scope. |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/wala/instrumentation/PolicyOnePathAllowedOverwrite.yaml | Include FileSystemAccessTest in WALA+instrumentation overwrite policy scope. |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/wala/instrumentation/PolicyOnePathAllowedExecute.yaml | Update allowed execute script paths and command execution entries (trustedExecute rename). |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/wala/instrumentation/PolicyOnePathAllowedDeleteOneThreadAllowed.yaml | Expand allowed FS delete paths for delete+thread policy (WALA+instrumentation). |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/wala/instrumentation/PolicyOnePathAllowedDelete.yaml | Expand allowed FS delete paths for WALA+instrumentation delete policy. |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/wala/aspectj/PolicyOnePathAllowedReadOverwriteDelete.yaml | Expand allowed FS delete paths for WALA+AspectJ policy. |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/wala/aspectj/PolicyOnePathAllowedRead.yaml | Include FileSystemAccessTest in WALA+AspectJ read policy scope. |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/wala/aspectj/PolicyOnePathAllowedOverwrite.yaml | Include FileSystemAccessTest in WALA+AspectJ overwrite policy scope. |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/wala/aspectj/PolicyOnePathAllowedExecute.yaml | Update allowed execute script paths and command execution entries (trustedExecute rename). |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/wala/aspectj/PolicyOnePathAllowedDeleteOneThreadAllowed.yaml | Expand allowed FS delete paths for delete+thread policy (WALA+AspectJ). |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/wala/aspectj/PolicyOnePathAllowedDelete.yaml | Expand allowed FS delete paths for WALA+AspectJ delete policy. |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/wala/aspectj/PolicyOneNetworkConnectionAllowed.yaml | Add WALA+AspectJ policy allowing a loopback connection. |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/instrumentation/PolicyOnePathAllowedReadOverwriteDelete.yaml | Maintain ArchUnit+instrumentation read/overwrite/delete policy alignment. |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/instrumentation/PolicyOnePathAllowedRead.yaml | Maintain ArchUnit+instrumentation read policy alignment. |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/instrumentation/PolicyOnePathAllowedOverwrite.yaml | Maintain ArchUnit+instrumentation overwrite policy alignment. |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/instrumentation/PolicyOnePathAllowedExecute.yaml | Maintain ArchUnit+instrumentation execute policy alignment. |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/instrumentation/PolicyOnePathAllowedDeleteOneThreadAllowed.yaml | Maintain ArchUnit+instrumentation delete+thread policy alignment. |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/instrumentation/PolicyOnePathAllowedDelete.yaml | Maintain ArchUnit+instrumentation delete policy alignment. |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyValidationUser.yaml | Add/update ArchUnit+AspectJ policy for ValidationUser. |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyReflectionTestUtilsUser.yaml | Add/update ArchUnit+AspectJ policy for ReflectionTestUtilsUser. |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyPrivilegedExceptionUser.yaml | Add/update ArchUnit+AspectJ policy for PrivilegedExceptionUser. |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyOnePathAllowedReadOverwriteDelete.yaml | Maintain ArchUnit+AspectJ read/overwrite/delete policy alignment. |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyOnePathAllowedRead.yaml | Maintain ArchUnit+AspectJ read policy alignment. |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyOnePathAllowedOverwrite.yaml | Maintain ArchUnit+AspectJ overwrite policy alignment. |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyOnePathAllowedExecute.yaml | Maintain ArchUnit+AspectJ execute policy alignment. |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyOnePathAllowedDeleteOneThreadAllowed.yaml | Maintain ArchUnit+AspectJ delete+thread policy alignment. |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyOnePathAllowedDelete.yaml | Maintain ArchUnit+AspectJ delete policy alignment. |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyOneNetworkConnectionAllowed.yaml | Add/update ArchUnit+AspectJ policy allowing a loopback connection. |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyLoopbackEchoConnectionAllowed.yaml | Add/update policy to support loopback echo-server connectivity testing. |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyJqwickUser.yaml | Add/update policy for JqwickUser integration tests. |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyInputOutputUser.yaml | Add/update policy for InputOutputUser integration tests. |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyExceptionFailureUser.yaml | Add/update policy for ExceptionFailureUser integration tests. |
| src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyDynamicsUser.yaml | Add/update policy for DynamicsUser integration tests. |
| src/test/java/example/student/InstrumentationSecurityProbe.java | Add probe helpers to exercise instrumentation toolboxes in tests. |
| src/test/java/de/tum/cit/ase/ares/integration/ThreadTest.java | Update thread tests to use @Policy + locale pinning and revised assertions. |
| src/test/java/de/tum/cit/ase/ares/integration/testuser/ValidationUser.java | Migrate ValidationUser integration behavior to current policy model. |
| src/test/java/de/tum/cit/ase/ares/integration/testuser/TrustedClassesUser.java | Migrate TrustedClassesUser integration behavior to current policy model. |
| src/test/java/de/tum/cit/ase/ares/integration/testuser/ThreadUser.java | Migrate ThreadUser integration behavior to current policy model. |
| src/test/java/de/tum/cit/ase/ares/integration/testuser/subject/architectureTests/fileSystem/FileSystemAccessPenguin.java | Adjust architecture FS test helper behavior/paths to match updated policies. |
| src/test/java/de/tum/cit/ase/ares/integration/testuser/StructuralUser.java | Migrate StructuralUser integration behavior to current policy model. |
| src/test/java/de/tum/cit/ase/ares/integration/testuser/SecurityUser.java | Migrate SecurityUser integration behavior to current policy model. |
| src/test/java/de/tum/cit/ase/ares/integration/testuser/ReflectionTestUtilsUser.java | Migrate ReflectionTestUtilsUser integration behavior to current policy model. |
| src/test/java/de/tum/cit/ase/ares/integration/testuser/PrivilegedExceptionUser.java | Migrate PrivilegedExceptionUser integration behavior to current policy model. |
| src/test/java/de/tum/cit/ase/ares/integration/testuser/PackageAccessUser.java | Migrate PackageAccessUser integration behavior to current policy model. |
| src/test/java/de/tum/cit/ase/ares/integration/testuser/NetworkUser.java | Update network integration tests to use external echo server approach. |
| src/test/java/de/tum/cit/ase/ares/integration/testuser/JqwickUser.java | Migrate JqwickUser integration behavior to current policy model. |
| src/test/java/de/tum/cit/ase/ares/integration/testuser/InputOutputUser.java | Migrate InputOutputUser integration behavior to current policy model. |
| src/test/java/de/tum/cit/ase/ares/integration/testuser/FileSystemAccessUser.java | Migrate FS integration user to current policy model and updated fixtures. |
| src/test/java/de/tum/cit/ase/ares/integration/testuser/ExceptionFailureUser.java | Migrate ExceptionFailureUser integration behavior to current policy model. |
| src/test/java/de/tum/cit/ase/ares/integration/testuser/DynamicsUser.java | Migrate DynamicsUser integration behavior to current policy model. |
| src/test/java/de/tum/cit/ase/ares/integration/testuser/CommandExecutionUser.java | Migrate CommandExecutionUser integration behavior to current policy model. |
| src/test/java/de/tum/cit/ase/ares/integration/precompile/PrecompileTest.java | Write precompile scaffold into temp dir to avoid repo pollution. |
| src/test/java/de/tum/cit/ase/ares/integration/FileSystemAccessTest.java | Update FS access integration tests and policy wiring (read/overwrite/create/execute/delete). |
| src/test/java/de/tum/cit/ase/ares/integration/architecture/forbidden/SystemAccessTest.java | Adjust architecture forbidden SystemAccess tests for updated enforcement behavior. |
| src/test/java/de/tum/cit/ase/ares/integration/architecture/forbidden/FileSystemAccessReadTest.java | Fix/update architecture forbidden FS read tests (paths/assertions). |
| src/test/java/de/tum/cit/ase/ares/integration/architecture/forbidden/FileSystemAccessOverwriteTest.java | Fix/update architecture forbidden FS overwrite tests (paths/assertions). |
| src/test/java/de/tum/cit/ase/ares/integration/architecture/forbidden/FileSystemAccessDeleteTest.java | Fix/update architecture forbidden FS delete tests (fixtures/assertions). |
| src/test/java/de/tum/cit/ase/ares/integration/aop/forbidden/SystemAccessTest.java | Adjust AOP forbidden SystemAccess tests for updated enforcement behavior. |
| src/test/java/de/tum/cit/ase/ares/integration/aop/forbidden/subject/threadSystem/create/threadPoolExecutor/CreateThreadPoolExecutorMain.java | Add/update thread-creation forbidden subject for ThreadPoolExecutor. |
| src/test/java/de/tum/cit/ase/ares/integration/aop/forbidden/subject/threadSystem/create/scheduledExecutorService/CreateScheduledExecutorServiceMain.java | Add/update thread-creation forbidden subject for ScheduledExecutorService. |
| src/test/java/de/tum/cit/ase/ares/integration/aop/forbidden/subject/threadSystem/create/forkJoinPool/CreateForkJoinPoolMain.java | Add/update thread-creation forbidden subject for ForkJoinPool. |
| src/test/java/de/tum/cit/ase/ares/integration/aop/forbidden/subject/threadSystem/create/executorService/CreateExecutorServiceMain.java | Add/update thread-creation forbidden subject for ExecutorService. |
| src/test/java/de/tum/cit/ase/ares/integration/aop/forbidden/subject/networkSystem/connect/socket/SocketConnectMain.java | Add/update forbidden network socket-connect subject. |
| src/test/java/de/tum/cit/ase/ares/integration/aop/forbidden/subject/fileSystem/delete/nottrusteddir/nottrusted.txt | Add/adjust delete forbidden fixture file. |
| src/test/java/de/tum/cit/ase/ares/integration/aop/forbidden/DenialReasonAccessTest.java | Add denial-reason regression tests for AOP/toolbox SecurityException messaging. |
| src/test/java/de/tum/cit/ase/ares/integration/aop/allowed/SystemAccessTest.java | Adjust AOP allowed SystemAccess tests for updated enforcement behavior. |
| src/test/java/de/tum/cit/ase/ares/integration/aop/allowed/subject/fileSystem/read/thirdPartyPackage/ReadThirdPartyPackageMain.java | Add/update allowed third-party read subject. |
| src/test/java/de/tum/cit/ase/ares/integration/aop/allowed/subject/fileSystem/read/thirdPartyPackage/AllowedThirdPartyPackagePenguin.java | Add/update helper for third-party read subject. |
| src/test/java/de/tum/cit/ase/ares/integration/aop/allowed/subject/fileSystem/read/fileSystemProvider/ReadFileSystemProviderMain.java | Add/update allowed FS-provider read subject. |
| src/test/java/de/tum/cit/ase/ares/integration/aop/allowed/subject/fileSystem/overwrite/fileSystemProvider/WriteFileSystemProviderMain.java | Add/update allowed FS-provider overwrite subject. |
| src/test/java/de/tum/cit/ase/ares/integration/aop/allowed/subject/fileSystem/execute/desktop/ExecuteDesktopMain.java | Add/update Desktop-based execute subject (for file-read binding changes). |
| src/test/java/de/tum/cit/ase/ares/integration/aop/allowed/subject/fileSystem/delete/trusteddir/trusted.txt | Add trusted delete fixture file under dedicated directory. |
| src/test/java/de/tum/cit/ase/ares/integration/aop/allowed/subject/fileSystem/delete/fileSystemProvider/DeleteFileSystemProviderMain.java | Add/update allowed FS-provider delete subject. |
| src/test/java/de/tum/cit/ase/ares/integration/aop/allowed/FileSystemAccessTest.java | Adjust allowed FS access integration tests to new @Policy YAMLs. |
| src/test/java/de/tum/cit/ase/ares/api/securitytest/java/creator/JavaCreatorTest.java | Update creator tests for scaffold/template/policy behavior changes. |
| src/test/java/de/tum/cit/ase/ares/api/policy/director/java/SecurityPolicyJavaDirectorTest.java | Update policy director tests to match policy/schema changes. |
| src/test/java/de/tum/cit/ase/ares/api/architecture/java/wala/WalaRuleTest.java | Update WALA rule tests for cache-handling and resilience changes. |
| src/test/java/de/tum/cit/ase/ares/api/architecture/java/JavaArchitectureTestCaseSupportedTest.java | Update supported-test coverage for architecture mode changes. |
| src/test/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationAdviceThreadSystemToolboxTest.java | Add/update instrumentation thread toolbox tests (denial reasons, exemptions). |
| src/test/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationAdviceNetworkSystemToolboxTest.java | Add/update instrumentation network toolbox tests (IPv6/loopback parsing, denial reasons). |
| src/test/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationAdviceFileSystemToolboxTest.java | Add/update instrumentation FS toolbox tests (JDK-internal reads, denial reasons). |
| src/test/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationAdviceCommandSystemToolboxTest.java | Add/update instrumentation command toolbox tests (denial reasons). |
| src/main/resources/de/tum/cit/ase/ares/api/templates/architecture/java/archunit/methods/network-access-methods.txt | Update network access method list for architecture enforcement. |
| src/main/resources/de/tum/cit/ase/ares/api/localization/messages.properties | Add/update denial-reason localization keys (EN). |
| src/main/resources/de/tum/cit/ase/ares/api/localization/messages_de.properties | Repair/update German localization bundle and add missing keys. |
| src/main/resources/de/tum/cit/ase/ares/api/configuration/copyFiles/java/WalaJavaCopyFiles.csv | Fix scaffold copy-file config for WALA generator paths/counts. |
| src/main/resources/de/tum/cit/ase/ares/api/configuration/copyFiles/java/InstrumentationJavaCopyFiles.csv | Fix scaffold copy-file config for instrumentation generator paths/counts. |
| src/main/resources/de/tum/cit/ase/ares/api/configuration/copyFiles/java/AspectJAJCopyFiles.csv | Fix scaffold copy-file config for AspectJ generator paths/counts. |
| src/main/resources/de/tum/cit/ase/ares/api/configuration/copyFiles/java/ArchunitJavaCopyFiles.csv | Fix scaffold copy-file config for ArchUnit generator paths/counts. |
| src/main/java/de/tum/cit/ase/ares/api/util/ProjectSourcesFinder.java | Handle default Maven source dirs for generated scaffold. |
| src/main/java/de/tum/cit/ase/ares/api/util/FileTools.java | Adjust file tooling used by scaffold generation and test setup. |
| src/main/java/de/tum/cit/ase/ares/api/securitytest/java/writer/JavaWriter.java | Fix generated-file copy paths / placeholder counts in scaffold writer. |
| src/main/java/de/tum/cit/ase/ares/api/jupiter/JupiterSecurityExtension.java | Keep policy setup out of fixture lifecycle and stabilize extension behavior. |
| src/main/java/de/tum/cit/ase/ares/api/architecture/java/wala/JavaWalaTestCase.java | Make WALA outcome-cache loading resilient to SecurityException. |
| src/main/java/de/tum/cit/ase/ares/api/architecture/ArchitectureMode.java | Exclude Ares engine classes from student architecture analysis. |
| src/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/pointcut/JavaInstrumentationPointcutDefinitions.java | Adjust instrumentation pointcuts for corrected classifications/interceptions. |
| src/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationAdviceThreadSystemToolbox.java | Add timeout-origin exemption + denial reason suffixing in thread advice. |
| src/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationAdviceNetworkSystemToolbox.java | Fix network target parsing (loopback/IPv6) + denial reason suffixing. |
| src/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationAdviceFileSystemToolbox.java | Refine FS classification/exemptions (e.g., java.home reads) + denial reasons. |
| src/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationAdviceCommandSystemToolbox.java | Refine command execution enforcement + denial reason suffixing. |
| src/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationAdviceAbstractToolbox.java | Centralize denial-reason building and class-loading state handling. |
| src/main/java/de/tum/cit/ase/ares/api/aop/java/aspectj/adviceandpointcut/JavaAspectJThreadSystemAdviceDefinitions.aj | Mirror thread enforcement fixes in AspectJ layer. |
| src/main/java/de/tum/cit/ase/ares/api/aop/java/aspectj/adviceandpointcut/JavaAspectJNetworkSystemAdviceDefinitions.aj | Mirror network enforcement fixes in AspectJ layer. |
| src/main/java/de/tum/cit/ase/ares/api/aop/java/aspectj/adviceandpointcut/JavaAspectJFileSystemAdviceDefinitions.aj | Mirror FS enforcement fixes in AspectJ layer. |
| src/main/java/de/tum/cit/ase/ares/api/aop/java/aspectj/adviceandpointcut/JavaAspectJCommandSystemAdviceDefinitions.aj | Mirror command enforcement fixes in AspectJ layer. |
| src/main/java/de/tum/cit/ase/ares/api/aop/java/aspectj/adviceandpointcut/JavaAspectJAbstractAdviceDefinitions.aj | Mirror shared denial-reason and supporting logic in AspectJ layer. |
| pom.xml | CI/test-run stabilization (timeouts, forks, JVM args, module opens). |
| ares/api/util/LruCache.java | Supporting util updates mirrored under ares/ path. |
| ares/api/util/FileTools.java | Supporting util updates mirrored under ares/ path. |
| ares/api/templates/architecture/java/exclusions.txt | Update architecture template exclusions. |
| ares/api/templates/architecture/java/archunit/rules/THREAD_CREATION.txt | Update thread creation rule template. |
| ares/api/templates/architecture/java/archunit/rules/TERMINATE_JVM.txt | Update JVM termination rule template. |
| ares/api/templates/architecture/java/archunit/rules/SERIALIZATION.txt | Update serialization rule template. |
| ares/api/templates/architecture/java/archunit/rules/REFLECTION.txt | Update reflection rule template. |
| ares/api/templates/architecture/java/archunit/rules/PACKAGE_IMPORT.txt | Update package import rule template. |
| ares/api/templates/architecture/java/archunit/rules/NETWORK_CONNECTION.txt | Update network connection rule template. |
| ares/api/templates/architecture/java/archunit/rules/FILESYSTEM_INTERACTION.txt | Update filesystem interaction rule template. |
| ares/api/templates/architecture/java/archunit/rules/COMMAND_EXECUTION.txt | Update command execution rule template. |
| ares/api/templates/architecture/java/archunit/rules/CLASS_LOADING.txt | Update class loading rule template. |
| ares/api/templates/architecture/java/archunit/methods/thread-manipulation-methods.txt | Update thread-manipulation methods list. |
| ares/api/templates/architecture/java/archunit/methods/serializable-methods.txt | Update serializable methods list. |
| ares/api/templates/architecture/java/archunit/methods/reflection-methods.txt | Update reflection methods list. |
| ares/api/templates/architecture/java/archunit/methods/network-access-methods.txt | Update network methods list (template copy). |
| ares/api/templates/architecture/java/archunit/methods/jvm-termination-methods.txt | Update JVM termination methods list. |
| ares/api/templates/architecture/java/archunit/methods/file-system-access-methods.txt | Update FS access methods list. |
| ares/api/templates/architecture/java/archunit/methods/command-execution-methods.txt | Update command execution methods list. |
| ares/api/templates/architecture/java/archunit/methods/classloader-methods.txt | Update classloader methods list. |
| ares/api/policy/policySubComponents/PackagePermission.java | Update policy component behavior/schema for package permissions. |
| ares/api/localization/Messages.java | Update localization handling to support new denial-reason messages. |
| ares/api/archunit.properties | Update ArchUnit config for revised rules/templates. |
| ares/api/architecture/java/JavaArchitectureTestCaseSupported.java | Update supported architecture test-case wiring. |
| ares/api/architecture/java/FileHandlerConstants.java | Update FS constants to match enforcement/scaffold changes. |
| ares/api/architecture/java/archunit/TransitivelyAccessesMethodsCondition.java | Update ArchUnit condition behavior for revised method lists. |
| ares/api/architecture/java/archunit/JavaArchunitTestCaseCollection.java | Update ArchUnit test-case collection behavior for revised analysis scope. |
| ares/api/architecture/ArchitectureTestCaseSupported.java | Update base supported architecture test-case wiring. |
| AGENTS.md | Add repo-wide conventions for network testing (external echo server + skip semantics). |
| .gitignore | Update ignores to prevent generated artifacts polluting the repo. |
| .github/workflows/maven.yml | CI adjustments (timeouts/steps) for suite stabilization. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // <editor-fold desc="Within Paths"> | ||
| private static final String FILE_READ_WITHIN_PATH = "test-classes/de/tum/cit/ase/ares/integration/aop/forbidden/subject/fileSystem/read/ByteStream"; | ||
| private static final String COMMAND_RUNTIME_WITHIN_PATH = "test-classes/de/tum/cit/ase/ares/integration/aop/forbidden/subject/commandSystem/execute/runtime"; | ||
| private static final String THREAD_EXECUTOR_SERVICE_WITHIN_PATH = "test-classes/de/tum/cit/ase/ares/integration/aop/forbidden/subject/threadSystem/create/executorService"; | ||
| private static final String NETWORK_SOCKET_WITHIN_PATH = "test-classes/de/tum/cit/ase/ares/integration/aop/forbidden/subject/networkSystem/connect/socket"; | ||
| // </editor-fold> |
| try { | ||
| NetworkPenguin.tryConnect(host, PORT, MESSAGE); | ||
| } catch (SecurityException e) { | ||
| // An Ares block of an explicitly allowed connection is a real failure. | ||
| throw e; | ||
| } catch (IOException e) { | ||
| // No Ares block: the external echo server is simply not reachable in this | ||
| // environment (see AGENTS.md). The security property under test - that an | ||
| // allowed connection is NOT blocked by Ares - already holds, so this is not | ||
| // a failure. The functional round-trip is exercised by CI, which provides | ||
| // the external echo server. | ||
| } |
| private void assertThreadErrorMessage(String actualMessage, String operationText) { | ||
| assertTrue(actualMessage.contains("Thread Security Error"), | ||
| "Exception message should contain 'Thread Security Error'" + System.lineSeparator() + actualMessage); | ||
| assertTrue(actualMessage.contains("Ares Security Error"), | ||
| "Exception message should contain 'Ares Security Error'" + System.lineSeparator() + actualMessage); |
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (5)
src/test/java/de/tum/cit/ase/ares/integration/ThreadTest.java (1)
73-100:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winRestore operation-specific assertion coverage in
assertThreadErrorMessage.
operationTextis no longer used, and all scenarios now require"create Thread". That weakens per-case validation and can miss regressions for non-create operations.Possible fix
- assertTrue(actualMessage.contains("create Thread"), - "Exception message should indicate an illegal thread creation" + System.lineSeparator() - + actualMessage); + assertTrue(actualMessage.contains(operationText), + "Exception message should contain operation text '" + operationText + "'" + + System.lineSeparator() + actualMessage);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/test/java/de/tum/cit/ase/ares/integration/ThreadTest.java` around lines 73 - 100, The test lost per-operation checks by hardcoding "create Thread"; update assertThreadErrorMessage to verify the passed operationText is present in actualMessage instead of the fixed "create Thread" string (e.g., replace the assertTrue(actualMessage.contains("create Thread"), ...) with an assert that actualMessage.contains(operationText) and include operationText in the assertion failure message); ensure assertThreadSecurityException still passes the intended operationText through to assertThreadErrorMessage and consider a null-check/fallback if any callers pass null so tests remain deterministic.src/test/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationAdviceNetworkSystemToolboxTest.java (1)
186-188:⚠️ Potential issue | 🟠 Major | ⚡ Quick winReplace the in-JVM socket listener with an external echo endpoint.
This test spins up
ServerSocketinside the test JVM, which breaks the required test boundary and reintroduces bind/lifecycle flakiness. Use a configurable external echo server (default loopback:25565) and abort/skip via assumptions when unreachable.Suggested direction
- try (ServerSocket serverSocket = new ServerSocket(0); - Socket socket = new Socket("127.0.0.1", serverSocket.getLocalPort()); - Socket acceptedSocket = serverSocket.accept()) { + String host = System.getProperty("ares.echo.host", "127.0.0.1"); + int port = Integer.getInteger("ares.echo.port", 25565); + // assumption/abort when echo server is unavailable + try (Socket socket = new Socket(host, port)) { Object target = toTarget.invoke(null, socket); ... - assertEquals("127.0.0.1:" + serverSocket.getLocalPort(), toDisplayString.invoke(target)); + assertEquals(host + ":" + port, toDisplayString.invoke(target)); }As per coding guidelines,
**/*Test.java: “never spin up an internal server … outgoing-connection tests must connect to an external echo server … skip if unreachable.”🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/test/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationAdviceNetworkSystemToolboxTest.java` around lines 186 - 188, The test in JavaInstrumentationAdviceNetworkSystemToolboxTest currently creates an in-JVM ServerSocket and Socket (the try-with-resources block using ServerSocket and Socket/acceptedSocket); replace that with a connection to a configurable external echo endpoint (default 127.0.0.1:25565) and use JUnit assumptions (e.g., Assumptions.assumeTrue or assumeTrue with a quick connect probe) to skip the test when the endpoint is unreachable; ensure the test reads/writes to the external echo server instead of accepting an internal socket and remove the ServerSocket/acceptedSocket code paths so lifecycle/bind flakiness is avoided.Source: Coding guidelines
src/test/java/de/tum/cit/ase/ares/integration/testuser/NetworkUser.java (1)
64-94:⚠️ Potential issue | 🔴 Critical | 🏗️ Heavy liftRemove internal server creation from sandboxed tests.
The three server test methods (
serverAllowedAndAccept,serverAllowedAndTimeout,serverNotAllowed) violate the coding guideline by spinning up internal servers within the sandboxed test JVM viaNetworkPenguin.tryStartServer(). The guideline explicitly forbids this pattern because the server itself becomes subject to the security policy being tested, creating circular dependencies and in-JVM lifecycle flakiness.The
serverAllowedAndAccepttest is particularly problematic: it creates a server (line 68) and then connects to it (line 76), exactly the self-hosted listener pattern the guideline prohibits.Test fixtures must live outside the security boundary. Consider removing these server tests entirely or restructuring them to use an external test service similar to the echo server approach in
connectLocallyAllowed.As per coding guidelines: "In sandboxed test JVMs, never spin up an internal server (echo server, socket listener) to test incoming or outgoing connections. Test fixtures must live outside the security boundary being tested."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/test/java/de/tum/cit/ase/ares/integration/testuser/NetworkUser.java` around lines 64 - 94, Remove or relocate the three sandboxed tests that start an in-JVM server: serverAllowedAndAccept, serverAllowedAndTimeout, and serverNotAllowed; do not call NetworkPenguin.tryStartServer from within the sandboxed test JVM. Instead either delete these tests or rewrite them to use an external fixture (an out-of-process echo/test server like the one used by connectLocallyAllowed) so the server lifecycle and network behavior live outside the security boundary being tested; update test references and any assertions accordingly to point to the external test service.Source: Coding guidelines
src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyOnePathAllowedExecute.yaml (1)
3-3:⚠️ Potential issue | 🟠 Major | ⚡ Quick winUse the AspectJ runtime identifier in this AspectJ policy file.
Line 3 currently selects instrumentation mode in an
archunit/aspectjpolicy. This can route checks through the wrong enforcement path and make integration expectations inconsistent.Suggested fix
- theFollowingProgrammingLanguageConfigurationIsUsed: JAVA_USING_MAVEN_ARCHUNIT_AND_INSTRUMENTATION + theFollowingProgrammingLanguageConfigurationIsUsed: JAVA_USING_MAVEN_ARCHUNIT_AND_ASPECTJ🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyOnePathAllowedExecute.yaml` at line 3, The policy currently sets theProgrammingLanguage config key theFollowingProgrammingLanguageConfigurationIsUsed to JAVA_USING_MAVEN_ARCHUNIT_AND_INSTRUMENTATION; change that value to the AspectJ runtime identifier (use JAVA_USING_MAVEN_ARCHUNIT_ASPECTJ_RUNTIME) so the AspectJ policy routes through the runtime enforcement path instead of the instrumentation path.src/main/java/de/tum/cit/ase/ares/api/aop/java/aspectj/adviceandpointcut/JavaAspectJNetworkSystemAdviceDefinitions.aj (1)
601-621:⚠️ Potential issue | 🟠 Major | ⚡ Quick winMask consumed host/port pairs before the fallback parameter scan.
parametersToTarget()already resolves adjacent(host, port)pairs, but this block then rescans the original array element-by-element. For allowedInetAddresspairs, the second pass turns the consumed host into<host>:-1and rejects it unless the policy also uses the-1wildcard port, so AspectJ still false-fails cases the instrumentation backend now handles correctly.Suggested fix
+ java.util.BitSet consumedParameterIndices = new java.util.BitSet(parameters == null ? 0 : parameters.length); `@Nullable` - NetworkTarget targetFromParameters = (parameters == null || parameters.length == 0) ? null - : parametersToTarget(parameters); + NetworkTarget targetFromParameters = (parameters == null || parameters.length == 0) ? null + : parametersToTarget(parameters, consumedParameterIndices); if (targetFromParameters != null && checkIfNetworkIsForbidden(targetFromParameters, allowedHosts, allowedPorts)) { throw new SecurityException(localize( "security.advice.illegal.network.execution", @@ } `@Nullable` - String networkIllegallyInteractedThroughParameter = (parameters == null || parameters.length == 0) ? null - : checkIfVariableCriteriaIsViolated(parameters, allowedHosts, allowedPorts, + Object[] residualParameters = parameters; + if (parameters != null && !consumedParameterIndices.isEmpty()) { + residualParameters = new Object[parameters.length]; + for (int i = 0; i < parameters.length; i++) { + residualParameters[i] = consumedParameterIndices.get(i) ? null : parameters[i]; + } + } + String networkIllegallyInteractedThroughParameter = (residualParameters == null || residualParameters.length == 0) ? null + : checkIfVariableCriteriaIsViolated(residualParameters, allowedHosts, allowedPorts, NETWORK_SYSTEM_IGNORE_PARAMETERS_EXCEPT.getOrDefault(declaringTypeName + "." + methodName, IgnoreValues.NONE));🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/java/de/tum/cit/ase/ares/api/aop/java/aspectj/adviceandpointcut/JavaAspectJNetworkSystemAdviceDefinitions.aj` around lines 601 - 621, The parametersToTarget(...) pass consumes adjacent (host,port) pairs but you still run checkIfVariableCriteriaIsViolated(...) on the original parameters; before calling checkIfVariableCriteriaIsViolated, mask or remove the parameters that parametersToTarget consumed so they aren't rescanned: after calling parametersToTarget(parameters) identify the indices/values that formed the host/port pair(s) (reuse the same parsing logic as parametersToTarget), then overwrite those parameter entries in the parameters array (or a shallow copy passed to checkIfVariableCriteriaIsViolated) with a sentinel (e.g., null or a masked value) so checkIfVariableCriteriaIsViolated(…, NETWORK_SYSTEM_IGNORE_PARAMETERS_EXCEPT.getOrDefault(...)) will skip them and not produce false negatives.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@src/main/java/de/tum/cit/ase/ares/api/aop/java/aspectj/adviceandpointcut/JavaAspectJFileSystemAdviceDefinitions.aj`:
- Around line 109-127: isExemptSystemFileAccess currently exempts any "read"
under java.home, which lets student code read arbitrary JDK files; update the
helper (method isExemptSystemFileAccess and any call sites like the AspectJ
pointcut at lines referenced) to stop blanket-allowing reads: either require an
explicit internal-origin signal/flag passed into isExemptSystemFileAccess (or
set by the JVM-internal call path) before returning true for "read", or narrow
the allowed read paths to a tight allowlist of specific JVM-only
files/directories (e.g. specific conf/security or native/lib paths) and only
return true when path matches those exact allowed subpaths; also ensure
NATIVE_LIBRARY_SUFFIXES handling remains unchanged for "execute".
In
`@src/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/pointcut/JavaInstrumentationPointcutDefinitions.java`:
- Around line 597-598: The URL.openStream method is wrongly classified as a
file-read; remove "openStream" from the methodsWhichCanReadFiles map (where it's
currently listed) and add it to the methodsWhichCanConnectToNetwork entry for
"java.net.URL" (so the map entry with Map.entry("java.net.URL", List.of(...))
includes "openStream"). This ensures URL.fetches use the network connect/receive
pointcuts (so they are handled by the network advice instead of
JavaInstrumentationReadPath*Advice /
JavaInstrumentationAdviceFileSystemToolbox.checkFileSystemInteraction).
- Around line 474-481: The instrumented handling for java.awt.Desktop is wrong:
remove or relocate "java.awt.Desktop" (and its methods
open/edit/print/browse/browseFileDirectory) out of methodsWhichCanReadFiles and
place it into the correct action/bucket (or add a dedicated Desktop bucket) in
JavaInstrumentationPointcutDefinitions.methodsWhichCanReadFiles/methodsWhichCanExecuteFiles,
and then update JavaInstrumentationAdviceFileSystemToolbox.variableToPath to
explicitly handle non-file URIs/URLs (or make it return a sentinel that causes
checkIfPathIsForbidden to treat them as forbidden) so that
checkIfPathIsForbidden does not silently allow non-file Desktop targets; ensure
changes reference methodsWhichCanReadFiles, methodsWhichCanExecuteFiles,
JavaInstrumentationAdviceFileSystemToolbox.variableToPath and
checkIfPathIsForbidden and cover Desktop methods
open/edit/print/browse/browseFileDirectory.
In `@src/main/java/de/tum/cit/ase/ares/api/util/ProjectSourcesFinder.java`:
- Around line 95-103: The current logic in ProjectSourcesFinder prematurely
returns null when a <sourceDirectory> element exists but its text content is
empty; change the handling in the method that reads sourceDirectoryNodes (the
block that returns toRelativeSourceDirectory(sourceDirectoryPropertyValue)) to
treat blank/whitespace-only values as if the element were absent (i.e., trim and
check length > 0 before returning), so the default fallback
(DEFAULT_MAVEN_SOURCE_DIRECTORY) can be used; apply the same blank-check fix to
the analogous block around the code flagged at lines 110–113.
In
`@src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyOneNetworkConnectionAllowed.yaml`:
- Around line 11-16: The policy's network connection entry under
regardingNetworkConnections currently uses onThePort: 12345 causing tests to
target the wrong echo server; update the entry (the object with onTheHost,
onThePort, openConnections, sendData, receiveData) to use the external loopback
echo-server port 25565 (keep onTheHost as "127.0.0.1" and preserve the other
flags) so the integration tests connect to the expected external echo server.
---
Outside diff comments:
In
`@src/main/java/de/tum/cit/ase/ares/api/aop/java/aspectj/adviceandpointcut/JavaAspectJNetworkSystemAdviceDefinitions.aj`:
- Around line 601-621: The parametersToTarget(...) pass consumes adjacent
(host,port) pairs but you still run checkIfVariableCriteriaIsViolated(...) on
the original parameters; before calling checkIfVariableCriteriaIsViolated, mask
or remove the parameters that parametersToTarget consumed so they aren't
rescanned: after calling parametersToTarget(parameters) identify the
indices/values that formed the host/port pair(s) (reuse the same parsing logic
as parametersToTarget), then overwrite those parameter entries in the parameters
array (or a shallow copy passed to checkIfVariableCriteriaIsViolated) with a
sentinel (e.g., null or a masked value) so checkIfVariableCriteriaIsViolated(…,
NETWORK_SYSTEM_IGNORE_PARAMETERS_EXCEPT.getOrDefault(...)) will skip them and
not produce false negatives.
In
`@src/test/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationAdviceNetworkSystemToolboxTest.java`:
- Around line 186-188: The test in
JavaInstrumentationAdviceNetworkSystemToolboxTest currently creates an in-JVM
ServerSocket and Socket (the try-with-resources block using ServerSocket and
Socket/acceptedSocket); replace that with a connection to a configurable
external echo endpoint (default 127.0.0.1:25565) and use JUnit assumptions
(e.g., Assumptions.assumeTrue or assumeTrue with a quick connect probe) to skip
the test when the endpoint is unreachable; ensure the test reads/writes to the
external echo server instead of accepting an internal socket and remove the
ServerSocket/acceptedSocket code paths so lifecycle/bind flakiness is avoided.
In `@src/test/java/de/tum/cit/ase/ares/integration/testuser/NetworkUser.java`:
- Around line 64-94: Remove or relocate the three sandboxed tests that start an
in-JVM server: serverAllowedAndAccept, serverAllowedAndTimeout, and
serverNotAllowed; do not call NetworkPenguin.tryStartServer from within the
sandboxed test JVM. Instead either delete these tests or rewrite them to use an
external fixture (an out-of-process echo/test server like the one used by
connectLocallyAllowed) so the server lifecycle and network behavior live outside
the security boundary being tested; update test references and any assertions
accordingly to point to the external test service.
In `@src/test/java/de/tum/cit/ase/ares/integration/ThreadTest.java`:
- Around line 73-100: The test lost per-operation checks by hardcoding "create
Thread"; update assertThreadErrorMessage to verify the passed operationText is
present in actualMessage instead of the fixed "create Thread" string (e.g.,
replace the assertTrue(actualMessage.contains("create Thread"), ...) with an
assert that actualMessage.contains(operationText) and include operationText in
the assertion failure message); ensure assertThreadSecurityException still
passes the intended operationText through to assertThreadErrorMessage and
consider a null-check/fallback if any callers pass null so tests remain
deterministic.
In
`@src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyOnePathAllowedExecute.yaml`:
- Line 3: The policy currently sets theProgrammingLanguage config key
theFollowingProgrammingLanguageConfigurationIsUsed to
JAVA_USING_MAVEN_ARCHUNIT_AND_INSTRUMENTATION; change that value to the AspectJ
runtime identifier (use JAVA_USING_MAVEN_ARCHUNIT_ASPECTJ_RUNTIME) so the
AspectJ policy routes through the runtime enforcement path instead of the
instrumentation path.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 4e337b2b-778c-40bc-8120-de606383bc3e
⛔ Files ignored due to path filters (4)
src/main/resources/de/tum/cit/ase/ares/api/configuration/copyFiles/java/ArchunitJavaCopyFiles.csvis excluded by!**/*.csvsrc/main/resources/de/tum/cit/ase/ares/api/configuration/copyFiles/java/AspectJAJCopyFiles.csvis excluded by!**/*.csvsrc/main/resources/de/tum/cit/ase/ares/api/configuration/copyFiles/java/InstrumentationJavaCopyFiles.csvis excluded by!**/*.csvsrc/main/resources/de/tum/cit/ase/ares/api/configuration/copyFiles/java/WalaJavaCopyFiles.csvis excluded by!**/*.csv
📒 Files selected for processing (137)
.github/workflows/maven.yml.gitignoreAGENTS.mdares/api/architecture/ArchitectureTestCaseSupported.javaares/api/architecture/java/FileHandlerConstants.javaares/api/architecture/java/JavaArchitectureTestCaseSupported.javaares/api/architecture/java/archunit/JavaArchunitTestCaseCollection.javaares/api/architecture/java/archunit/TransitivelyAccessesMethodsCondition.javaares/api/archunit.propertiesares/api/localization/Messages.javaares/api/policy/policySubComponents/PackagePermission.javaares/api/templates/architecture/java/archunit/methods/classloader-methods.txtares/api/templates/architecture/java/archunit/methods/command-execution-methods.txtares/api/templates/architecture/java/archunit/methods/file-system-access-methods.txtares/api/templates/architecture/java/archunit/methods/jvm-termination-methods.txtares/api/templates/architecture/java/archunit/methods/network-access-methods.txtares/api/templates/architecture/java/archunit/methods/reflection-methods.txtares/api/templates/architecture/java/archunit/methods/serializable-methods.txtares/api/templates/architecture/java/archunit/methods/thread-manipulation-methods.txtares/api/templates/architecture/java/archunit/rules/CLASS_LOADING.txtares/api/templates/architecture/java/archunit/rules/COMMAND_EXECUTION.txtares/api/templates/architecture/java/archunit/rules/FILESYSTEM_INTERACTION.txtares/api/templates/architecture/java/archunit/rules/NETWORK_CONNECTION.txtares/api/templates/architecture/java/archunit/rules/PACKAGE_IMPORT.txtares/api/templates/architecture/java/archunit/rules/REFLECTION.txtares/api/templates/architecture/java/archunit/rules/SERIALIZATION.txtares/api/templates/architecture/java/archunit/rules/TERMINATE_JVM.txtares/api/templates/architecture/java/archunit/rules/THREAD_CREATION.txtares/api/templates/architecture/java/exclusions.txtares/api/util/FileTools.javaares/api/util/LruCache.javapom.xmlsrc/main/java/de/tum/cit/ase/ares/api/aop/java/aspectj/adviceandpointcut/JavaAspectJAbstractAdviceDefinitions.ajsrc/main/java/de/tum/cit/ase/ares/api/aop/java/aspectj/adviceandpointcut/JavaAspectJCommandSystemAdviceDefinitions.ajsrc/main/java/de/tum/cit/ase/ares/api/aop/java/aspectj/adviceandpointcut/JavaAspectJFileSystemAdviceDefinitions.ajsrc/main/java/de/tum/cit/ase/ares/api/aop/java/aspectj/adviceandpointcut/JavaAspectJNetworkSystemAdviceDefinitions.ajsrc/main/java/de/tum/cit/ase/ares/api/aop/java/aspectj/adviceandpointcut/JavaAspectJThreadSystemAdviceDefinitions.ajsrc/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationAdviceAbstractToolbox.javasrc/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationAdviceCommandSystemToolbox.javasrc/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationAdviceFileSystemToolbox.javasrc/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationAdviceNetworkSystemToolbox.javasrc/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationAdviceThreadSystemToolbox.javasrc/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/pointcut/JavaInstrumentationPointcutDefinitions.javasrc/main/java/de/tum/cit/ase/ares/api/architecture/ArchitectureMode.javasrc/main/java/de/tum/cit/ase/ares/api/architecture/java/wala/JavaWalaTestCase.javasrc/main/java/de/tum/cit/ase/ares/api/jupiter/JupiterSecurityExtension.javasrc/main/java/de/tum/cit/ase/ares/api/securitytest/java/writer/JavaWriter.javasrc/main/java/de/tum/cit/ase/ares/api/util/FileTools.javasrc/main/java/de/tum/cit/ase/ares/api/util/ProjectSourcesFinder.javasrc/main/resources/de/tum/cit/ase/ares/api/localization/messages.propertiessrc/main/resources/de/tum/cit/ase/ares/api/localization/messages_de.propertiessrc/main/resources/de/tum/cit/ase/ares/api/templates/architecture/java/archunit/methods/network-access-methods.txtsrc/test/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationAdviceCommandSystemToolboxTest.javasrc/test/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationAdviceFileSystemToolboxTest.javasrc/test/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationAdviceNetworkSystemToolboxTest.javasrc/test/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationAdviceThreadSystemToolboxTest.javasrc/test/java/de/tum/cit/ase/ares/api/architecture/java/JavaArchitectureTestCaseSupportedTest.javasrc/test/java/de/tum/cit/ase/ares/api/architecture/java/wala/WalaRuleTest.javasrc/test/java/de/tum/cit/ase/ares/api/policy/director/java/SecurityPolicyJavaDirectorTest.javasrc/test/java/de/tum/cit/ase/ares/api/securitytest/java/creator/JavaCreatorTest.javasrc/test/java/de/tum/cit/ase/ares/integration/FileSystemAccessTest.javasrc/test/java/de/tum/cit/ase/ares/integration/ThreadTest.javasrc/test/java/de/tum/cit/ase/ares/integration/aop/allowed/FileSystemAccessTest.javasrc/test/java/de/tum/cit/ase/ares/integration/aop/allowed/SystemAccessTest.javasrc/test/java/de/tum/cit/ase/ares/integration/aop/allowed/subject/fileSystem/delete/fileSystemProvider/DeleteFileSystemProviderMain.javasrc/test/java/de/tum/cit/ase/ares/integration/aop/allowed/subject/fileSystem/delete/trusteddir/trusted.txtsrc/test/java/de/tum/cit/ase/ares/integration/aop/allowed/subject/fileSystem/execute/desktop/ExecuteDesktopMain.javasrc/test/java/de/tum/cit/ase/ares/integration/aop/allowed/subject/fileSystem/overwrite/fileSystemProvider/WriteFileSystemProviderMain.javasrc/test/java/de/tum/cit/ase/ares/integration/aop/allowed/subject/fileSystem/read/fileSystemProvider/ReadFileSystemProviderMain.javasrc/test/java/de/tum/cit/ase/ares/integration/aop/allowed/subject/fileSystem/read/thirdPartyPackage/AllowedThirdPartyPackagePenguin.javasrc/test/java/de/tum/cit/ase/ares/integration/aop/allowed/subject/fileSystem/read/thirdPartyPackage/ReadThirdPartyPackageMain.javasrc/test/java/de/tum/cit/ase/ares/integration/aop/forbidden/DenialReasonAccessTest.javasrc/test/java/de/tum/cit/ase/ares/integration/aop/forbidden/SystemAccessTest.javasrc/test/java/de/tum/cit/ase/ares/integration/aop/forbidden/subject/fileSystem/delete/nottrusteddir/nottrusted.txtsrc/test/java/de/tum/cit/ase/ares/integration/aop/forbidden/subject/networkSystem/connect/socket/SocketConnectMain.javasrc/test/java/de/tum/cit/ase/ares/integration/aop/forbidden/subject/threadSystem/create/executorService/CreateExecutorServiceMain.javasrc/test/java/de/tum/cit/ase/ares/integration/aop/forbidden/subject/threadSystem/create/forkJoinPool/CreateForkJoinPoolMain.javasrc/test/java/de/tum/cit/ase/ares/integration/aop/forbidden/subject/threadSystem/create/scheduledExecutorService/CreateScheduledExecutorServiceMain.javasrc/test/java/de/tum/cit/ase/ares/integration/aop/forbidden/subject/threadSystem/create/threadPoolExecutor/CreateThreadPoolExecutorMain.javasrc/test/java/de/tum/cit/ase/ares/integration/architecture/forbidden/FileSystemAccessDeleteTest.javasrc/test/java/de/tum/cit/ase/ares/integration/architecture/forbidden/FileSystemAccessOverwriteTest.javasrc/test/java/de/tum/cit/ase/ares/integration/architecture/forbidden/FileSystemAccessReadTest.javasrc/test/java/de/tum/cit/ase/ares/integration/architecture/forbidden/SystemAccessTest.javasrc/test/java/de/tum/cit/ase/ares/integration/precompile/PrecompileTest.javasrc/test/java/de/tum/cit/ase/ares/integration/testuser/CommandExecutionUser.javasrc/test/java/de/tum/cit/ase/ares/integration/testuser/DynamicsUser.javasrc/test/java/de/tum/cit/ase/ares/integration/testuser/ExceptionFailureUser.javasrc/test/java/de/tum/cit/ase/ares/integration/testuser/FileSystemAccessUser.javasrc/test/java/de/tum/cit/ase/ares/integration/testuser/InputOutputUser.javasrc/test/java/de/tum/cit/ase/ares/integration/testuser/JqwickUser.javasrc/test/java/de/tum/cit/ase/ares/integration/testuser/NetworkUser.javasrc/test/java/de/tum/cit/ase/ares/integration/testuser/PackageAccessUser.javasrc/test/java/de/tum/cit/ase/ares/integration/testuser/PrivilegedExceptionUser.javasrc/test/java/de/tum/cit/ase/ares/integration/testuser/ReflectionTestUtilsUser.javasrc/test/java/de/tum/cit/ase/ares/integration/testuser/SecurityUser.javasrc/test/java/de/tum/cit/ase/ares/integration/testuser/StructuralUser.javasrc/test/java/de/tum/cit/ase/ares/integration/testuser/ThreadUser.javasrc/test/java/de/tum/cit/ase/ares/integration/testuser/TrustedClassesUser.javasrc/test/java/de/tum/cit/ase/ares/integration/testuser/ValidationUser.javasrc/test/java/de/tum/cit/ase/ares/integration/testuser/subject/architectureTests/fileSystem/FileSystemAccessPenguin.javasrc/test/java/example/student/InstrumentationSecurityProbe.javasrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/PolicyOnePathAllowedExecuteOneCommandExecutionAllowed.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/PolicyOnePathAllowedRead.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyDynamicsUser.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyExceptionFailureUser.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyInputOutputUser.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyJqwickUser.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyLoopbackEchoConnectionAllowed.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyOneNetworkConnectionAllowed.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyOnePathAllowedDelete.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyOnePathAllowedDeleteOneThreadAllowed.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyOnePathAllowedExecute.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyOnePathAllowedOverwrite.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyOnePathAllowedRead.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyOnePathAllowedReadOverwriteDelete.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyPrivilegedExceptionUser.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyReflectionTestUtilsUser.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyValidationUser.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/instrumentation/PolicyOnePathAllowedDelete.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/instrumentation/PolicyOnePathAllowedDeleteOneThreadAllowed.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/instrumentation/PolicyOnePathAllowedExecute.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/instrumentation/PolicyOnePathAllowedOverwrite.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/instrumentation/PolicyOnePathAllowedRead.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/instrumentation/PolicyOnePathAllowedReadOverwriteDelete.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/wala/aspectj/PolicyOneNetworkConnectionAllowed.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/wala/aspectj/PolicyOnePathAllowedDelete.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/wala/aspectj/PolicyOnePathAllowedDeleteOneThreadAllowed.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/wala/aspectj/PolicyOnePathAllowedExecute.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/wala/aspectj/PolicyOnePathAllowedOverwrite.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/wala/aspectj/PolicyOnePathAllowedRead.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/wala/aspectj/PolicyOnePathAllowedReadOverwriteDelete.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/wala/instrumentation/PolicyOnePathAllowedDelete.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/wala/instrumentation/PolicyOnePathAllowedDeleteOneThreadAllowed.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/wala/instrumentation/PolicyOnePathAllowedExecute.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/wala/instrumentation/PolicyOnePathAllowedOverwrite.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/wala/instrumentation/PolicyOnePathAllowedRead.yamlsrc/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/wala/instrumentation/PolicyOnePathAllowedReadOverwriteDelete.yaml
💤 Files with no reviewable changes (37)
- ares/api/templates/architecture/java/exclusions.txt
- ares/api/templates/architecture/java/archunit/rules/CLASS_LOADING.txt
- src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/PolicyOnePathAllowedRead.yaml
- ares/api/templates/architecture/java/archunit/rules/SERIALIZATION.txt
- ares/api/templates/architecture/java/archunit/rules/NETWORK_CONNECTION.txt
- ares/api/templates/architecture/java/archunit/methods/file-system-access-methods.txt
- ares/api/templates/architecture/java/archunit/methods/classloader-methods.txt
- ares/api/templates/architecture/java/archunit/rules/TERMINATE_JVM.txt
- ares/api/templates/architecture/java/archunit/rules/PACKAGE_IMPORT.txt
- ares/api/templates/architecture/java/archunit/rules/THREAD_CREATION.txt
- ares/api/localization/Messages.java
- ares/api/templates/architecture/java/archunit/rules/COMMAND_EXECUTION.txt
- ares/api/templates/architecture/java/archunit/methods/jvm-termination-methods.txt
- ares/api/templates/architecture/java/archunit/methods/serializable-methods.txt
- ares/api/templates/architecture/java/archunit/methods/thread-manipulation-methods.txt
- ares/api/util/LruCache.java
- src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/PolicyOnePathAllowedExecuteOneCommandExecutionAllowed.yaml
- ares/api/archunit.properties
- ares/api/policy/policySubComponents/PackagePermission.java
- ares/api/templates/architecture/java/archunit/methods/reflection-methods.txt
- ares/api/templates/architecture/java/archunit/rules/REFLECTION.txt
- ares/api/templates/architecture/java/archunit/rules/FILESYSTEM_INTERACTION.txt
- ares/api/architecture/java/archunit/JavaArchunitTestCaseCollection.java
- ares/api/architecture/java/FileHandlerConstants.java
- src/test/java/de/tum/cit/ase/ares/integration/testuser/FileSystemAccessUser.java
- src/test/java/de/tum/cit/ase/ares/integration/testuser/CommandExecutionUser.java
- ares/api/architecture/ArchitectureTestCaseSupported.java
- ares/api/templates/architecture/java/archunit/methods/command-execution-methods.txt
- ares/api/util/FileTools.java
- src/test/java/de/tum/cit/ase/ares/integration/FileSystemAccessTest.java
- src/test/java/de/tum/cit/ase/ares/integration/testuser/SecurityUser.java
- ares/api/architecture/java/JavaArchitectureTestCaseSupported.java
- ares/api/templates/architecture/java/archunit/methods/network-access-methods.txt
- ares/api/architecture/java/archunit/TransitivelyAccessesMethodsCondition.java
- src/test/java/de/tum/cit/ase/ares/integration/testuser/ThreadUser.java
- src/test/java/de/tum/cit/ase/ares/integration/testuser/PackageAccessUser.java
- src/test/java/de/tum/cit/ase/ares/integration/testuser/subject/architectureTests/fileSystem/FileSystemAccessPenguin.java
| // Reading an instance's declared fields is best-effort: when the JVM refuses | ||
| // access to a field (e.g. a JDK-internal field reached via Ares's own timeout | ||
| // executor), skip that field instead of turning a JDK-side reflection limit into | ||
| // an Ares-Code SecurityException that would abort otherwise legal student code. | ||
| // The security check still runs over the parameters and the accessible fields. | ||
| // Mirrors the instrumentation backend and the network AspectJ advice. | ||
| @Nonnull Object[] attributes = new Object[0]; | ||
| if (instance != null) { | ||
| try { | ||
| @Nonnull Field[] fields = instance.getClass().getDeclaredFields(); | ||
| attributes = new Object[fields.length]; | ||
| for (int i = 0; i < fields.length; i++) { | ||
| try { | ||
| fields[i].setAccessible(true); | ||
| attributes[i] = fields[i].get(instance); | ||
| } catch (InaccessibleObjectException e) { | ||
| throw new SecurityException(localize("security.instrumentation.inaccessible.object.exception", fields[i].getName(), instance.getClass().getName()), e); | ||
| } catch (IllegalAccessException e) { | ||
| throw new SecurityException(localize("security.instrumentation.illegal.access.exception", fields[i].getName(), instance.getClass().getName()), e); | ||
| } catch (IllegalArgumentException e) { | ||
| throw new SecurityException(localize("security.instrumentation.illegal.argument.exception", fields[i].getName(), fields[i].getDeclaringClass().getName(), instance.getClass().getName()), e); | ||
| } catch (NullPointerException e) { | ||
| throw new SecurityException(localize("security.instrumentation.null.pointer.exception", fields[i].getName(), instance.getClass().getName()), e); | ||
| } catch (ExceptionInInitializerError e) { | ||
| throw new SecurityException(localize("security.instrumentation.exception.in-initializer.error", fields[i].getName(), instance.getClass().getName()), e); | ||
| } | ||
| @Nonnull Field[] fields = instance.getClass().getDeclaredFields(); | ||
| attributes = new Object[fields.length]; | ||
| for (int i = 0; i < fields.length; i++) { | ||
| try { | ||
| fields[i].setAccessible(true); | ||
| attributes[i] = fields[i].get(instance); | ||
| } catch (InaccessibleObjectException | ||
| | IllegalAccessException | ||
| | IllegalArgumentException | ||
| | NullPointerException | ||
| | ExceptionInInitializerError ignored) { | ||
| attributes[i] = null; | ||
| } |
There was a problem hiding this comment.
Fail-closed is required when the command-carrying field cannot be inspected
Line 489 currently downgrades reflection failures to null, which can let ProcessBuilder.start() bypass command allowlist enforcement when command is unreadable. This turns an enforcement failure into an allow decision.
Suggested fix (fail closed for critical command field reads)
- `@Nonnull` Object[] attributes = new Object[0];
+ `@Nonnull` Object[] attributes = new Object[0];
+ boolean criticalCommandFieldUnreadable = false;
+ String signatureWithoutModifiers = extractMethodNameWithoutModifiers(fullMethodSignature);
if (instance != null) {
`@Nonnull` Field[] fields = instance.getClass().getDeclaredFields();
attributes = new Object[fields.length];
for (int i = 0; i < fields.length; i++) {
try {
fields[i].setAccessible(true);
attributes[i] = fields[i].get(instance);
} catch (InaccessibleObjectException
| IllegalAccessException
| IllegalArgumentException
| NullPointerException
- | ExceptionInInitializerError ignored) {
+ | ExceptionInInitializerError ignored) {
attributes[i] = null;
+ if ("java.lang.ProcessBuilder.start".equals(signatureWithoutModifiers)
+ && "command".equals(fields[i].getName())) {
+ criticalCommandFieldUnreadable = true;
+ }
}
}
}
@@
+ if (criticalCommandFieldUnreadable) {
+ throw new SecurityException(localize(
+ "security.advice.illegal.command.execution",
+ commandSystemMethodToCheck,
+ action,
+ "<unknown>",
+ fullMethodSignature + (studentCalledMethod == null ? "" : " (called by " + studentCalledMethod + ")")
+ + " | " + buildDenialReason(noAllowRuleConfigured)
+ ));
+ }| private static boolean isExemptSystemFileAccess(@Nonnull String action, @Nonnull String path) { | ||
| if (path == null || !path.startsWith(System.getProperty("java.home"))) { | ||
| return false; | ||
| } | ||
| // JDK-internal reads under JAVA_HOME (e.g. the crypto jurisdiction-policy files in | ||
| // conf/security read by javax.crypto.JceSecurity's static initialiser) are JVM | ||
| // infrastructure, not student file access, and must not be blocked. | ||
| if ("read".equals(action)) { | ||
| return true; | ||
| } | ||
| if (!"execute".equals(action)) { | ||
| return false; | ||
| } | ||
| for (String suffix : NATIVE_LIBRARY_SUFFIXES) { | ||
| if (path.endsWith(suffix)) { | ||
| return true; | ||
| } | ||
| } | ||
| return false; |
There was a problem hiding this comment.
Don't exempt every student-supplied java.home read.
This helper now treats any read under java.home as trusted and Line 943 skips the violation entirely. That means student code can read arbitrary JDK files just by passing paths like ${java.home}/release or ${java.home}/conf/security/java.security, even when the policy does not allow them. The exemption needs an internal-origin signal or a much narrower path check; otherwise both the AspectJ path here and the mirrored instrumentation path become an allowlist bypass.
Also applies to: 943-945
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@src/main/java/de/tum/cit/ase/ares/api/aop/java/aspectj/adviceandpointcut/JavaAspectJFileSystemAdviceDefinitions.aj`
around lines 109 - 127, isExemptSystemFileAccess currently exempts any "read"
under java.home, which lets student code read arbitrary JDK files; update the
helper (method isExemptSystemFileAccess and any call sites like the AspectJ
pointcut at lines referenced) to stop blanket-allowing reads: either require an
explicit internal-origin signal/flag passed into isExemptSystemFileAccess (or
set by the JVM-internal call path) before returning true for "read", or narrow
the allowed read paths to a tight allowlist of specific JVM-only
files/directories (e.g. specific conf/security or native/lib paths) and only
return true when path matches those exact allowed subpaths; also ensure
NATIVE_LIBRARY_SUFFIXES handling remains unchanged for "execute".
| public static final Map<String, List<String>> methodsWhichCanExecuteFiles = Map.ofEntries( | ||
| // java.lang - only load/loadLibrary, not exec (handled by Command System) | ||
| Map.entry("java.lang.Runtime", List.of("load", "loadLibrary")), | ||
| Map.entry("java.lang.System", List.of("load", "loadLibrary")), | ||
| // Note: ProcessBuilder is handled entirely by Command System | ||
| // java.awt | ||
| Map.entry("java.awt.Desktop", List.of("open", "edit", "print", "browse", "browseFileDirectory", "mail", | ||
| "openHelpViewer", "setDefaultMenuBar", "setOpenFileHandler", "setOpenURIHandler"))); | ||
| Map.entry("java.lang.System", List.of("load", "loadLibrary"))); | ||
| // Note: ProcessBuilder is handled entirely by Command System | ||
| // Note: java.awt.Desktop is intentionally NOT included here - it is bound only | ||
| // to the read file-system check so a Desktop call is deterministically | ||
| // classified as "read". |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="src/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/pointcut/JavaInstrumentationPointcutDefinitions.java"
if [ ! -f "$FILE" ]; then
echo "Missing $FILE"
exit 1
fi
echo "=== Desktop occurrences in target file ==="
rg -n "java\.awt\.Desktop|Desktop\." "$FILE" || true
echo
echo "=== methodsWhichCanReadFiles section (around first Desktop mention) ==="
# Print a window around the first match for Desktop in this file
FIRST_LINE=$(rg -n "java\.awt\.Desktop" "$FILE" | head -n1 | cut -d: -f1)
START=$((FIRST_LINE-40))
END=$((FIRST_LINE+40))
sed -n "${START},${END}p" "$FILE" | nl -ba | sed -n '1,120p'
echo
echo "=== methodsWhichCanExecuteFiles final state section (around lines 474-481) ==="
sed -n '430,520p' "$FILE" | nl -ba
echo
echo "=== Find the buckets / maps definitions for execute/read in this file ==="
rg -n "methodsWhichCanReadFiles|methodsWhichCanExecuteFiles|execute|read bucket|bucket" "$FILE" | head -n 80
echo
echo "=== Search for how the read bucket is checked (control-flow) ==="
rg -n "checkFileSystemInteraction\(|methodsWhichCanReadFiles|methodsWhichCanExecuteFiles" src/main/java/de/tum/cit/ase/ares/api -S || trueRepository: ls1intum/Ares2
Length of output: 429
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="src/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/pointcut/JavaInstrumentationPointcutDefinitions.java"
echo "=== Desktop occurrences in target file ==="
rg -n "java\.awt\.Desktop|Desktop\." "$FILE" || true
echo
echo "=== methodsWhichCanReadFiles section (around Desktop entry) ==="
FIRST_LINE=$(rg -n "java\.awt\.Desktop" "$FILE" | head -n1 | cut -d: -f1)
START=$((FIRST_LINE-40))
END=$((FIRST_LINE+80))
awk -v s="$START" -v e="$END" 'NR>=s && NR<=e {printf "%d:\t%s\n", NR, $0}' "$FILE" | sed -n '1,180p'
echo
echo "=== methodsWhichCanExecuteFiles final state section (around lines 430-520) ==="
awk 'NR>=430 && NR<=520 {printf "%d:\t%s\n", NR, $0}' "$FILE"
echo
echo "=== Find the definitions for methodsWhichCanReadFiles / methodsWhichCanExecuteFiles ==="
rg -n "methodsWhichCanReadFiles|methodsWhichCanExecuteFiles" "$FILE" || true
echo
echo "=== Search for checkFileSystemInteraction call sites mentioning read ==="
rg -n "checkFileSystemInteraction\(|read\"" src/main/java/de/tum/cit/ase/ares/api -S || true
echo
echo "=== Search for file-read enforcement / logic in this pointcut file ==="
rg -n "read" "$FILE" | head -n 80Repository: ls1intum/Ares2
Length of output: 27426
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Search for Desktop usage across src
rg -n "java\.awt\.Desktop" src/main/java/de/tum/cit/ase/ares/api || true
# Inspect toolbox logic around variableToPath / checkIfPathIsForbidden / checkFileSystemInteraction
FILE="src/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationAdviceFileSystemToolbox.java"
echo "=== Inspect Toolbox: variableToPath / checkIfPathIsForbidden / checkFileSystemInteraction ==="
# show key functions by locating their definitions
rg -n "variableToPath|checkIfPathIsForbidden|checkFileSystemInteraction|pathsAllowedToBeRead|case \"read\" ->" "$FILE"
# Print around variableToPath and checkIfPathIsForbidden
python3 - <<'PY'
import re, pathlib
path = pathlib.Path("src/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationAdviceFileSystemToolbox.java")
txt = path.read_text(encoding='utf-8')
def snippet(name):
m = re.search(rf"\b{name}\b\s*\(", txt)
return m.start() if m else None
for name in ["variableToPath","checkIfPathIsForbidden","checkFileSystemInteraction"]:
m = re.search(rf"^[ \t]*(?:public|private|protected)?[ \t]*(?:static\s+)?[^;\n]*\b{name}\b[ \t]*\(", txt, re.M)
if not m:
print("Not found", name)
else:
print(name, "byte", m.start())
PY
# Use sed to print around likely regions (line numbers from rg)
awk 'NR>=900 && NR<=1100 {print NR ":" $0}' "$FILE" | head -n 250
echo "----"
awk 'NR>=1100 && NR<=1280 {print NR ":" $0}' "$FILE" | head -n 220
echo "----"
awk 'NR>=1180 && NR<=1305 {print NR ":" $0}' "$FILE" | head -n 160Repository: ls1intum/Ares2
Length of output: 26096
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n "java\.awt\.Desktop" src/main/java/de/tum/cit/ase/ares/api || true
FILE="src/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationAdviceFileSystemToolbox.java"
echo
echo "=== Toolbox key references ==="
rg -n "variableToPath|checkIfPathIsForbidden|checkFileSystemInteraction|pathsAllowedToBeRead|case \"read\"" "$FILE" || true
echo
echo "=== Toolbox: around variableToPath (search for its definition line) ==="
VAR_LINE=$(rg -n "variableToPath" "$FILE" | head -n1 | cut -d: -f1 || true)
if [ -n "${VAR_LINE}" ]; then
START=$((VAR_LINE-60)); END=$((VAR_LINE+120))
sed -n "${START},${END}p" "$FILE" | nl -ba | head -n 220 || true
fi
echo
echo "=== Toolbox: around checkIfPathIsForbidden definition ==="
CHK_LINE=$(rg -n "checkIfPathIsForbidden" "$FILE" | head -n1 | cut -d: -f1 || true)
if [ -n "${CHK_LINE}" ]; then
START=$((CHK_LINE-80)); END=$((CHK_LINE+160))
sed -n "${START},${END}p" "$FILE" | nl -ba | head -n 260 || true
fi
echo
echo "=== Toolbox: around checkFileSystemInteraction definition ==="
CFS_LINE=$(rg -n "checkFileSystemInteraction" "$FILE" | head -n1 | cut -d: -f1 || true)
if [ -n "${CFS_LINE}" ]; then
START=$((CFS_LINE-40)); END=$((CFS_LINE+220))
sed -n "${START},${END}p" "$FILE" | nl -ba | head -n 320 || true
fiRepository: ls1intum/Ares2
Length of output: 4882
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n "java\.awt\.Desktop" src/main/java/de/tum/cit/ase/ares/api || true
FILE="src/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationAdviceFileSystemToolbox.java"
echo
echo "=== Toolbox key references ==="
rg -n "variableToPath|checkIfPathIsForbidden|checkFileSystemInteraction|pathsAllowedToBeRead|case \"read\"" "$FILE" || true
print_window () {
local start=$1 end=$2 file=$3
awk -v s="$start" -v e="$end" 'NR>=s && NR<=e {printf "%d:\t%s\n", NR, $0}' "$file"
}
echo
echo "=== Toolbox: around variableToPath definition ==="
VAR_LINE=$(rg -n "variableToPath" "$FILE" | head -n1 | cut -d: -f1 || true)
if [ -n "${VAR_LINE}" ]; then
print_window $((VAR_LINE-60)) $((VAR_LINE+160)) "$FILE" | head -n 260
fi
echo
echo "=== Toolbox: around checkIfPathIsForbidden definition ==="
CHK_LINE=$(rg -n "checkIfPathIsForbidden" "$FILE" | head -n1 | cut -d: -f1 || true)
if [ -n "${CHK_LINE}" ]; then
print_window $((CHK_LINE-80)) $((CHK_LINE+220)) "$FILE" | head -n 300
fi
echo
echo "=== Toolbox: around checkFileSystemInteraction definition ==="
CFS_LINE=$(rg -n "checkFileSystemInteraction" "$FILE" | head -n1 | cut -d: -f1 || true)
if [ -n "${CFS_LINE}" ]; then
print_window $((CFS_LINE-40)) $((CFS_LINE+260)) "$FILE" | head -n 340
fiRepository: ls1intum/Ares2
Length of output: 44655
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n "java\.awt\.Desktop" src/main/java/de/tum/cit/ase/ares/api || true
FILE="src/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationAdviceFileSystemToolbox.java"
echo
echo "=== Toolbox key references ==="
rg -n "variableToPath|checkIfPathIsForbidden|checkFileSystemInteraction|pathsAllowedToBeRead|case \"read\"" "$FILE" || true
print_window () {
local start=$1 end=$2 file=$3
awk -v s="$start" -v e="$end" 'NR>=s && NR<=e {printf "%d:\t%s\n", NR, $0}' "$file"
}
echo
echo "=== Toolbox: around variableToPath definition ==="
VAR_LINE=$(rg -n "variableToPath" "$FILE" | head -n1 | cut -d: -f1 || true)
if [ -n "${VAR_LINE}" ]; then
print_window $((VAR_LINE-60)) $((VAR_LINE+160)) "$FILE" | head -n 260
fi
echo
echo "=== Toolbox: around checkIfPathIsForbidden definition ==="
CHK_LINE=$(rg -n "checkIfPathIsForbidden" "$FILE" | head -n1 | cut -d: -f1 || true)
if [ -n "${CHK_LINE}" ]; then
print_window $((CHK_LINE-80)) $((CHK_LINE+220)) "$FILE" | head -n 300
fi
echo
echo "=== Toolbox: around checkFileSystemInteraction definition ==="
CFS_LINE=$(rg -n "checkFileSystemInteraction" "$FILE" | head -n1 | cut -d: -f1 || true)
if [ -n "${CFS_LINE}" ]; then
print_window $((CFS_LINE-40)) $((CFS_LINE+260)) "$FILE" | head -n 340
fiRepository: ls1intum/Ares2
Length of output: 44655
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n "java\.awt\.Desktop" src/main/java/de/tum/cit/ase/ares/api || true
FILE="src/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationAdviceFileSystemToolbox.java"
echo
echo "=== Toolbox key references ==="
rg -n "variableToPath|checkIfPathIsForbidden|checkFileSystemInteraction|pathsAllowedToBeRead|case \"read\"" "$FILE" || true
print_window () {
local start=$1 end=$2 file=$3
awk -v s="$start" -v e="$end" 'NR>=s && NR<=e {printf "%d:\t%s\n", NR, $0}' "$file"
}
echo
echo "=== Toolbox: around variableToPath definition ==="
VAR_LINE=$(rg -n "variableToPath" "$FILE" | head -n1 | cut -d: -f1 || true)
if [ -n "${VAR_LINE}" ]; then
print_window $((VAR_LINE-60)) $((VAR_LINE+160)) "$FILE" | head -n 260
fi
echo
echo "=== Toolbox: around checkIfPathIsForbidden definition ==="
CHK_LINE=$(rg -n "checkIfPathIsForbidden" "$FILE" | head -n1 | cut -d: -f1 || true)
if [ -n "${CHK_LINE}" ]; then
print_window $((CHK_LINE-80)) $((CHK_LINE+220)) "$FILE" | head -n 300
fi
echo
echo "=== Toolbox: around checkFileSystemInteraction definition ==="
CFS_LINE=$(rg -n "checkFileSystemInteraction" "$FILE" | head -n1 | cut -d: -f1 || true)
if [ -n "${CFS_LINE}" ]; then
print_window $((CFS_LINE-40)) $((CFS_LINE+260)) "$FILE" | head -n 340
fiRepository: ls1intum/Ares2
Length of output: 44655
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n "methodsWhichCanReadFiles|methodsWhichCanExecuteFiles" src/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation -S
echo
echo "=== Inspect JavaInstrumentationReadPathMethodAdvice checkFileSystemInteraction action ==="
FILE="src/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationReadPathMethodAdvice.java"
if [ -f "$FILE" ]; then
awk 'NR>=1 && NR<=140 {print NR ":" $0}' "$FILE"
fi
echo
echo "=== Inspect JavaInstrumentationExecutePathMethodAdvice checkFileSystemInteraction action ==="
FILE="src/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationExecutePathMethodAdvice.java"
if [ -f "$FILE" ]; then
awk 'NR>=1 && NR<=140 {print NR ":" $0}' "$FILE"
fi
echo
echo "=== Inspect JavaInstrumentationBindingDefinitions where pointcuts are built from maps (if any) ==="
FILE="src/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/pointcut/JavaInstrumentationBindingDefinitions.java"
if [ -f "$FILE" ]; then
rg -n "methodsWhichCanReadFiles|methodsWhichCanExecuteFiles" "$FILE" -S || true
awk 'NR>=1 && NR<=260 {print NR ":" $0}' "$FILE" | head -n 260
fiRepository: ls1intum/Ares2
Length of output: 26763
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="src/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/advice/JavaInstrumentationAdviceFileSystemToolbox.java"
rg -n "checkIfVariableCriteriaIsViolated|analyseViolation\\(|variableToTarget\\(" "$FILE" -S || true
echo
echo "=== Around checkIfVariableCriteriaIsViolated ==="
LINE=$(rg -n "checkIfVariableCriteriaIsViolated" "$FILE" -S | head -n1 | cut -d: -f1 || true)
if [ -n "${LINE:-}" ]; then
awk -v s=$((LINE-40)) -v e=$((LINE+160)) 'NR>=s && NR<=e {print NR ":" $0}' "$FILE" | head -n 260
fi
echo
echo "=== Around analyseViolation completion where variableToTarget called ==="
# Find first occurrence after 'analyseViolation' for variableToTarget usage
LINE2=$(rg -n "variableToTarget\\(" "$FILE" -S | head -n1 | cut -d: -f1 || true)
if [ -n "${LINE2:-}" ]; then
awk -v s=$((LINE2-40)) -v e=$((LINE2+160)) 'NR>=s && NR<=e {print NR ":" $0}' "$FILE" | head -n 260
fiRepository: ls1intum/Ares2
Length of output: 19889
Do not collapse java.awt.Desktop into the “read” file-system bucket.
JavaInstrumentationPointcutDefinitions.methodsWhichCanReadFiles includes java.awt.Desktop (open/edit/print/browse/browseFileDirectory) while methodsWhichCanExecuteFiles omits it, so the Byte Buddy instrumentation applies checkFileSystemInteraction("read", ...) to these calls. In JavaInstrumentationAdviceFileSystemToolbox.variableToPath, URI/URL values are only converted for file:/file schemes; otherwise it returns null, and checkIfPathIsForbidden returns false when target is null—so non-file: Desktop targets bypass the read allowlist path checks entirely.
Move java.awt.Desktop to an appropriate action/bucket (or add explicit handling that blocks or correctly validates non-file: URI/URL arguments) instead of relying on the "read" policy.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@src/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/pointcut/JavaInstrumentationPointcutDefinitions.java`
around lines 474 - 481, The instrumented handling for java.awt.Desktop is wrong:
remove or relocate "java.awt.Desktop" (and its methods
open/edit/print/browse/browseFileDirectory) out of methodsWhichCanReadFiles and
place it into the correct action/bucket (or add a dedicated Desktop bucket) in
JavaInstrumentationPointcutDefinitions.methodsWhichCanReadFiles/methodsWhichCanExecuteFiles,
and then update JavaInstrumentationAdviceFileSystemToolbox.variableToPath to
explicitly handle non-file URIs/URLs (or make it return a sentinel that causes
checkIfPathIsForbidden to treat them as forbidden) so that
checkIfPathIsForbidden does not silently allow non-file Desktop targets; ensure
changes reference methodsWhichCanReadFiles, methodsWhichCanExecuteFiles,
JavaInstrumentationAdviceFileSystemToolbox.variableToPath and
checkIfPathIsForbidden and cover Desktop methods
open/edit/print/browse/browseFileDirectory.
| Map.entry("java.net.URL", List.of("openConnection")), | ||
| Map.entry("java.net.URLConnection", List.of("connect"))); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Search for the specific maps and where they're used for advice/policy selection
rg -n "methodsWhichCanReadFiles|methodsWhichCanConnectToNetwork" src/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/pointcut/JavaInstrumentationPointcutDefinitions.java
rg -n "methodsWhichCanReadFiles|methodsWhichCanConnectToNetwork" src/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/pointcut src/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation -S
# Inspect bindings/agent install logic that selects file-vs-network enforcement in instrumentation mode
rg -n "installAgentBuilder|AgentBuilder|instrumentation mode|deriveActionChecks|JavaInstrumentationAdviceFileSystemToolbox|JavaInstrumentationAdviceNetworkSystemToolbox" src/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation -S
# Print relevant sections around line numbers mentioned in prior context (377, 597-598) and around map usage in bindings
python3 - <<'PY'
import pathlib, itertools
path = pathlib.Path("src/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/pointcut/JavaInstrumentationPointcutDefinitions.java")
lines = path.read_text().splitlines()
for start, end in [(350,420),(560,620)]:
print("\n---", path, "lines", start, "-", end, "---")
for i in range(start-1, min(end, len(lines))):
print(f"{i+1:6d}: {lines[i]}")
PY
python3 - <<'PY'
import pathlib
path = pathlib.Path("src/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/pointcut/JavaInstrumentationBindingDefinitions.java")
if not path.exists():
print("Missing", path)
raise SystemExit(0)
lines = path.read_text().splitlines()
# print around likely usages (from earlier context: ~228, ~241, ~497, ~510)
for start, end in [(190,270),(460,540)]:
print("\n---", path, "lines", start, "-", end, "---")
for i in range(start-1, min(end, len(lines))):
print(f"{i+1:6d}: {lines[i]}")
PYRepository: ls1intum/Ares2
Length of output: 46351
Fix java.net.URL.openStream classification (still treated as file-read). java.net.URL.openStream remains in methodsWhichCanReadFiles (entry at ~line 377) and is therefore bound to the file-read advice (JavaInstrumentationReadPath*Advice → JavaInstrumentationAdviceFileSystemToolbox.checkFileSystemInteraction("read", ...)), while it is absent from methodsWhichCanConnectToNetwork (~lines 597–598). Move openStream out of the read pointcuts and into the appropriate network connect/receive pointcuts so URL fetches are controlled by network policy rather than file-read policy.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@src/main/java/de/tum/cit/ase/ares/api/aop/java/instrumentation/pointcut/JavaInstrumentationPointcutDefinitions.java`
around lines 597 - 598, The URL.openStream method is wrongly classified as a
file-read; remove "openStream" from the methodsWhichCanReadFiles map (where it's
currently listed) and add it to the methodsWhichCanConnectToNetwork entry for
"java.net.URL" (so the map entry with Map.entry("java.net.URL", List.of(...))
includes "openStream"). This ensures URL.fetches use the network connect/receive
pointcuts (so they are handled by the network advice instead of
JavaInstrumentationReadPath*Advice /
JavaInstrumentationAdviceFileSystemToolbox.checkFileSystemInteraction).
| if (sourceDirectoryNodes.getLength() > 0) { | ||
| var sourceDirectoryPropertyValue = sourceDirectoryNodes.item(0).getTextContent(); | ||
| return toRelativeSourceDirectory(sourceDirectoryPropertyValue); | ||
| } | ||
| } | ||
| } | ||
| } catch (ParserConfigurationException | SAXException | IOException | NullPointerException e) { | ||
| if (Files.exists(Path.of(DEFAULT_MAVEN_SOURCE_DIRECTORY))) { | ||
| return DEFAULT_MAVEN_SOURCE_DIRECTORY; | ||
| } |
There was a problem hiding this comment.
Avoid early null return when <sourceDirectory> is present but blank.
At Line [95]–Line [98], a blank <sourceDirectory> returns null immediately, so the default fallback at Line [101] is never reached. That can incorrectly disable source-path discovery for otherwise valid Maven defaults.
Suggested patch
- if (sourceDirectoryNodes.getLength() > 0) {
- var sourceDirectoryPropertyValue = sourceDirectoryNodes.item(0).getTextContent();
- return toRelativeSourceDirectory(sourceDirectoryPropertyValue);
- }
+ if (sourceDirectoryNodes.getLength() > 0) {
+ var sourceDirectoryPropertyValue = sourceDirectoryNodes.item(0).getTextContent();
+ var resolved = toRelativeSourceDirectory(sourceDirectoryPropertyValue);
+ if (resolved != null) {
+ return resolved;
+ }
+ }Also applies to: 110-113
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/main/java/de/tum/cit/ase/ares/api/util/ProjectSourcesFinder.java` around
lines 95 - 103, The current logic in ProjectSourcesFinder prematurely returns
null when a <sourceDirectory> element exists but its text content is empty;
change the handling in the method that reads sourceDirectoryNodes (the block
that returns toRelativeSourceDirectory(sourceDirectoryPropertyValue)) to treat
blank/whitespace-only values as if the element were absent (i.e., trim and check
length > 0 before returning), so the default fallback
(DEFAULT_MAVEN_SOURCE_DIRECTORY) can be used; apply the same blank-check fix to
the analogous block around the code flagged at lines 110–113.
| regardingNetworkConnections: | ||
| - onTheHost: "127.0.0.1" | ||
| onThePort: 12345 | ||
| openConnections: true | ||
| sendData: false | ||
| receiveData: false |
There was a problem hiding this comment.
Use the external echo-server port in this policy.
Line 13 currently allows 12345, but the integration contract uses loopback echo on 25565; this can cause spurious connection failures in tests that should validate policy behavior.
Suggested fix
regardingNetworkConnections:
- onTheHost: "127.0.0.1"
- onThePort: 12345
+ onThePort: 25565
openConnections: true
sendData: false
receiveData: falseAs per coding guidelines, “Outgoing-connection tests must connect to an external echo server … on loopback at port 25565”.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| regardingNetworkConnections: | |
| - onTheHost: "127.0.0.1" | |
| onThePort: 12345 | |
| openConnections: true | |
| sendData: false | |
| receiveData: false | |
| regardingNetworkConnections: | |
| - onTheHost: "127.0.0.1" | |
| onThePort: 25565 | |
| openConnections: true | |
| sendData: false | |
| receiveData: false |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/java/maven/archunit/aspectj/PolicyOneNetworkConnectionAllowed.yaml`
around lines 11 - 16, The policy's network connection entry under
regardingNetworkConnections currently uses onThePort: 12345 causing tests to
target the wrong echo server; update the entry (the object with onTheHost,
onThePort, openConnections, sendData, receiveData) to use the external loopback
echo-server port 25565 (keep onTheHost as "127.0.0.1" and preserve the other
flags) so the integration tests connect to the expected external echo server.
Source: Coding guidelines
Summary
This branch stabilises the Ares 2 test suite and the Maven CI pipeline. It fixes a number of real production bugs in the AOP and architecture enforcement layers, repairs the build/format gate, migrates the integration test users off the defunct Ares 1 annotations onto
@Policy, and corrects a large amount of test/fixture/policy drift. Compared with the starting point on this branch, the full-suite failures are down from 188 failures / 38 errors to 121 failures / 18 errors, with several whole test classes now green (JqwickTest,NetworkTest,InputOutputTest, the allowed file-system read/overwrite/delete operations, the precompile flow, and the architecture file-system forbidden tests in isolation).Changes
spotless:applysospotless:check(the first CI step) passes; add the CI job timeout, surefire fork timeout, heap cap and JVM module-access args.java.awt.Desktopinterception to the file-read check only (was bound to read/overwrite/execute/delete at once, giving a nondeterministic verb); stop misclassifyingjava.net.URL.openStreamandjava.net.URI.createas network access; exempt JDK-internal reads underjava.home(e.g.JceSecurityreading the crypto policy files) from the file-system checks; add denial reasons to theSecurityExceptionmessages; fix loopback/IPv6 network-target parsing. Changes are applied symmetrically across the AspectJ and instrumentation layers.SecurityExceptionso a cache read inside an active policy can no longer poisonJavaWalaTestCase(and every subsequent WALA test) withNoClassDefFoundError; exclude Ares's own engine classes from student architecture analysis.@WhitelistPath,@BlacklistPath,@AllowThreads,@AllowLocalPort,@TrustedThreads,@WhitelistClass/@WhitelistPackage,@BlacklistPackage,@AddTrustedPackage) onto active@Policydefinitions; pin the English locale for AOP/thread tests; connect the network test to an external echo server instead of an in-JVM one; correct the forbidden file-system within-paths and assertions; add the trusted/nottrusted delete fixtures; let theSecurityExceptionpropagate from forbidden thread subjects; write the precompile scaffold into a temporary directory so the repository is no longer polluted.Rationale
The Ares 2 enforcement model moved entirely to
@Policy-driven architecture and AOP analysis; the test suite still carried a large amount of Ares 1 era state (defunct annotations, stale paths, an in-JVM echo server, generated artefacts written into the repo) and several genuine production bugs surfaced only under the full suite. The production fixes address real correctness issues (operation misclassification, a class-initialiser poisoning bug, JDK-internal reads being blocked), while the test changes realign the suite with the current production behaviour and make it reproducible.Known remaining work
aop.allowed.FileSystemAccessExecuteTest(38F/16E): the Execute bucket still needs its subjects pointed at the policy-permitted trusted script plus the missing fixtures; not yet started.aop.forbiddenfile-system (44F/2E): remaining classification/assertion fixes.ThreadTest+architecture.forbidden.ThreadSystemAccessTest(11F): an AOP thread-interception gap (Thread.sleep, parallel streams,Thread.run(), Flow publisher).forkCount=1,reuseForks=true). The architecture file-system forbidden tests are green in isolation (200 run, 0 failures) but fail in the full run because the WALA analysis is affected by global state left by earlier tests. Resolving this (e.g.reuseForks=false, weighed against the CI time budget, or fixing the WALA reentrancy) is the highest-leverage next step and would clear roughly a third of the remaining failures.Summary by CodeRabbit
New Features
Bug Fixes
Tests
Chores