Break OO privacy: Difference between revisions

Omit Zig
m (Automated syntax highlighting fixup (second round - minor fixes))
(Omit Zig)
 
(6 intermediate revisions by 4 users not shown)
Line 428:
 
{{improve|E|Show an example of such an evaluator once it is available.}}
 
=={{header|Ecstasy}}==
In Ecstasy, using the keywords <span style="background-color: #e5e4e2"><tt>&nbsp;public&nbsp;</tt></span>, <span style="background-color: #e5e4e2"><tt>&nbsp;protected&nbsp;</tt></span>, and <span style="background-color: #e5e4e2"><tt>&nbsp;private&nbsp;</tt></span> to mark classes and class members is solely for the benefit of the developer, and not in any way related to security. These keywords help the developer to classify information among three categories: Things that are useful to everyone; things that are useful to further compositions (such as sub-classes and mixins); and things that, were they exposed, would likely to create an ugly mess. <b>Information hiding is about organization, and not about security.</b>
 
An Ecstasy reference contains both its type (the type of the <i>reference</i> itself, as opposed to the type of the referred-to object, a.k.a. the <i>referent</i>), and the means -- a "pointer" or a "value" -- to refer to the referent. By default, the type of a reference is of the <i>public type</i> of the referent, but it is possible to reveal the referent as any other legal type -- where <i>legal</i> simply means that strong type safety is enforced. This is <b>not</b> a type cast; it is a request to the runtime to provide a different reference to the same underlying object.
 
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";
private String pri = "private";
 
@Override
String toString() {
return $"pub={pub.quoted()}, pro={pro.quoted()}, pri={pri.quoted()}";
}
}
 
void run() {
@Inject Console console;
 
Exposed expo = new Exposed();
console.print($"before: {expo}");
 
// you can only access public members from the default reference
expo.pub = $"this was {expo.pub}";
// expo.pro = $"this was {expo.pro}"; <- compiler error
// expo.pri = $"this was {expo.pri}"; <- compiler error
 
// but you can ask for the protected reference ...
assert (protected Exposed) expoPro := &expo.revealAs((protected Exposed));
expoPro.pro = $"this was {expoPro.pro}";
// expoPro.pri = $"this was {expoPro.pri}"; <- compiler error
 
// and you can ask for the private reference ...
assert (private Exposed) expoPri := &expo.revealAs((private Exposed));
expoPri.pri = $"this was {expoPri.pri}";
 
// or you can ask for the underlying struct, which is a passive
// object that contains only the field storage
assert (struct Exposed) expoStr := &expo.revealAs((struct Exposed));
expoStr.pub = $"{expoStr.pub}!!!";
expoStr.pro = $"{expoStr.pro}!!!";
expoStr.pri = $"{expoStr.pri}!!!";
 
console.print($"after: {expo}");
}
}
</syntaxhighlight>
 
{{out}}
<pre>
before: pub="public", pro="protected", pri="private"
after: pub="this was public!!!", pro="this was protected!!!", pri="this was private!!!"
</pre>
 
=={{header|F_Sharp|F#}}==
{{trans|C#}}
Line 663 ⟶ 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,365 ⟶ 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,382 ⟶ 1,474:
84
</pre>
 
=={{header|zkl}}==
In zkl, privacy is more convention than enforced (unlike const or protected).
Line 1,413 ⟶ 1,506:
{{omit from|x86 Assembly}}
{{omit from|Z80 Assembly}}
{{omit from|Zig}}
{{omit from|ZX Spectrum Basic}}
{{omit from|Insitux}}
28

edits