1109 lines
58 KiB
HTML
1109 lines
58 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<html>
|
||
|
<head>
|
||
|
<meta charset="utf-8">
|
||
|
<meta content="IE=edge" http-equiv="X-UA-Compatible">
|
||
|
<meta content="width=device-width, initial-scale=1.0" name="viewport">
|
||
|
<title>Defensive Coding Guide | Defensive Coding Guide | Programming Languages | The Java Programming Language</title>
|
||
|
|
||
|
<!-- Bootstrap -->
|
||
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
|
||
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
|
||
|
|
||
|
<!-- Overpass Font -->
|
||
|
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
|
||
|
|
||
|
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
|
||
|
|
||
|
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
|
||
|
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
||
|
<!--[if lt IE 9]>
|
||
|
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
|
||
|
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||
|
<![endif]-->
|
||
|
|
||
|
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
|
||
|
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
|
||
|
<meta content="AsciiBinder" name="application-name">
|
||
|
</head>
|
||
|
<body>
|
||
|
<div class="navbar navbar-default" role="navigation">
|
||
|
<div class="container-fluid">
|
||
|
<div class="navbar-header">
|
||
|
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="container">
|
||
|
<p class="toggle-nav visible-xs pull-left">
|
||
|
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
|
||
|
</p>
|
||
|
<ol class="breadcrumb">
|
||
|
<li class="sitename">
|
||
|
<a href="../../../index.html">Home</a>
|
||
|
</li>
|
||
|
<li class="hidden-xs active">
|
||
|
<a href="../../en-US/index.html">Defensive Coding Guide </a>
|
||
|
</li>
|
||
|
<li class="hidden-xs active">
|
||
|
<a href="../../en-US/index.html">Defensive Coding Guide</a>
|
||
|
</li>
|
||
|
<li class="hidden-xs active"><a href="../../en-US/programming-languages/C.html">Programming Languages</a></li>
|
||
|
<li class="hidden-xs active">
|
||
|
The Java Programming Language
|
||
|
</li>
|
||
|
</ol>
|
||
|
<div class="row row-offcanvas row-offcanvas-left">
|
||
|
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
|
||
|
<ul class="nav nav-sidebar">
|
||
|
<li class="nav-header">
|
||
|
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
|
||
|
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
|
||
|
</a>
|
||
|
<ul id="topicGroup0" class="collapse in list-unstyled">
|
||
|
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
|
||
|
<li class="nav-header">
|
||
|
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
|
||
|
<span id="sgSpan-0-1" class="fa fa-caret-down"></span> Programming Languages
|
||
|
</a>
|
||
|
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse in">
|
||
|
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
|
||
|
<li><a class="" href="../../en-US/programming-languages/CXX.html">The C++ Programming Language</a></li>
|
||
|
<li><a class=" active" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
|
||
|
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
|
||
|
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
|
||
|
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
|
||
|
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li class="nav-header">
|
||
|
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
|
||
|
<span id="sgSpan-0-2" class="fa fa-caret-right"></span> Specific Programming Tasks
|
||
|
</a>
|
||
|
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse">
|
||
|
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
|
||
|
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
|
||
|
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
|
||
|
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
|
||
|
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
|
||
|
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
|
||
|
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
|
||
|
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li class="nav-header">
|
||
|
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
|
||
|
<span id="sgSpan-0-3" class="fa fa-caret-right"></span> Implementing Security Features
|
||
|
</a>
|
||
|
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse">
|
||
|
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
|
||
|
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
|
||
|
<li><a class="" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
<div class="col-xs-12 col-sm-9 col-md-9 main">
|
||
|
<div class="page-header">
|
||
|
<h2>The Java Programming Language</h2>
|
||
|
</div>
|
||
|
<div class="sect1">
|
||
|
<h2 id="sect-Defensive_Coding-Java-Language"><a class="anchor" href="#sect-Defensive_Coding-Java-Language"></a>The Core Language</h2>
|
||
|
<div class="sectionbody">
|
||
|
<div class="paragraph">
|
||
|
<p>Implementations of the Java programming language provide strong
|
||
|
memory safety, even in the presence of data races in concurrent
|
||
|
code. This prevents a large range of security vulnerabilities
|
||
|
from occurring, unless certain low-level features are used; see
|
||
|
<a href="#sect-Defensive_Coding-Java-LowLevel">Low-level Features of the Virtual Machine</a>.</p>
|
||
|
</div>
|
||
|
<div class="sect2">
|
||
|
<h3 id="sect-Defensive_Coding-Java-Language-ReadArray"><a class="anchor" href="#sect-Defensive_Coding-Java-Language-ReadArray"></a>Increasing Robustness when Reading Arrays</h3>
|
||
|
<div class="paragraph">
|
||
|
<p>External data formats often include arrays, and the data is
|
||
|
stored as an integer indicating the number of array elements,
|
||
|
followed by this number of elements in the file or protocol data
|
||
|
unit. This length specified can be much larger than what is
|
||
|
actually available in the data source.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>To avoid allocating extremely large amounts of data, you can
|
||
|
allocate a small array initially and grow it as you read more
|
||
|
data, implementing an exponential growth policy. See the
|
||
|
<code>readBytes(InputStream, int)</code> function in
|
||
|
<a href="#ex-Defensive_Coding-Java-Language-ReadArray">Incrementally reading a byte array</a>.</p>
|
||
|
</div>
|
||
|
<div id="ex-Defensive_Coding-Java-Language-ReadArray" class="exampleblock">
|
||
|
<div class="title">Example 1. Incrementally reading a byte array</div>
|
||
|
<div class="content">
|
||
|
<div class="listingblock">
|
||
|
<div class="content">
|
||
|
<pre class="CodeRay highlight"><code data-lang="java"><span style="color:#088;font-weight:bold">static</span> <span style="color:#339;font-weight:bold">byte</span><span style="color:#339;font-weight:bold">[]</span> readBytes(<span style="color:#0a8;font-weight:bold">InputStream</span> in, <span style="color:#339;font-weight:bold">int</span> length) <span style="color:#088;font-weight:bold">throws</span> <span style="color:#C00;font-weight:bold">IOException</span> {
|
||
|
<span style="color:#088;font-weight:bold">final</span> <span style="color:#339;font-weight:bold">int</span> startSize = <span style="color:#00D">65536</span>;
|
||
|
<span style="color:#339;font-weight:bold">byte</span><span style="color:#339;font-weight:bold">[]</span> b = <span style="color:#080;font-weight:bold">new</span> <span style="color:#339;font-weight:bold">byte</span>[<span style="color:#0a8;font-weight:bold">Math</span>.min(length, startSize)];
|
||
|
<span style="color:#339;font-weight:bold">int</span> filled = <span style="color:#00D">0</span>;
|
||
|
<span style="color:#080;font-weight:bold">while</span> (<span style="color:#069">true</span>) {
|
||
|
<span style="color:#339;font-weight:bold">int</span> remaining = b.length - filled;
|
||
|
readFully(in, b, filled, remaining);
|
||
|
<span style="color:#080;font-weight:bold">if</span> (b.length == length) {
|
||
|
<span style="color:#080;font-weight:bold">break</span>;
|
||
|
}
|
||
|
filled = b.length;
|
||
|
<span style="color:#080;font-weight:bold">if</span> (length - b.length <= b.length) {
|
||
|
<span style="color:#777">// Allocate final length. Condition avoids overflow.</span>
|
||
|
b = <span style="color:#0a8;font-weight:bold">Arrays</span>.copyOf(b, length);
|
||
|
} <span style="color:#080;font-weight:bold">else</span> {
|
||
|
b = <span style="color:#0a8;font-weight:bold">Arrays</span>.copyOf(b, b.length * <span style="color:#00D">2</span>);
|
||
|
}
|
||
|
}
|
||
|
<span style="color:#080;font-weight:bold">return</span> b;
|
||
|
}
|
||
|
|
||
|
<span style="color:#088;font-weight:bold">static</span> <span style="color:#339;font-weight:bold">void</span> readFully(<span style="color:#0a8;font-weight:bold">InputStream</span> in,<span style="color:#339;font-weight:bold">byte</span><span style="color:#339;font-weight:bold">[]</span> b, <span style="color:#339;font-weight:bold">int</span> off, <span style="color:#339;font-weight:bold">int</span> len)
|
||
|
<span style="color:#088;font-weight:bold">throws</span> <span style="color:#C00;font-weight:bold">IOException</span> {
|
||
|
<span style="color:#339;font-weight:bold">int</span> startlen = len;
|
||
|
<span style="color:#080;font-weight:bold">while</span> (len > <span style="color:#00D">0</span>) {
|
||
|
<span style="color:#339;font-weight:bold">int</span> count = in.read(b, off, len);
|
||
|
<span style="color:#080;font-weight:bold">if</span> (count < <span style="color:#00D">0</span>) {
|
||
|
<span style="color:#080;font-weight:bold">throw</span> <span style="color:#080;font-weight:bold">new</span> <span style="color:#C00;font-weight:bold">EOFException</span>();
|
||
|
}
|
||
|
off += count;
|
||
|
len -= count;
|
||
|
}
|
||
|
}</code></pre>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>When reading data into arrays, hash maps or hash sets, use the
|
||
|
default constructor and do not specify a size hint. You can
|
||
|
simply add the elements to the collection as you read them.</p>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="sect2">
|
||
|
<h3 id="sect-Defensive_Coding-Java-Language-Resources"><a class="anchor" href="#sect-Defensive_Coding-Java-Language-Resources"></a>Resource Management</h3>
|
||
|
<div class="paragraph">
|
||
|
<p>Unlike C++, Java does not offer destructors which can deallocate
|
||
|
resources in a predictable fashion. All resource management has
|
||
|
to be manual, at the usage site. (Finalizers are generally not
|
||
|
usable for resource management, especially in high-performance
|
||
|
code; see <a href="#sect-Defensive_Coding-Java-Language-Finalizers">Finalizers</a>.)</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>The first option is the
|
||
|
<code>try</code>-<code>finally</code> construct, as
|
||
|
shown in <a href="#ex-Defensive_Coding-Java-Language-Finally">Resource management with a <code>try</code>-<code>finally</code> block</a>.
|
||
|
The code in the <code>finally</code> block should be as short as
|
||
|
possible and should not throw any exceptions.</p>
|
||
|
</div>
|
||
|
<div id="ex-Defensive_Coding-Java-Language-Finally" class="exampleblock">
|
||
|
<div class="title">Example 2. Resource management with a <code>try</code>-<code>finally</code> block</div>
|
||
|
<div class="content">
|
||
|
<div class="listingblock">
|
||
|
<div class="content">
|
||
|
<pre class="CodeRay highlight"><code data-lang="java"><span style="color:#0a8;font-weight:bold">InputStream</span> in = <span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">BufferedInputStream</span>(<span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">FileInputStream</span>(path));
|
||
|
<span style="color:#080;font-weight:bold">try</span> {
|
||
|
readFile(in);
|
||
|
} <span style="color:#080;font-weight:bold">finally</span> {
|
||
|
in.close();
|
||
|
}</code></pre>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>Note that the resource allocation happens
|
||
|
<strong>outside</strong> the <code>try</code> block,
|
||
|
and that there is no <code>null</code> check in the
|
||
|
<code>finally</code> block. (Both are common artifacts
|
||
|
stemming from IDE code templates.)</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>If the resource object is created freshly and implements the
|
||
|
<code>java.lang.AutoCloseable</code> interface, the code
|
||
|
in <a href="#ex-Defensive_Coding-Java-Language-TryWithResource">Resource management using the <code>try</code>-with-resource construct</a> can be
|
||
|
used instead. The Java compiler will automatically insert the
|
||
|
<code>close()</code> method call in a synthetic
|
||
|
<code>finally</code> block.</p>
|
||
|
</div>
|
||
|
<div id="ex-Defensive_Coding-Java-Language-TryWithResource" class="exampleblock">
|
||
|
<div class="title">Example 3. Resource management using the <code>try</code>-with-resource construct</div>
|
||
|
<div class="content">
|
||
|
<div class="listingblock">
|
||
|
<div class="content">
|
||
|
<pre class="CodeRay highlight"><code data-lang="java"><span style="color:#080;font-weight:bold">try</span> (<span style="color:#0a8;font-weight:bold">InputStream</span> in = <span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">BufferedInputStream</span>(<span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">FileInputStream</span>(path))) {
|
||
|
readFile(in);
|
||
|
}</code></pre>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>To be compatible with the <code>try</code>-with-resource
|
||
|
construct, new classes should name the resource deallocation
|
||
|
method <code>close()</code>, and implement the
|
||
|
<code>AutoCloseable</code> interface (the latter breaking
|
||
|
backwards compatibility with Java 6). However, using the
|
||
|
<code>try</code>-with-resource construct with objects that
|
||
|
are not freshly allocated is at best awkward, and an explicit
|
||
|
<code>finally</code> block is usually the better approach.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>In general, it is best to design the programming interface in
|
||
|
such a way that resource deallocation methods like
|
||
|
<code>close()</code> cannot throw any (checked or
|
||
|
unchecked) exceptions, but this should not be a reason to ignore
|
||
|
any actual error conditions.</p>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="sect2">
|
||
|
<h3 id="sect-Defensive_Coding-Java-Language-Finalizers"><a class="anchor" href="#sect-Defensive_Coding-Java-Language-Finalizers"></a>Finalizers</h3>
|
||
|
<div class="paragraph">
|
||
|
<p>Finalizers can be used a last-resort approach to free resources
|
||
|
which would otherwise leak. Finalization is unpredictable,
|
||
|
costly, and there can be a considerable delay between the last
|
||
|
reference to an object going away and the execution of the
|
||
|
finalizer. Generally, manual resource management is required;
|
||
|
see <a href="#sect-Defensive_Coding-Java-Language-Resources">Resource Management</a>.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>Finalizers should be very short and should only deallocate
|
||
|
native or other external resources held directly by the object
|
||
|
being finalized. In general, they must use synchronization:
|
||
|
Finalization necessarily happens on a separate thread because it is
|
||
|
inherently concurrent. There can be multiple finalization
|
||
|
threads, and despite each object being finalized at most once,
|
||
|
the finalizer must not assume that it has exclusive access to
|
||
|
the object being finalized (in the <code>this</code>
|
||
|
pointer).</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>Finalizers should not deallocate resources held by other
|
||
|
objects, especially if those objects have finalizers on their
|
||
|
own. In particular, it is a very bad idea to define a finalizer
|
||
|
just to invoke the resource deallocation method of another object,
|
||
|
or overwrite some pointer fields.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>Finalizers are not guaranteed to run at all. For instance, the
|
||
|
virtual machine (or the machine underneath) might crash,
|
||
|
preventing their execution.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>Objects with finalizers are garbage-collected much later than
|
||
|
objects without them, so using finalizers to zero out key
|
||
|
material (to reduce its undecrypted lifetime in memory) may have
|
||
|
the opposite effect, keeping objects around for much longer and
|
||
|
prevent them from being overwritten in the normal course of
|
||
|
program execution.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>For the same reason, code which allocates objects with
|
||
|
finalizers at a high rate will eventually fail (likely with a
|
||
|
<code>java.lang.OutOfMemoryError</code> exception) because
|
||
|
the virtual machine has finite resources for keeping track of
|
||
|
objects pending finalization. To deal with that, it may be
|
||
|
necessary to recycle objects with finalizers.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>The remarks in this section apply to finalizers which are
|
||
|
implemented by overriding the <code>finalize()</code>
|
||
|
method, and to custom finalization using reference queues.</p>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="sect2">
|
||
|
<h3 id="sect-Defensive_Coding-Java-Language-Exceptions"><a class="anchor" href="#sect-Defensive_Coding-Java-Language-Exceptions"></a>Recovering from Exceptions and Errors</h3>
|
||
|
<div class="paragraph">
|
||
|
<p>Java exceptions come in three kinds, all ultimately deriving
|
||
|
from <code>java.lang.Throwable</code>:</p>
|
||
|
</div>
|
||
|
<div class="ulist">
|
||
|
<ul>
|
||
|
<li>
|
||
|
<p><strong>Run-time exceptions</strong> do not have to be
|
||
|
declared explicitly and can be explicitly thrown from any
|
||
|
code, by calling code which throws them, or by triggering an
|
||
|
error condition at run time, like division by zero, or an
|
||
|
attempt at an out-of-bounds array access. These exceptions
|
||
|
derive from from the
|
||
|
<code>java.lang.RuntimeException</code> class (perhaps
|
||
|
indirectly).</p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p><strong>Checked exceptions</strong> have to be declared
|
||
|
explicitly by functions that throw or propagate them. They
|
||
|
are similar to run-time exceptions in other regards, except
|
||
|
that there is no language construct to throw them (except
|
||
|
the <code>throw</code> statement itself). Checked
|
||
|
exceptions are only present at the Java language level and
|
||
|
are only enforced at compile time. At run time, the virtual
|
||
|
machine does not know about them and permits throwing
|
||
|
exceptions from any code. Checked exceptions must derive
|
||
|
(perhaps indirectly) from the
|
||
|
<code>java.lang.Exception</code> class, but not from
|
||
|
<code>java.lang.RuntimeException</code>.</p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p><strong>Errors</strong> are exceptions which typically
|
||
|
reflect serious error conditions. They can be thrown at any
|
||
|
point in the program, and do not have to be declared (unlike
|
||
|
checked exceptions). In general, it is not possible to
|
||
|
recover from such errors; more on that below, in <a href="#sect-Defensive_Coding-Java-Language-Exceptions-Errors">The Difficulty of Catching Errors</a>.
|
||
|
Error classes derive (perhaps indirectly) from
|
||
|
<code>java.lang.Error</code>, or from
|
||
|
<code>java.lang.Throwable</code>, but not from
|
||
|
<code>java.lang.Exception</code>.</p>
|
||
|
</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>The general expection is that run-time errors are avoided by
|
||
|
careful programming (e.g., not dividing by zero). Checked
|
||
|
exception are expected to be caught as they happen (e.g., when
|
||
|
an input file is unexpectedly missing). Errors are impossible
|
||
|
to predict and can happen at any point and reflect that
|
||
|
something went wrong beyond all expectations.</p>
|
||
|
</div>
|
||
|
<div class="sect3">
|
||
|
<h4 id="sect-Defensive_Coding-Java-Language-Exceptions-Errors"><a class="anchor" href="#sect-Defensive_Coding-Java-Language-Exceptions-Errors"></a>The Difficulty of Catching Errors</h4>
|
||
|
<div class="paragraph">
|
||
|
<p>Errors (that is, exceptions which do not (indirectly) derive
|
||
|
from <code>java.lang.Exception</code>), have the
|
||
|
peculiar property that catching them is problematic. There
|
||
|
are several reasons for this:</p>
|
||
|
</div>
|
||
|
<div class="ulist">
|
||
|
<ul>
|
||
|
<li>
|
||
|
<p>The error reflects a failed consistenty check, for example,
|
||
|
<code>java.lang.AssertionError</code>.</p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p>The error can happen at any point, resulting in
|
||
|
inconsistencies due to half-updated objects. Examples are
|
||
|
<code>java.lang.ThreadDeath</code>,
|
||
|
<code>java.lang.OutOfMemoryError</code> and
|
||
|
<code>java.lang.StackOverflowError</code>.</p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p>The error indicates that virtual machine failed to provide
|
||
|
some semantic guarantees by the Java programming language.
|
||
|
<code>java.lang.ExceptionInInitializerError</code>
|
||
|
is an example—it can leave behind a half-initialized
|
||
|
class.</p>
|
||
|
</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>In general, if an error is thrown, the virtual machine should
|
||
|
be restarted as soon as possible because it is in an
|
||
|
inconsistent state. Continuing running as before can have
|
||
|
unexpected consequences. However, there are legitimate
|
||
|
reasons for catching errors because not doing so leads to even
|
||
|
greater problems.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>Code should be written in a way that avoids triggering errors.
|
||
|
See <a href="#sect-Defensive_Coding-Java-Language-ReadArray">Increasing Robustness when Reading Arrays</a>
|
||
|
for an example.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>It is usually necessary to log errors. Otherwise, no trace of
|
||
|
the problem might be left anywhere, making it very difficult
|
||
|
to diagnose realted failures. Consequently, if you catch
|
||
|
<code>java.lang.Exception</code> to log and suppress all
|
||
|
unexpected exceptions (for example, in a request dispatching
|
||
|
loop), you should consider switching to
|
||
|
<code>java.lang.Throwable</code> instead, to also cover
|
||
|
errors.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>The other reason mainly applies to such request dispatching
|
||
|
loops: If you do not catch errors, the loop stops looping,
|
||
|
resulting in a denial of service.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>However, if possible, catching errors should be coupled with a
|
||
|
way to signal the requirement of a virtual machine restart.</p>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="sect1">
|
||
|
<h2 id="sect-Defensive_Coding-Java-LowLevel"><a class="anchor" href="#sect-Defensive_Coding-Java-LowLevel"></a>Low-level Features of the Virtual Machine</h2>
|
||
|
<div class="sectionbody">
|
||
|
<div class="sect2">
|
||
|
<h3 id="sect-Defensive_Coding-Java-Reflection"><a class="anchor" href="#sect-Defensive_Coding-Java-Reflection"></a>Reflection and Private Parts</h3>
|
||
|
<div class="paragraph">
|
||
|
<p>The <code>setAccessible(boolean)</code> method of the
|
||
|
<code>java.lang.reflect.AccessibleObject</code> class
|
||
|
allows a program to disable language-defined access rules for
|
||
|
specific constructors, methods, or fields. Once the access
|
||
|
checks are disabled, any code can use the
|
||
|
<code>java.lang.reflect.Constructor</code>,
|
||
|
<code>java.lang.reflect.Method</code>, or
|
||
|
<code>java.lang.reflect.Field</code> object to access the
|
||
|
underlying Java entity, without further permission checks. This
|
||
|
breaks encapsulation and can undermine the stability of the
|
||
|
virtual machine. (In contrast, without using the
|
||
|
<code>setAccessible(boolean)</code> method, this should
|
||
|
not happen because all the language-defined checks still apply.)</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>This feature should be avoided if possible.</p>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="sect2">
|
||
|
<h3 id="sect-Defensive_Coding-Java-JNI"><a class="anchor" href="#sect-Defensive_Coding-Java-JNI"></a>Java Native Interface (JNI)</h3>
|
||
|
<div class="paragraph">
|
||
|
<p>The Java Native Interface allows calling from Java code
|
||
|
functions specifically written for this purpose, usually in C or
|
||
|
C++.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>The transition between the Java world and the C world is not
|
||
|
fully type-checked, and the C code can easily break the Java
|
||
|
virtual machine semantics. Therefore, extra care is needed when
|
||
|
using this functionality.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>To provide a moderate amount of type safety, it is recommended
|
||
|
to recreate the class-specific header file using
|
||
|
<strong class="application">javah</strong> during the build process,
|
||
|
include it in the implementation, and use the
|
||
|
<code class="option">-Wmissing-declarations</code> option.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>Ideally, the required data is directly passed to static JNI
|
||
|
methods and returned from them, and the code and the C side does
|
||
|
not have to deal with accessing Java fields (or even methods).</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>When using <code>GetPrimitiveArrayCritical</code> or
|
||
|
<code>GetStringCritical</code>, make sure that you only
|
||
|
perform very little processing between the get and release
|
||
|
operations. Do not access the file system or the network, and
|
||
|
not perform locking, because that might introduce blocking.
|
||
|
When processing large strings or arrays, consider splitting the
|
||
|
computation into multiple sub-chunks, so that you do not prevent
|
||
|
the JVM from reaching a safepoint for extended periods of time.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>If necessary, you can use the Java <code>long</code> type
|
||
|
to store a C pointer in a field of a Java class. On the C side,
|
||
|
when casting between the <code>jlong</code> value and the
|
||
|
pointer on the C side,</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>You should not try to perform pointer arithmetic on the Java
|
||
|
side (that is, you should treat pointer-carrying
|
||
|
<code>long</code> values as opaque). When passing a slice
|
||
|
of an array to the native code, follow the Java convention and
|
||
|
pass it as the base array, the integer offset of the start of
|
||
|
the slice, and the integer length of the slice. On the native
|
||
|
side, check the offset/length combination against the actual
|
||
|
array length, and use the offset to compute the pointer to the
|
||
|
beginning of the array.</p>
|
||
|
</div>
|
||
|
<div id="ex-Defensive_Coding-Java-JNI-Pointers" class="exampleblock">
|
||
|
<div class="title">Example 4. Array length checking in JNI code</div>
|
||
|
<div class="content">
|
||
|
<div class="listingblock">
|
||
|
<div class="content">
|
||
|
<pre class="CodeRay highlight"><code data-lang="java">JNIEXPORT jint JNICALL Java_sum
|
||
|
(JNIEnv *jEnv, jclass clazz, jbyteArray buffer, jint offset, jint length)
|
||
|
{
|
||
|
<span style="color:#080;font-weight:bold">assert</span>(sizeof(jint) == sizeof(unsigned));
|
||
|
<span style="color:#080;font-weight:bold">if</span> (offset < <span style="color:#00D">0</span> || length < <span style="color:#00D">0</span>) {
|
||
|
(*jEnv)->ThrowNew(jEnv, arrayIndexOutOfBoundsExceptionClass,
|
||
|
<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">negative offset/length</span><span style="color:#710">"</span></span>);
|
||
|
<span style="color:#080;font-weight:bold">return</span> <span style="color:#00D">0</span>;
|
||
|
}
|
||
|
unsigned uoffset = offset;
|
||
|
unsigned ulength = length;
|
||
|
<span style="color:#777">// This cannot overflow because of the check above.</span>
|
||
|
unsigned totallength = uoffset + ulength;
|
||
|
unsigned actuallength = (*jEnv)->GetArrayLength(jEnv, buffer);
|
||
|
<span style="color:#080;font-weight:bold">if</span> (totallength > actuallength) {
|
||
|
(*jEnv)->ThrowNew(jEnv, arrayIndexOutOfBoundsExceptionClass,
|
||
|
<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">offset + length too large</span><span style="color:#710">"</span></span>);
|
||
|
<span style="color:#080;font-weight:bold">return</span> <span style="color:#00D">0</span>;
|
||
|
}
|
||
|
unsigned <span style="color:#339;font-weight:bold">char</span> *ptr = (*jEnv)->GetPrimitiveArrayCritical(jEnv, buffer, <span style="color:#00D">0</span>);
|
||
|
<span style="color:#080;font-weight:bold">if</span> (ptr == NULL) {
|
||
|
<span style="color:#080;font-weight:bold">return</span> <span style="color:#00D">0</span>;
|
||
|
}
|
||
|
unsigned <span style="color:#339;font-weight:bold">long</span> <span style="color:#339;font-weight:bold">long</span> sum = <span style="color:#00D">0</span>;
|
||
|
<span style="color:#080;font-weight:bold">for</span> (unsigned <span style="color:#339;font-weight:bold">char</span> *p = ptr + uoffset, *end = p + ulength; p != end; ++p) {
|
||
|
sum += *p;
|
||
|
}
|
||
|
(*jEnv)->ReleasePrimitiveArrayCritical(jEnv, buffer, ptr, <span style="color:#00D">0</span>);
|
||
|
<span style="color:#080;font-weight:bold">return</span> sum;
|
||
|
}</code></pre>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>In any case, classes referring to native resources must be
|
||
|
declared <code>final</code>, and must not be serializeable
|
||
|
or cloneable. Initialization and mutation of the state used by
|
||
|
the native side must be controlled carefully. Otherwise, it
|
||
|
might be possible to create an object with inconsistent native
|
||
|
state which results in a crash (or worse) when used (or perhaps
|
||
|
only finalized) later. If you need both Java inheritance and
|
||
|
native resources, you should consider moving the native state to
|
||
|
a separate class, and only keep a reference to objects of that
|
||
|
class. This way, cloning and serialization issues can be
|
||
|
avoided in most cases.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>If there are native resources associated with an object, the
|
||
|
class should have an explicit resource deallocation method
|
||
|
(<a href="#sect-Defensive_Coding-Java-Language-Resources">Resource Management</a>) and a
|
||
|
finalizer (<a href="#sect-Defensive_Coding-Java-Language-Finalizers">Finalizers</a>) as a
|
||
|
last resort. The need for finalization means that a minimum
|
||
|
amount of synchronization is needed. Code on the native side
|
||
|
should check that the object is not in a closed/freed state.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>Many JNI functions create local references. By default, these
|
||
|
persist until the JNI-implemented method returns. If you create
|
||
|
many such references (e.g., in a loop), you may have to free
|
||
|
them using <code>DeleteLocalRef</code>, or start using
|
||
|
<code>PushLocalFrame</code> and
|
||
|
<code>PopLocalFrame</code>. Global references must be
|
||
|
deallocated with <code>DeleteGlobalRef</code>, otherwise
|
||
|
there will be a memory leak, just as with
|
||
|
<code>malloc</code> and <code>free</code>.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>When throwing exceptions using <code>Throw</code> or
|
||
|
<code>ThrowNew</code>, be aware that these functions
|
||
|
return regularly. You have to return control manually to the
|
||
|
JVM.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>Technically, the <code>JNIEnv</code> pointer is not
|
||
|
necessarily constant during the lifetime of your JNI module.
|
||
|
Storing it in a global variable is therefore incorrect.
|
||
|
Particularly if you are dealing with callbacks, you may have to
|
||
|
store the pointer in a thread-local variable (defined with
|
||
|
<code>__thread</code>). It is, however, best to avoid the
|
||
|
complexity of calling back into Java code.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>Keep in mind that C/C and Java are different languages,
|
||
|
despite very similar syntax for expressions. The Java memory
|
||
|
model is much more strict than the C or C memory models, and
|
||
|
native code needs more synchronization, usually using JVM
|
||
|
facilities or POSIX threads mutexes. Integer overflow in Java
|
||
|
is defined, but in C/C++ it is not (for the
|
||
|
<code>jint</code> and <code>jlong</code> types).</p>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="sect2">
|
||
|
<h3 id="sect-Defensive_Coding-Java-MiscUnsafe"><a class="anchor" href="#sect-Defensive_Coding-Java-MiscUnsafe"></a><code>sun.misc.Unsafe</code></h3>
|
||
|
<div class="paragraph">
|
||
|
<p>The <code>sun.misc.Unsafe</code> class is unportable and
|
||
|
contains many functions explicitly designed to break Java memory
|
||
|
safety (for performance and debugging). If possible, avoid
|
||
|
using this class.</p>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="sect1">
|
||
|
<h2 id="sect-Defensive_Coding-Java-SecurityManager"><a class="anchor" href="#sect-Defensive_Coding-Java-SecurityManager"></a>Interacting with the Security Manager</h2>
|
||
|
<div class="sectionbody">
|
||
|
<div class="paragraph">
|
||
|
<p>The Java platform is largely implemented in the Java language
|
||
|
itself. Therefore, within the same JVM, code runs which is part
|
||
|
of the Java installation and which is trusted, but there might
|
||
|
also be code which comes from untrusted sources and is restricted
|
||
|
by the Java sandbox (to varying degrees). The <strong>security
|
||
|
manager</strong> draws a line between fully trusted, partially
|
||
|
trusted and untrusted code.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>The type safety and accessibility checks provided by the Java
|
||
|
language and JVM would be sufficient to implement a sandbox.
|
||
|
However, only some Java APIs employ such a capabilities-based
|
||
|
approach. (The Java SE library contains many public classes with
|
||
|
public constructors which can break any security policy, such as
|
||
|
<code>java.io.FileOutputStream</code>.) Instead, critical
|
||
|
functionality is protected by <strong>stack
|
||
|
inspection</strong>: At a security check, the stack is walked
|
||
|
from top (most-nested) to bottom. The security check fails if a
|
||
|
stack frame for a method is encountered whose class lacks the
|
||
|
permission which the security check requires.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>This simple approach would not allow untrusted code (which lacks
|
||
|
certain permissions) to call into trusted code while the latter
|
||
|
retains trust. Such trust transitions are desirable because they
|
||
|
enable Java as an implementation language for most parts of the
|
||
|
Java platform, including security-relevant code. Therefore, there
|
||
|
is a mechanism to mark certain stack frames as trusted (<a href="#sect-Defensive_Coding-Java-SecurityManager-Privileged">Re-gaining Privileges</a>).</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>In theory, it is possible to run a Java virtual machine with a
|
||
|
security manager that acts very differently from this approach,
|
||
|
but a lot of code expects behavior very close to the platform
|
||
|
default (including many classes which are part of the OpenJDK
|
||
|
implementation).</p>
|
||
|
</div>
|
||
|
<div class="sect2">
|
||
|
<h3 id="sect-Defensive_Coding-Java-SecurityManager-Compatible"><a class="anchor" href="#sect-Defensive_Coding-Java-SecurityManager-Compatible"></a>Security Manager Compatibility</h3>
|
||
|
<div class="paragraph">
|
||
|
<p>A lot of code can run without any additional permissions at all,
|
||
|
with little changes. The following guidelines should help to
|
||
|
increase compatibility with a restrictive security manager.</p>
|
||
|
</div>
|
||
|
<div class="ulist">
|
||
|
<ul>
|
||
|
<li>
|
||
|
<p>When retrieving system properties using
|
||
|
<code>System.getProperty(String)</code> or similar
|
||
|
methods, catch <code>SecurityException</code>
|
||
|
exceptions and treat the property as unset.</p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p>Avoid unnecessary file system or network access.</p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p>Avoid explicit class loading. Access to a suitable class
|
||
|
loader might not be available when executing as untrusted
|
||
|
code.</p>
|
||
|
</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>If the functionality you are implementing absolutely requires
|
||
|
privileged access and this functionality has to be used from
|
||
|
untrusted code (hopefully in a restricted and secure manner),
|
||
|
see <a href="#sect-Defensive_Coding-Java-SecurityManager-Privileged">Re-gaining Privileges</a>.</p>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="sect2">
|
||
|
<h3 id="sect-Defensive_Coding-Java-SecurityManager-Activate"><a class="anchor" href="#sect-Defensive_Coding-Java-SecurityManager-Activate"></a>Activating the Security Manager</h3>
|
||
|
<div class="paragraph">
|
||
|
<p>The usual command to launch a Java application,
|
||
|
<code class="command">java</code>, does not activate the security manager.
|
||
|
Therefore, the virtual machine does not enforce any sandboxing
|
||
|
restrictions, even if explicitly requested by the code (for
|
||
|
example, as described in <a href="#sect-Defensive_Coding-Java-SecurityManager-Unprivileged">Reducing Trust in Code</a>).</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>The <code class="option">-Djava.security.manager</code> option activates
|
||
|
the security manager, with the fairly restrictive default
|
||
|
policy. With a very permissive policy, most Java code will run
|
||
|
unchanged. Assuming the policy in <a href="#ex-Defensive_Coding-Java-SecurityManager-GrantAll">Most permissve OpenJDK policy file</a>
|
||
|
has been saved in a file <code>grant-all.policy</code>,
|
||
|
this policy can be activated using the option
|
||
|
<code class="option">-Djava.security.policy=grant-all.policy</code> (in
|
||
|
addition to the <code class="option">-Djava.security.manager</code>
|
||
|
option).</p>
|
||
|
</div>
|
||
|
<div id="ex-Defensive_Coding-Java-SecurityManager-GrantAll" class="exampleblock">
|
||
|
<div class="title">Example 5. Most permissve OpenJDK policy file</div>
|
||
|
<div class="content">
|
||
|
<div class="listingblock">
|
||
|
<div class="content">
|
||
|
<pre class="CodeRay highlight"><code data-lang="java">grant {
|
||
|
permission java.security.AllPermission;
|
||
|
};</code></pre>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>With this most permissive policy, the security manager is still
|
||
|
active, and explicit requests to drop privileges will be
|
||
|
honored.</p>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="sect2">
|
||
|
<h3 id="sect-Defensive_Coding-Java-SecurityManager-Unprivileged"><a class="anchor" href="#sect-Defensive_Coding-Java-SecurityManager-Unprivileged"></a>Reducing Trust in Code</h3>
|
||
|
<div class="paragraph">
|
||
|
<p>The <a href="#ex-Defensive_Coding-Java-SecurityManager-Unprivileged">Using the security manager to run code with reduced privileges</a> example
|
||
|
shows how to run a piece code of with reduced privileges.</p>
|
||
|
</div>
|
||
|
<div id="ex-Defensive_Coding-Java-SecurityManager-Unprivileged" class="exampleblock">
|
||
|
<div class="title">Example 6. Using the security manager to run code with reduced privileges</div>
|
||
|
<div class="content">
|
||
|
<div class="listingblock">
|
||
|
<div class="content">
|
||
|
<pre class="CodeRay highlight"><code data-lang="java"><span style="color:#0a8;font-weight:bold">Permissions</span> permissions = <span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">Permissions</span>();
|
||
|
<span style="color:#0a8;font-weight:bold">ProtectionDomain</span> protectionDomain =
|
||
|
<span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">ProtectionDomain</span>(<span style="color:#069">null</span>, permissions);
|
||
|
<span style="color:#0a8;font-weight:bold">AccessControlContext</span> context = <span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">AccessControlContext</span>(
|
||
|
<span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">ProtectionDomain</span><span style="color:#339;font-weight:bold">[]</span> { protectionDomain });
|
||
|
|
||
|
<span style="color:#777">// This is expected to succeed.</span>
|
||
|
<span style="color:#080;font-weight:bold">try</span> (<span style="color:#0a8;font-weight:bold">FileInputStream</span> in = <span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">FileInputStream</span>(path)) {
|
||
|
<span style="color:#0a8;font-weight:bold">System</span>.out.format(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">FileInputStream: %s%n</span><span style="color:#710">"</span></span>, in);
|
||
|
}
|
||
|
|
||
|
<span style="color:#0a8;font-weight:bold">AccessController</span>.doPrivileged(<span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">PrivilegedExceptionAction</span><<span style="color:#0a8;font-weight:bold">Void</span>>() {
|
||
|
<span style="color:#007">@Override</span>
|
||
|
<span style="color:#088;font-weight:bold">public</span> <span style="color:#0a8;font-weight:bold">Void</span> run() <span style="color:#088;font-weight:bold">throws</span> <span style="color:#C00;font-weight:bold">Exception</span> {
|
||
|
<span style="color:#777">// This code runs with reduced privileges and is</span>
|
||
|
<span style="color:#777">// expected to fail.</span>
|
||
|
<span style="color:#080;font-weight:bold">try</span> (<span style="color:#0a8;font-weight:bold">FileInputStream</span> in = <span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">FileInputStream</span>(path)) {
|
||
|
<span style="color:#0a8;font-weight:bold">System</span>.out.format(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">FileInputStream: %s%n</span><span style="color:#710">"</span></span>, in);
|
||
|
}
|
||
|
<span style="color:#080;font-weight:bold">return</span> <span style="color:#069">null</span>;
|
||
|
}
|
||
|
}, context);</code></pre>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>The example above does not add any additional permissions to the
|
||
|
<code>permissions</code> object. If such permissions are
|
||
|
necessary, code like the following (which grants read permission
|
||
|
on all files in the current directory) can be used:</p>
|
||
|
</div>
|
||
|
<div class="listingblock">
|
||
|
<div class="content">
|
||
|
<pre class="CodeRay highlight"><code data-lang="java">permissions.add(<span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">FilePermission</span>(
|
||
|
<span style="color:#0a8;font-weight:bold">System</span>.getProperty(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">user.dir</span><span style="color:#710">"</span></span>) + <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">/-</span><span style="color:#710">"</span></span>, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">read</span><span style="color:#710">"</span></span>));</code></pre>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="admonitionblock important">
|
||
|
<table>
|
||
|
<tr>
|
||
|
<td class="icon">
|
||
|
<i class="fa icon-important" title="Important"></i>
|
||
|
</td>
|
||
|
<td class="content">
|
||
|
<div class="paragraph">
|
||
|
<p>Calls to the
|
||
|
<code>java.security.AccessController.doPrivileged()</code>
|
||
|
methods do not enforce any additional restriction if no
|
||
|
security manager has been set. Except for a few special
|
||
|
exceptions, the restrictions no longer apply if the
|
||
|
<code>doPrivileged()</code> has returned, even to
|
||
|
objects created by the code which ran with reduced privileges.
|
||
|
(This applies to object finalization in particular.)</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>The example code above does not prevent the called code from
|
||
|
calling the
|
||
|
<code>java.security.AccessController.doPrivileged()</code>
|
||
|
methods. This mechanism should be considered an additional
|
||
|
safety net, but it still can be used to prevent unexpected
|
||
|
behavior of trusted code. As long as the executed code is not
|
||
|
dynamic and came with the original application or library, the
|
||
|
sandbox is fairly effective.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>The <code>context</code> argument in <a href="#ex-Defensive_Coding-Java-SecurityManager-Unprivileged">Using the security manager to run code with reduced privileges</a>
|
||
|
is extremely important—otherwise, this code would increase
|
||
|
privileges instead of reducing them.</p>
|
||
|
</div>
|
||
|
</td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>For activating the security manager, see <a href="#sect-Defensive_Coding-Java-SecurityManager-Activate">Activating the Security Manager</a>.
|
||
|
Unfortunately, this affects the virtual machine as a whole, so
|
||
|
it is not possible to do this from a library.</p>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="sect2">
|
||
|
<h3 id="sect-Defensive_Coding-Java-SecurityManager-Privileged"><a class="anchor" href="#sect-Defensive_Coding-Java-SecurityManager-Privileged"></a>Re-gaining Privileges</h3>
|
||
|
<div class="paragraph">
|
||
|
<p>Ordinarily, when trusted code is called from untrusted code, it
|
||
|
loses its privileges (because of the untrusted stack frames
|
||
|
visible to stack inspection). The
|
||
|
<code>java.security.AccessController.doPrivileged()</code>
|
||
|
family of methods provides a controlled backdoor from untrusted
|
||
|
to trusted code.</p>
|
||
|
</div>
|
||
|
<div class="admonitionblock important">
|
||
|
<table>
|
||
|
<tr>
|
||
|
<td class="icon">
|
||
|
<i class="fa icon-important" title="Important"></i>
|
||
|
</td>
|
||
|
<td class="content">
|
||
|
<div class="paragraph">
|
||
|
<p>By design, this feature can undermine the Java security model
|
||
|
and the sandbox. It has to be used very carefully. Most
|
||
|
sandbox vulnerabilities can be traced back to its misuse.</p>
|
||
|
</div>
|
||
|
</td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>In essence, the <code>doPrivileged()</code> methods
|
||
|
cause the stack inspection to end at their call site. Untrusted
|
||
|
code further down the call stack becomes invisible to security
|
||
|
checks.</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>The following operations are common and safe to perform with
|
||
|
elevated privileges.</p>
|
||
|
</div>
|
||
|
<div class="ulist">
|
||
|
<ul>
|
||
|
<li>
|
||
|
<p>Reading custom system properties with fixed names,
|
||
|
especially if the value is not propagated to untrusted code.
|
||
|
(File system paths including installation paths, host names
|
||
|
and user names are sometimes considered private information
|
||
|
and need to be protected.)</p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p>Reading from the file system at fixed paths, either
|
||
|
determined at compile time or by a system property. Again,
|
||
|
leaking the file contents to the caller can be problematic.</p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p>Accessing network resources under a fixed address, name or
|
||
|
URL, derived from a system property or configuration file,
|
||
|
information leaks not withstanding.</p>
|
||
|
</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>The <a href="#ex-Defensive_Coding-Java-SecurityManager-Privileged">Using the security manager to run code with increased privileges</a> example
|
||
|
shows how to request additional privileges.</p>
|
||
|
</div>
|
||
|
<div id="ex-Defensive_Coding-Java-SecurityManager-Privileged" class="exampleblock">
|
||
|
<div class="title">Example 7. Using the security manager to run code with increased privileges</div>
|
||
|
<div class="content">
|
||
|
<div class="listingblock">
|
||
|
<div class="content">
|
||
|
<pre class="CodeRay highlight"><code data-lang="java"><span style="color:#777">// This is expected to fail.</span>
|
||
|
<span style="color:#080;font-weight:bold">try</span> {
|
||
|
<span style="color:#0a8;font-weight:bold">System</span>.out.println(<span style="color:#0a8;font-weight:bold">System</span>.getProperty(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">user.home</span><span style="color:#710">"</span></span>));
|
||
|
} <span style="color:#080;font-weight:bold">catch</span> (<span style="color:#C00;font-weight:bold">SecurityException</span> e) {
|
||
|
e.printStackTrace(<span style="color:#0a8;font-weight:bold">System</span>.err);
|
||
|
}
|
||
|
<span style="color:#0a8;font-weight:bold">AccessController</span>.doPrivileged(<span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">PrivilegedAction</span><<span style="color:#0a8;font-weight:bold">Void</span>>() {
|
||
|
<span style="color:#088;font-weight:bold">public</span> <span style="color:#0a8;font-weight:bold">Void</span> run() {
|
||
|
<span style="color:#777">// This should work.</span>
|
||
|
<span style="color:#0a8;font-weight:bold">System</span>.out.println(<span style="color:#0a8;font-weight:bold">System</span>.getProperty(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">user.home</span><span style="color:#710">"</span></span>));
|
||
|
<span style="color:#080;font-weight:bold">return</span> <span style="color:#069">null</span>;
|
||
|
}
|
||
|
});</code></pre>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>Obviously, this only works if the class containing the call to
|
||
|
<code>doPrivileged()</code> is marked trusted (usually
|
||
|
because it is loaded from a trusted class loader).</p>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>When writing code that runs with elevated privileges, make sure
|
||
|
that you follow the rules below.</p>
|
||
|
</div>
|
||
|
<div class="ulist">
|
||
|
<ul>
|
||
|
<li>
|
||
|
<p>Make the privileged code as small as possible. Perform as
|
||
|
many computations as possible before and after the
|
||
|
privileged code section, even if it means that you have to
|
||
|
define a new class to pass the data around.</p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p>Make sure that you either control the inputs to the
|
||
|
privileged code, or that the inputs are harmless and cannot
|
||
|
affect security properties of the privileged code.</p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p>Data that is returned from or written by the privileged code
|
||
|
must either be restricted (that is, it cannot be accessed by
|
||
|
untrusted code), or must be harmless. Otherwise, privacy
|
||
|
leaks or information disclosures which affect security
|
||
|
properties can be the result.</p>
|
||
|
</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
<div class="paragraph">
|
||
|
<p>If the code calls back into untrusted code at a later stage (or
|
||
|
performs other actions under control from the untrusted caller),
|
||
|
you must obtain the original security context and restore it
|
||
|
before performing the callback, as in <a href="#ex-Defensive_Coding-Java-SecurityManager-Callback">Restoring privileges when invoking callbacks</a>.
|
||
|
(In this example, it would be much better to move the callback
|
||
|
invocation out of the privileged code section, of course.)</p>
|
||
|
</div>
|
||
|
<div id="ex-Defensive_Coding-Java-SecurityManager-Callback" class="exampleblock">
|
||
|
<div class="title">Example 8. Restoring privileges when invoking callbacks</div>
|
||
|
<div class="content">
|
||
|
<div class="listingblock">
|
||
|
<div class="content">
|
||
|
<pre class="CodeRay highlight"><code data-lang="java"><span style="color:#339;font-weight:bold">interface</span> <span style="color:#B06;font-weight:bold">Callback</span><T> {
|
||
|
T call(<span style="color:#339;font-weight:bold">boolean</span> flag);
|
||
|
}
|
||
|
|
||
|
<span style="color:#339;font-weight:bold">class</span> <span style="color:#B06;font-weight:bold">CallbackInvoker</span><T> {
|
||
|
<span style="color:#088;font-weight:bold">private</span> <span style="color:#088;font-weight:bold">final</span> <span style="color:#0a8;font-weight:bold">AccessControlContext</span> context;
|
||
|
<span style="color:#0a8;font-weight:bold">Callback</span><T> callback;
|
||
|
|
||
|
CallbackInvoker(<span style="color:#0a8;font-weight:bold">Callback</span><T> callback) {
|
||
|
context = <span style="color:#0a8;font-weight:bold">AccessController</span>.getContext();
|
||
|
<span style="color:#950">this</span>.callback = callback;
|
||
|
}
|
||
|
|
||
|
<span style="color:#088;font-weight:bold">public</span> T invoke() {
|
||
|
<span style="color:#777">// Obtain increased privileges.</span>
|
||
|
<span style="color:#080;font-weight:bold">return</span> <span style="color:#0a8;font-weight:bold">AccessController</span>.doPrivileged(<span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">PrivilegedAction</span><T>() {
|
||
|
<span style="color:#007">@Override</span>
|
||
|
<span style="color:#088;font-weight:bold">public</span> T run() {
|
||
|
<span style="color:#777">// This operation would fail without</span>
|
||
|
<span style="color:#777">// additional privileges.</span>
|
||
|
<span style="color:#088;font-weight:bold">final</span> <span style="color:#339;font-weight:bold">boolean</span> flag = <span style="color:#0a8;font-weight:bold">Boolean</span>.getBoolean(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">"</span><span style="color:#D20">some.property</span><span style="color:#710">"</span></span>);
|
||
|
|
||
|
<span style="color:#777">// Restore the original privileges.</span>
|
||
|
<span style="color:#080;font-weight:bold">return</span> <span style="color:#0a8;font-weight:bold">AccessController</span>.doPrivileged(
|
||
|
<span style="color:#080;font-weight:bold">new</span> <span style="color:#0a8;font-weight:bold">PrivilegedAction</span><T>() {
|
||
|
<span style="color:#007">@Override</span>
|
||
|
<span style="color:#088;font-weight:bold">public</span> T run() {
|
||
|
<span style="color:#080;font-weight:bold">return</span> callback.call(flag);
|
||
|
}
|
||
|
}, context);
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
}</code></pre>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div id="bottom" class="text-muted py-3" >
|
||
|
<div class="foot">
|
||
|
<div class="container">
|
||
|
<div class="row footerlinks">
|
||
|
<div class="col-sm-3 col-xs-6 widget">
|
||
|
<h3 class="widget-title">About</h3>
|
||
|
<div class="widget-body">
|
||
|
<dl>
|
||
|
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
|
||
|
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
|
||
|
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
|
||
|
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
|
||
|
</dl>
|
||
|
<ul class="list-inline">
|
||
|
<li>
|
||
|
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
|
||
|
</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<div class="col-sm-3 col-xs-6 widget">
|
||
|
<h3 class="widget-title uppercase">Download</h3>
|
||
|
<div class="widget-body">
|
||
|
<dl>
|
||
|
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
|
||
|
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
|
||
|
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
|
||
|
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
|
||
|
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
|
||
|
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">®</span></a></dd>
|
||
|
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
|
||
|
|
||
|
</dl>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<div class="col-sm-3 col-xs-6 widget">
|
||
|
<h3 class="widget-title">Support</h3>
|
||
|
<div class="widget-body">
|
||
|
<dl>
|
||
|
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
|
||
|
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
|
||
|
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
|
||
|
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
|
||
|
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
|
||
|
</dl>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<div class="col-sm-3 col-xs-6 widget">
|
||
|
<h3 class="widget-title">Join</h3>
|
||
|
<div class="widget-body">
|
||
|
<dl>
|
||
|
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
|
||
|
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
|
||
|
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
|
||
|
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
|
||
|
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
|
||
|
</dl>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div> <!-- /row of widgets -->
|
||
|
|
||
|
<div class="row">
|
||
|
<div class="col-md-2">
|
||
|
<div class="widget-body">
|
||
|
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="col-md-7">
|
||
|
<div class="widget-body">
|
||
|
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
|
||
|
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora »</a></p>
|
||
|
<p class="copy">© 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div> <!-- /row of widgets -->
|
||
|
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
|
||
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
|
||
|
<!-- Latest compiled and minified JavaScript -->
|
||
|
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
|
||
|
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
|
||
|
<script type="text/javascript">
|
||
|
/*<![CDATA[*/
|
||
|
$(document).ready(function() {
|
||
|
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
|
||
|
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
|
||
|
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
|
||
|
}
|
||
|
});
|
||
|
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
|
||
|
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
|
||
|
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
|
||
|
}
|
||
|
});
|
||
|
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
|
||
|
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
|
||
|
});
|
||
|
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
|
||
|
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
|
||
|
});
|
||
|
});
|
||
|
/*]]>*/
|
||
|
</script>
|
||
|
</body>
|
||
|
</html>
|