<div dir="auto">Hello Volker,<div dir="auto"><br></div><div dir="auto">The 2 ways of sharing information discussed here are "passing a parameter" and "having a field in scope", the only thing that Scoped/Thread locals gives is the thread safety (and integrity in the case of ScopedValues), the problem of security is more about visibility than those 2 specific classes.</div><div dir="auto"><br></div><div dir="auto">Here is an example that I believe showcase the problem, this example is a textbook example of how a strong type system solves the problem but it works just fine for our case.</div><div dir="auto"><br></div><div dir="auto">Imagine I have a function `Print` that prints to a shell, this function has 2 *dependencies*, the input we want to print, and the is the state of the shell (containing e.g. the offset we are in).</div><div dir="auto"><br></div><div dir="auto">The function `Print` change the state of the shell, let say we pass both of the dependencies as a parameter (and assume that State is immutable), in this case the function will have the following signature:</div><div dir="auto"><br></div><div dir="auto">    Print: Input -> State -> State</div><div dir="auto"><br></div><div dir="auto">And we will use it:</div><div dir="auto"><br></div><div dir="auto">    state = ...</div><div dir="auto">    state = Print("0", state)</div><div dir="auto">    state = Print("1", state)</div><div dir="auto"><br></div><div dir="auto">Removing shadowing we have:</div><div dir="auto"><br></div><div dir="auto">    state = ...</div><div dir="auto">    state1 = Print("0", state)</div><div dir="auto">    state2 = Print("1", state1)</div><div dir="auto"><br></div><div dir="auto">But in this way we can have:</div><div dir="auto"><br></div><div dir="auto"><div dir="auto">    state = ...</div><div dir="auto">    state1 = Print("0", state)</div><div dir="auto">    state2 = Print("1", state)</div><div dir="auto"><br></div><div dir="auto">Which we won't necessarily want to be legal, using a stronger type system such as linear types solves this problem, but having the State dependency to not be visible at the user level also solves it, and the latter solution is much more feasible for Java.</div><div dir="auto"><br></div><div dir="auto">Now add it some threads and you want to have something like Scoped/Thread locals.</div><div dir="auto"><br></div><div dir="auto">Now this may looks like a silly example, but it comes to show the idea that we want stuff to not be accessible to the user in some cases.</div><div dir="auto"><br></div><div dir="auto">Another example is having some kind of access Token, which we don't want the user to be able to access (or we want to control the accessibility), but this Token is required for the execution.</div><div dir="auto"><br></div><div dir="auto">And indeed I can't think on any public thread local that is not a security problem (for scoped locals there is some rare use cases for public accessibility because they have a great integrity and they read-only stack base, but it is really not the common use cases)</div><div dir="auto"><br></div><div dir="auto">Hope it helps,</div><div dir="auto">Cheers,</div><div dir="auto">Holo</div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Apr 27, 2023, 17:17 Volker Simonis <<a href="mailto:volker.simonis@gmail.com">volker.simonis@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I take this discussion from the JEP issue in JBS [1] to the mailing<br>
list as requested by Alan:<br>
<br>
My initial comment was:<br>
<br>
In your motivation section you say:<br>
<br>
  Normally, data is shared between caller and callee by passing it as<br>
method arguments,<br>
  but this is not viable for a Principal shared between the server<br>
component and the data<br>
  access component because the server component calls untrusted user<br>
code first. We need<br>
  a better way to share data from the server component to the data<br>
access component than<br>
  wiring it into a cascade of untrusted method invocations.<br>
<br>
I can't see how ThreadLocals or ScopedValues improve the situation<br>
here with respect to "untrusted code"? I fully agree that passing the<br>
Principal data from the server component down to the data access<br>
component by means of method parameters is ugly and disturbing. But I<br>
can't see how it should be more "unsecure", because the "untrusted<br>
user code" can access a potential Principle object from its argument<br>
list in much the same way like a ThreadLocale or ScopedValue defined<br>
in an enclosing scope.<br>
<br>
So maybe it would be better to focus more on the usability aspect than<br>
on "avoiding information exposure to untrusted code" in the Motivation<br>
section?<br>
<br>
Andrew's response was:<br>
<br>
> But I can't see how it should be more "unsecure", because the "untrusted user code" can access a potential Principle object from its argument list in much the same way like a ThreadLocale or ScopedValue defined in an enclosing scope.<br>
<br>
I don't understand what you don't understand.<br>
<br>
We can reason about code when we know that its access to data is<br>
constrained in some way. We know that scoped values have particular<br>
properties, in that we can restrict accesses to them to code we trust.<br>
This isn't specifically security related: '"trusted code" can mean<br>
simply code that we've verified, and therefore can trust. If we set a<br>
scoped value in an outer scope, call via some unknown code, then<br>
access that scoped value in an inner scope, we know for certain that<br>
its value is one we set in the outer scope. The (untrusted, unknown)<br>
code in between can't have substituted something else.<br>
<br>
And Alan added:<br>
<br>
It may be that Volker has missed the point that the capability, as in<br>
the ThreadLocal or ScopeLocal variable, is usually stored in a private<br>
static final so it's not accessible to code in the intermediate frames<br>
between where it is set and (usually) the callback that will read the<br>
value. It would probably be better to bring questions to loom-dev<br>
rather having a protracted discussion in comments here.<br>
<br>
So finally my new comment:<br>
<br>
In your example "Web framework example with scoped values" both, the<br>
`Server` class where the ScopedValue `PRINCIPAL` is declared with<br>
`package-private` visibility as well as the `DBAccess` class which<br>
uses the `PRINCIPAL` are in the default unnamed package. But I doubt<br>
that in a real world application the server class and the database<br>
access class will be in the same package. So if you'd declare<br>
`PRINCIPAL` in a private field as Alan suggested, it would be<br>
impossible for another component to access it. If on the other hand<br>
your scoped value was declared in a public field, any untrusted,<br>
intermediate code executed between outer and inner scope could access<br>
it just as well.<br>
<br>
@Andrew: the untrusted, intermediate code can both read and even<br>
rebind the value of the ScopedValue set in an outer scope. The<br>
"security" you are talking about is a feature of the Java access rules<br>
and not of the scoped value implementation. I don't see how in a real<br>
world (e.g. Spring) application, the web server, the DB engine and the<br>
logging framework can easily share access to a common scoped value<br>
without exposing this scoped value to intermediate code outside of<br>
these components as well.<br>
<br>
But maybe I'm missing something in which case it might sense to<br>
explain this a little more detailed in the JEP?<br>
<br>
Thank you and best regards,<br>
Volker<br>
<br>
[1] <a href="https://bugs.openjdk.org/browse/JDK-8304357" rel="noreferrer noreferrer" target="_blank">https://bugs.openjdk.org/browse/JDK-8304357</a><br>
</blockquote></div>