Re: How to remove the SecurityManager
Appended inline below. On 29/07/2021 11:20 am, Peter Firmstone wrote: The intent of the following process is to perform a targeted audit, which allows inspection of small parts of the code identified by these steps. On 28/07/2021 9:12 am, Peter Firmstone wrote: Our process for establishing whether third party libraries are trusted before we use them: 1. Build dependency check using Owasp https://owasp.org/www-project-dependency-check/ Reject any dependencies that fail, see https://github.com/pfirmstone/JGDMS/blob/trunk/JGDMS/pom.xml line 87 for an example of a disabled module due to a vulnerability in a dependency, the module will only be re-enabled if the vulnerability is fixed. 2. Static analysis using SpotBugs, then review identified bugs, review source code if available. Reject if security bugs are present, or fix / patch. 3. Profiling of permission access checks using: https://github.com/pfirmstone/JGDMS/blob/trunk/JGDMS/tools/security-policy-debug/src/main/java/org/apache/river/tool/SecurityPolicyWriter.java 4. Reviewing generated policy files, using grep, this example was generated from over 2000 tests: https://github.com/pfirmstone/JGDMS/blob/trunk/qa/harness/policy/defaultsecuresharedvm.policy.new 5. Remove any permission from the policy file you don't want to grant to third party code, if safe to do so, eg usage statistics reporting. In the construction industry, a similar approach is used by structural engineers and weld inspectors, when inspecting welds for defects, using Ultrasonic, X-Ray or visual inspection, weld defects in structures have the potential to cause catastrophic failure and multiple fatalities, likely worse consequences than a bug in Java, so engineers identify critical areas for inspectors to target with 100% coverage, perhaps by UT or X-Ray, to inspect the weld internally, then the structural engineer will nominate to inspect 10% of other areas with UT, with 100% visual inspection, for example, if defects are found, then they will increase UT inspection coverage, welds need to be gouged out and re-welded, until the inspector is satisfied with quality. A targeted code audit process will also identify code quality, if there are many bugs, don't use it, even if these aren't security bugs. This can hardly be compared with the approach used for running Applets in a sandbox that may have malicious intent, in that case no auditing has been performed at all. This use case of SecurityManager recognizes shortcomings of Java platform security. Sandboxing was a marketing term used for Applets, I don't know the origin of the term sandbox when used for computer security, but whenever there is a sandbox, there is a risk of escape, and simplicity is thy friend, it should be left to cyber security professionals. If you removed applets, then there is no use case for a Sandbox, so why remove SecurityManager? Come on honestly, JEP 411 is confirmation biased, is overly focused on sandboxing and therefore not factual or relevant, I've provided sufficient evidence contrary to it's claims. It needs to take the ability to migrate code into account as well as use cases other than sandboxing. We use SM to prevent loading of untrusted (unaudited) code and untrusted (unauthenticated) data, but we don't use it as a sandbox to attempt to encapsulate malicious code and malicious users, we use it for authorization decisions, for external users and services, this could also be applied to Web Services, not just Jini services, these authorization decisions prevent loading untrusted code and parsing untrusted data. grant codebase "httpmd://${HOST}:9080/${mercury-dl.jar};sha-384=041531e5e3de288c121e865af8a46f7af86172ee0127dc4aff4f551c73a0ad604f51cb1c53076140fd415f957c14e8dd", principal javax.security.auth.x500.X500Principal "CN=Outrigger" { permission org.apache.river.api.io.DeSerializationPermission "MARSHALL"; permission net.jini.security.AuthenticationPermission "javax.security.auth.x500.X500Principal \"CN=Outrigger\" peer javax.security.auth.x500.X500Principal \"CN=Phoenix\"", "connect"; }; Rather than throwing developers who use SM under the bus, we could be given a migration path: 1. Review and reduce the number of permissions focused *only* on authorization use cases. Eg: Give Properties useful for authorization their own guarded area in the Property map? I mean, why are we guarding java.util.PropertyPermission "java.specification.version", "read" and many others like it? Fix SocketPermission, add netmask wild cards, use RFC3986 normalization, stop using DNS. Ever heard of DNS spoofing? 2. What about parsing of data? Such as XML and Java Serialization, among others, this should have a permission check, that when granted to users, ensures the data source has been authenticated. This is a server application, not
Re: How to remove the SecurityManager
The intent of the following process is to perform a targeted audit, which allows inspection of small parts of the code identified by these steps. On 28/07/2021 9:12 am, Peter Firmstone wrote: Our process for establishing whether third party libraries are trusted before we use them: 1. Build dependency check using Owasp https://owasp.org/www-project-dependency-check/ Reject any dependencies that fail, see https://github.com/pfirmstone/JGDMS/blob/trunk/JGDMS/pom.xml line 87 for an example of a disabled module due to a vulnerability in a dependency, the module will only be re-enabled if the vulnerability is fixed. 2. Static analysis using SpotBugs, then review identified bugs, review source code if available. Reject if security bugs are present, or fix / patch. 3. Profiling of permission access checks using: https://github.com/pfirmstone/JGDMS/blob/trunk/JGDMS/tools/security-policy-debug/src/main/java/org/apache/river/tool/SecurityPolicyWriter.java 4. Reviewing generated policy files, using grep, this example was generated from over 2000 tests: https://github.com/pfirmstone/JGDMS/blob/trunk/qa/harness/policy/defaultsecuresharedvm.policy.new 5. Remove any permission from the policy file you don't want to grant to third party code, if safe to do so, eg usage statistics reporting. In the construction industry, a similar approach is used by structural engineers and weld inspectors, when inspecting welds for defects, using Ultrasonic, X-Ray or visual inspection, weld defects in structures have the potential to cause catastrophic failure and multiple fatalities, likely worse consequences than a bug in Java, so engineers identify critical areas for inspectors to target with 100% coverage, perhaps by UT or X-Ray, to inspect the weld internally, then the structural engineer will nominate to inspect 10% of other areas with UT, with 100% visual inspection, for example, if defects are found, then they will increase UT inspection coverage, welds need to be gouged out and re-welded, until the inspector is satisfied with quality. A targeted code audit process will also identify code quality, if there are many bugs, don't use it, even if these aren't security bugs. This can hardly be compared with the approach used for running Applets in a sandbox that may have malicious intent, in that case no auditing has been performed at all. This use case of SecurityManager recognizes shortcomings of Java platform security. Sandboxing was a marketing term used for Applets, I don't know the origin of the term sandbox when used for computer security, but whenever there is a sandbox, there is a risk of escape, and simplicity is thy friend, it should be left to cyber security professionals. If you removed applets, then there is no use case for a Sandbox, so why remove SecurityManager? Come on honestly, JEP 411 is confirmation biased, is overly focused on sandboxing and therefore not factual or relevant, I've provided sufficient evidence contrary to it's claims. It needs to take the ability to migrate code into account as well as use cases other than sandboxing. We use SM to prevent loading of untrusted (unaudited) code and untrusted (unauthenticated) data, but we don't use it as a sandbox to attempt to encapsulate malicious code and malicious users, we use it for authorization decisions, for external users and services, this could also be applied to Web Services, not just Jini services, these authorization decisions prevent loading untrusted code and parsing untrusted data. grant codebase "httpmd://${HOST}:9080/${mercury-dl.jar};sha-384=041531e5e3de288c121e865af8a46f7af86172ee0127dc4aff4f551c73a0ad604f51cb1c53076140fd415f957c14e8dd", principal javax.security.auth.x500.X500Principal "CN=Outrigger" { permission org.apache.river.api.io.DeSerializationPermission "MARSHALL"; permission net.jini.security.AuthenticationPermission "javax.security.auth.x500.X500Principal \"CN=Outrigger\" peer javax.security.auth.x500.X500Principal \"CN=Phoenix\"", "connect"; }; Rather than throwing developers who use SM under the bus, we could be given a migration path: 1. Review and reduce the number of permissions focused *only* on authorization use cases. Eg: Give Properties useful for authorization their own guarded area in the Property map? I mean, why are we guarding java.util.PropertyPermission "java.specification.version", "read" and many others like it? Fix SocketPermission, add netmask wild cards, use RFC3986 normalization, stop using DNS. Ever heard of DNS spoofing? 2. What about parsing of data? Such as XML and Java Serialization, among others, this should have a permission check, that when granted to users, ensures the data source has been authenticated. This is a server application, not client. Permission to parse data should only be granted to user principal's. No user, then
Re: How to remove the SecurityManager
Thanks Remi, I'm a user of ASM also, for a long time, since 2007, it's a very performant library. Yes, we could replace the policy audit with another tool, but it's academic, the remaining code cannot be upgraded. For now the policy tools informs me of reflection access, I don't need to blacklist it if I read the code and it's doing something harmless, eg. it might be calling public methods, to support multiple versions of java. I looked at Agents to replace permission checks, it requires modification of private methods, it's bad practice, we've removed all code that accessed private implementation or state, we only use public API. It's not just a simple case of instrumenting public API's, many permissions defend constructors, and constructors contain private static methods to defend against finalizer attacks. While I could defend public methods, methods are called far more often than constructors, it would have an unacceptable impact on performance. Years will pass before finalizers are removed and constructors are simplified so they can be instrumented. It's not viable to re-implement an authorization layer as an external library for Java. Right now SM only has a less than 3% impact on performance and doesn't affect scalability, how can I justify replacing it, for what new feature? I don't run untrusted code, it works reliably for the authorization based access controls that I require and provides access to subject credentials for authentication of secure connections. Performance profiling of SM running with stateless TLS sockets <https://imgur.com/VcSwffC> https://imgur.com/VcSwffC https://imgur.com/VcSwffC https://imgur.com/VcSwffC I think Haskell has better type safety than Java, it handles Null with Maybe, it's good for parsing data, it appears to have made few compromises in its design, but I'm not saying that from experience. I think if I was looking for something to run untrusted code, it would be as source code that I parsed, then compiled, perhaps a subset of Haskell parsed as source code, if I used it for that, then it's audited by parsing and the compiler. I guess something similar could be done with ASM and bytecode, but it's not my goal to run untrusted code, I'll leave the sandbox for the developers cat to bury applets. Regards, Peter. On 28/07/2021 7:41 pm, fo...@univ-mlv.fr wrote: *From: *"Peter Firmstone" *To: *"Remi Forax" , "Alan Bateman" *Cc: *"jdk-dev" , "security-dev" *Sent: *Wednesday, July 28, 2021 1:12:32 AM *Subject: *Re: How to remove the SecurityManager Thanks Remi, Sand-boxing is a bad idea, we are in agreement, it's not something we do, personally I'm taking an interest in safer languages, eg Haskell on secure platforms, eg OpenBSD on Sparc64 *. Perhaps JEP 411 is simply a reflection on the evolution of languages. Java was safer than C and C++ so replaced these, something safer again will replace Java. All mainstream languages have a way to access to raw pointers to be able to call C functions, here is the one in Haskell https://hackage.haskell.org/package/base-4.5.0.0/docs/Foreign-Storable.html I think people are getting our primary use case, authorization, confused with sandboxing (not on our use case list). OpenJDK developers provided a Sandbox example, I just wanted to communicate that I didn't think it was a practical defense against exploits, nor applicable to our use case: https://inside.java/2021/04/23/security-and-sandboxing-post-securitymanager/ <https://inside.java/2021/04/23/security-and-sandboxing-post-securitymanager/> Our process for establishing whether third party libraries are trusted before we use them: 1. Build dependency check using Owasp https://owasp.org/www-project-dependency-check/ <https://owasp.org/www-project-dependency-check/> Reject any dependencies that fail, see https://github.com/pfirmstone/JGDMS/blob/trunk/JGDMS/pom.xml <https://github.com/pfirmstone/JGDMS/blob/trunk/JGDMS/pom.xml> line 87 for an example of a disabled module due to a vulnerability in a dependency, the module will only be re-enabled if the vulnerability is fixed. 2. Static analysis using SpotBugs, then review identified bugs, review source code if available. Reject if security bugs are present, or fix / patch. 3. Profiling of permission access checks using: https://github.com/pfirmstone/JGDMS/blob/trunk/JGDMS/tools/security-policy-debug/src/main/java/org/apache/river/tool/SecurityPolicyWriter.java <https://github.com/pfirmstone/JGDMS/blob/trunk/JGDMS/tools/security-policy-debug/src/main/java/org/apache/river/tool/SecurityPolicyWriter.java> 4.
Re: How to remove the SecurityManager
> From: "Peter Firmstone" > To: "Remi Forax" , "Alan Bateman" > Cc: "jdk-dev" , "security-dev" > > Sent: Wednesday, July 28, 2021 1:12:32 AM > Subject: Re: How to remove the SecurityManager > Thanks Remi, > Sand-boxing is a bad idea, we are in agreement, it's not something we do, > personally I'm taking an interest in safer languages, eg Haskell on secure > platforms, eg OpenBSD on Sparc64 *. > Perhaps JEP 411 is simply a reflection on the evolution of languages. Java was > safer than C and C++ so replaced these, something safer again will replace > Java. All mainstream languages have a way to access to raw pointers to be able to call C functions, here is the one in Haskell https://hackage.haskell.org/package/base-4.5.0.0/docs/Foreign-Storable.html > I think people are getting our primary use case, authorization, confused with > sandboxing (not on our use case list). OpenJDK developers provided a Sandbox > example, I just wanted to communicate that I didn't think it was a practical > defense against exploits, nor applicable to our use case: > [ > https://inside.java/2021/04/23/security-and-sandboxing-post-securitymanager/ | > https://inside.java/2021/04/23/security-and-sandboxing-post-securitymanager/ ] > Our process for establishing whether third party libraries are trusted before > we > use them: >1. Build dependency check using Owasp [ >https://owasp.org/www-project-dependency-check/ | >https://owasp.org/www-project-dependency-check/ ] Reject any dependencies > that >fail, see [ https://github.com/pfirmstone/JGDMS/blob/trunk/JGDMS/pom.xml | >https://github.com/pfirmstone/JGDMS/blob/trunk/JGDMS/pom.xml ] line 87 for > an >example of a disabled module due to a vulnerability in a dependency, the > module > will only be re-enabled if the vulnerability is fixed. >2. Static analysis using SpotBugs, then review identified bugs, review > source > code if available. Reject if security bugs are present, or fix / patch. >3. Profiling of permission access checks using: [ > > https://github.com/pfirmstone/JGDMS/blob/trunk/JGDMS/tools/security-policy-debug/src/main/java/org/apache/river/tool/SecurityPolicyWriter.java >| > > https://github.com/pfirmstone/JGDMS/blob/trunk/JGDMS/tools/security-policy-debug/src/main/java/org/apache/river/tool/SecurityPolicyWriter.java > ] >4. Reviewing generated policy files, using grep, this example was > generated from >over 2000 tests: [ > > https://github.com/pfirmstone/JGDMS/blob/trunk/qa/harness/policy/defaultsecuresharedvm.policy.new >| > > https://github.com/pfirmstone/JGDMS/blob/trunk/qa/harness/policy/defaultsecuresharedvm.policy.new > ] >5. Remove any permission from the policy file you don't want to grant to > third > party code, if safe to do so, eg usage statistics reporting. > One of my use cases for SM is for auditing to establish trust, and then using > SM > with POLP policy files generated following the audit, to turn off JVM features > we're not using. Our policy provider is performant and high scaling even with > policy files containing 1000's of lines: [ > https://github.com/pfirmstone/JGDMS/blob/trunk/JGDMS/jgdms-platform/src/main/java/org/apache/river/api/security/ConcurrentPolicyFile.java > | > https://github.com/pfirmstone/JGDMS/blob/trunk/JGDMS/jgdms-platform/src/main/java/org/apache/river/api/security/ConcurrentPolicyFile.java > ] > Our use of SM for access decisions occurs during and after authentication, but > also defines access roles for trusted parties, it's not possible to replace SM > authorization layer functionality (not to be confused with sandboxes). Our use > case is distributed systems, with trusted services and trusted clients, which > have POJO proxy's, different service proxies are given different > ProtectionDomain identity and these identities are used for authorization > decisions. > In a simple Client - Server application, you only have one user, from the > client > and the thread runs with this permission, but our systems might be performing > a > transaction, with 5 different services, and the transaction service is the > client of these 5 services, which are represented by their proxy > ProtectionDomain's. If one of the authenticated services is not authorized to > participate in the transaction (eg a third party that's not on the contract, > or > maybe the contract expired), then it's not authorized and the transaction will > fail. This all occurs over secure authenticated connections, where both > servers > and clients are authenticated, who's the server and who's the client, well > that > gets a little blurred
Re: How to remove the SecurityManager
On 28/07/2021 9:12 am, Peter Firmstone wrote: While its possible to use a dynamic proxy without downloading code, via an atomic serialization connection, it's not generally advised to do so with unauthenticated users, decisions around dynamic discovery, whether class loading or downloads are allowed, it's all based on policy decisions. Minor clarification / correction, it's not possible on our system to allow an unauthenticated user over a secure connection, our code disallows TLS connections with anon clients. We do provide TCP/IP connections, that are unsecured, however this is generally to allow testing of services during development and shouldn't be used in production. No changes to a service need to be made other than configuration settings to enable secure connections. Regards, Peter.
Re: How to remove the SecurityManager
, decisions around dynamic discovery, whether class loading or downloads are allowed, it's all based on policy decisions. The problem with our software is its designed to operate on un-trusted networks, and SM infrastructure is involved in authorization decisions during the authentication process, as well as providing user credentials for secure connections. We have no future Java migration path after JEP 411, the decision's been made, time to move on... On the bright side, according the JEP 411, we did achieve what OpenJDK dev's thought to be almost impossible. :) I'm pretty sure using the process I've documented above, you will identify 99% of accidental vulnerabilities in local code, and that was good enough for me lol. The threat of accidental vulnerabilities in local code is almost impossible to address with the Security Manager. * OpenBSD on Sparc (very well supported, Oracle should sell these lol, the only drawback is no zfs) is a good idea, no Spectre or Meltdown vulnerabilities. buffy$ uname -a OpenBSD buffy.lan 6.7 GENERIC.MP#310 sparc64 Although this one's a couple of versions behind, time for an upgrade. Regards, Peter. On 28/07/2021 5:52 am, fo...@univ-mlv.fr wrote: - Original Message - From: "Alan Bateman" To: "Remi Forax" , "Peter Firmstone" Sent: Tuesday, July 27, 2021 6:33:25 PM Subject: Re: How to remove the SecurityManager On 27/07/2021 17:11, Remi Forax wrote: Peter, this is how you remove the security manager using the jdk 17 (the SystemMirror class is specific to a JDK version). Any in-process security measures fail if the API let you to peek and poke the memory like Unsafe does. I hope you aren't really suggesting anyone does this :-) nope, it's a small example to explain why in-process sandboxing is a bad idea. It's dependent on the field layout so can break and crash the VM if it doesn't match. Also it assumes that someone gets theUnsafe before a SM is set. yes, it's just an example, you have infinite variations using JNI/JNA/JNR or panama and changing some field value. -Alan Rémi