Break OO privacy: Difference between revisions

Content added Content deleted
(Replace println() with print(); replace output "syntaxhighlight" tag with "pre" tag)
Line 728: Line 728:
J does support a "[http://www.jsoftware.com/help/dictionary/dx003.htm Lock Script]" mechanism - to transform a J script so that it's unreadable. However, anyone with access to a machine running the code and ordinary developer tools or who understands the "locking" technique could unlock it.
J does support a "[http://www.jsoftware.com/help/dictionary/dx003.htm Lock Script]" mechanism - to transform a J script so that it's unreadable. However, anyone with access to a machine running the code and ordinary developer tools or who understands the "locking" technique could unlock it.
=={{header|Java}}==
=={{header|Java}}==
<p>
Private fields (and in general all members) of a Java class can be accessed via reflection, but must pass a security check in order to do so. There are two such security checks, one for discovering the field at all, and another for granting access to it in order to be able to read and write it. (This in turn means that trusted applications can do this — it is in fact a mechanism used by important frameworks like Spring — but untrusted applets cannot.)
In order the access a class member of another class which is marked as <code>private</code>, you'll need to use <kbd>reflection</kbd>.<br />
<syntaxhighlight lang="java">import java.lang.reflect.*;
Java offers a collection of <kbd>reflection</kbd>-related utilities within the <code>java.lang.reflect</code> package.
</p>
<p>
In this example I'll use a class with two fields, <code>stringA</code> and <code>stringB</code>.
</p>
<syntaxhighlight lang="java">
class Example {
class Example {
private String _name;
String stringA = "rosetta";
private String stringB = "code";
public Example(String name) { _name = name; }
public String toString() { return "Hello, I am " + _name; }
}
}
</syntaxhighlight>
<p>
public class BreakPrivacy {
From another class, I'll instantiate <code>Example</code>, and use a <code>Field</code> object to return a specified, declared field.<br />
public static final void main(String[] args) throws Exception {
To do this you call the <code>getDeclaredField</code> on your <code>Class</code> object, supplying the <kbd>name</kbd> of the field.
Example foo = new Example("Eric");
</p>
<syntaxhighlight lang="java">
for (Field f : Example.class.getDeclaredFields()) {
Example example = new Example();
if (f.getName().equals("_name")) {
Field field = example.getClass().getDeclaredField("stringB");
// make it accessible
</syntaxhighlight>
f.setAccessible(true);
<p>
To allow access to <code>stringB</code> we'll need to use the <code>Field.setAccessible</code> method, and signify <kbd>true</kbd>.<br />
// get private field
This is essentially what the task is looking for, the ability to override the <kbd>access-modifier</kbd>.
System.out.println(f.get(foo));
</p>
<syntaxhighlight lang="java">
// set private field
field.setAccessible(true);
f.set(foo, "Edith");
</syntaxhighlight>
System.out.println(foo);
<p>
Now, we can access the data from the field by using the <code>Field.get</code> method, specifying the instance as the parameter.
break;
</p>
}
<syntaxhighlight lang="java">
}
String stringB = (String) field.get(example);
}
}</syntaxhighlight>
</syntaxhighlight>
<p>
{{out}}
So, all together our method would contain the following lines.
</p>
<syntaxhighlight lang="java">
Example example = new Example();
Field field = example.getClass().getDeclaredField("stringB");
field.setAccessible(true);
String stringA = example.stringA;
String stringB = (String) field.get(example);
System.out.println(stringA + " " + stringB);
</syntaxhighlight>
<p>
With an output of the following.
</p>
<pre>
<pre>
rosetta code
Eric
Hello, I am Edith
</pre>
</pre>
<p>
All classes are vulnerable to this, including <code>String</code> (and therefore, string literals). How long is the word "cat"?
If we hadn't used the <code>Field.setAccessible</code> method, we would get an <code>IllegalAccessException</code>.
</p>
<pre>
cannot access a member of class Example with modifiers "private"
</pre>
<p>
Additionally, you can do this with methods via the <code>Method</code> object.<br />
Consider the following class.
</p>
<syntaxhighlight lang="java">
class Example {
String stringA = "rosetta";


private String stringB() {
(Note: somewhere between Java 8 and Java 11 this stopped working because the <code>value</code> field of <code>String</code> is <code>final</code>. The reflective access is still possible, but changing a final field isn't.)
return "code";
<syntaxhighlight lang="java">import java.lang.reflect.*;
}
public class BreakString{
public static void main(String... args) throws Exception{
Field f = String.class.getDeclaredField("value");
f.setAccessible(true);
f.set("cat",new char[]{'t','i','g','e','r'});
System.out.println("cat");
System.out.println("cat".length());
}
}
}
</syntaxhighlight>
</syntaxhighlight>
<p>
{{out}}
The approach is the same, except we are using <code>getDeclaredMethod</code>, and instead of <code>get</code> we are using <code>invoke</code>.
</p>
<syntaxhighlight lang="java">
Example example = new Example();
Method method = example.getClass().getDeclaredMethod("stringB");
method.setAccessible(true);
String stringA = example.stringA;
String stringB = (String) method.invoke(example);
System.out.println(stringA + " " + stringB);
</syntaxhighlight>
<pre>
<pre>
rosetta code
tiger
5
</pre>
</pre>

=={{header|Julia}}==
=={{header|Julia}}==