Break OO privacy: Difference between revisions

Omit Zig
(Add Ecstasy example)
(Omit Zig)
 
(5 intermediate revisions by 4 users not shown)
Line 436:
Ecstasy security is accomplished by the use of <i>software containers</i>. Code running in a container is always allowed reveal any legal type on any object created within that container, including any object created within sub-containers. However, the runtime will reject any reveal request on any object that was <i>not</i> created within that container.
<syntaxhighlight lang="java">
module BreakOO {
{
/**
* This is a class with public, protected, and private properties.
*/
class Exposed {
{
public String pub = "public";
protected String pro = "protected";
Line 448 ⟶ 446:
 
@Override
String toString() {
{
return $"pub={pub.quoted()}, pro={pro.quoted()}, pri={pri.quoted()}";
}
}
}
 
void run() {
{
@Inject Console console;
 
Exposed expo = new Exposed();
console.printlnprint($"before: {expo}");
 
// you can only access public members from the default reference
Line 482 ⟶ 478:
expoStr.pri = $"{expoStr.pri}!!!";
 
console.printlnprint($"after: {expo}");
}
}
}
</syntaxhighlight>
 
{{out}}
Output:
<pre>
<syntaxhighlight>
before: pub="public", pro="protected", pri="private"
after: pub="this was public!!!", pro="this was protected!!!", pri="this was private!!!"
</pre>
</syntaxhighlight>
 
=={{header|F_Sharp|F#}}==
Line 728 ⟶ 724:
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}}==
<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 {
private String _namestringA = "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>
<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>
rosetta code
Eric
Hello, I am Edith
</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>
<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>
rosetta code
tiger
5
</pre>
 
=={{header|Julia}}==
 
Line 1,430 ⟶ 1,457:
 
However, there is no such thing as a private method. Although conventionally methods which are not intended to be called from outside the class are suffixed with an underscore, this doesn't prevent anyone from accessing them as the following example shows.
<syntaxhighlight lang="ecmascriptwren">class Safe {
construct new() { _safe = 42 } // the field _safe is private
safe { _safe } // provides public access to field
Line 1,447 ⟶ 1,474:
84
</pre>
 
=={{header|zkl}}==
In zkl, privacy is more convention than enforced (unlike const or protected).
Line 1,478 ⟶ 1,506:
{{omit from|x86 Assembly}}
{{omit from|Z80 Assembly}}
{{omit from|Zig}}
{{omit from|ZX Spectrum Basic}}
{{omit from|Insitux}}
28

edits