Skip to content

Commit 9495c5e

Browse files
Java: Add tests
1 parent 0902807 commit 9495c5e

10 files changed

+107
-12
lines changed
Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
public void processData(Socket sock) {
2-
InputStream iStream = sock.getInputStream();
3-
ObjectInpuStream oiStream = new ObjectInputStream(iStream);
2+
ObjectInputStream stream = new ObjectInputStream(sock.getInputStream());
43

5-
int size = oiStream.readInt();
4+
int size = stream.readInt();
65
// BAD: A user-controlled amount of memory is alocated
76
byte[] buffer = new byte[size];
87

9-
oiStream.readFully(buffer);
8+
// ...
109
}

java/ql/src/Security/CWE/CWE-789/UnboundedAllocationDeserializationBad.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ private void readObject(java.io.ObjectInputStream in) throws IOException, ClassN
1616
data = new Object[length];
1717

1818
for (int i = 0; i < length; i++) {
19-
data[i] = in.readObject()
19+
data[i] = in.readObject();
2020
}
2121
}
2222
}
Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
public void processData(Socket sock) {
2-
InputStream iStream = sock.getInputStream();
3-
ObjectInpuStream oiStream = new ObjectInputStream(iStream);
2+
ObjectInputStream stream = new ObjectInputStream(sock.getInputStream());
43

5-
int size = oiStream.readInt();
4+
int size = stream.readInt();
65

76
if (size > 4096) {
8-
throw new IllegalArgumentException("Size too large");
7+
throw new IOException("Size too large");
98
}
109

1110
// GOOD: There is an upper bound on memory consumption.
1211
byte[] buffer = new byte[size];
1312

14-
oiStream.readFully(buffer);
13+
// ...
1514
}

java/ql/src/Security/CWE/CWE-789/UnbounedAllocationDeserializationGood.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ private void writeObject(java.io.ObjectOutputStream out) throws IOException {
55
out.writeInt(data.length);
66

77
for (int i = 0; i < data.length; i++) {
8-
out.writeLong(data[i]);
8+
out.writeObject(data[i]);
99
}
1010
}
1111

java/ql/src/Security/CWE/CWE-789/UndoundedAllocationDeserialization.qhelp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ The following example allocates an array of a size provided by the input stream,
2929
<sample src="UnboundedAllocationDeserializationBad.java" />
3030

3131
<p>
32-
The following example uses an <code>ArrayList</code> to only allocate as much memory as needed, within a constanat factor:
32+
The following example uses an <code>ArrayList</code> to only allocate as much memory as needed, within a constant factor:
3333
</p>
3434

3535
<sample src="UnboundedAllocationDeserializationGood.java" />
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import java.io.*;
2+
import java.lang.ClassNotFoundException;
3+
import java.net.Socket;
4+
import java.util.ArrayList;
5+
6+
class Test {
7+
8+
class A implements Serializable{
9+
transient Object[] data;
10+
11+
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
12+
out.writeInt(data.length);
13+
14+
for (int i = 0; i < data.length; i++) {
15+
out.writeObject(data[i]);
16+
}
17+
}
18+
19+
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
20+
int length = in.readInt();
21+
22+
// BAD: An array is allocated whose size could be controlled by an attacker.
23+
data = new Object[length];
24+
25+
for (int i = 0; i < length; i++) {
26+
data[i] = in.readObject();
27+
}
28+
}
29+
}
30+
31+
class B implements Serializable{
32+
transient Object[] data;
33+
34+
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
35+
out.writeInt(data.length);
36+
37+
for (int i = 0; i < data.length; i++) {
38+
out.writeObject(data[i]);
39+
}
40+
}
41+
42+
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
43+
int length = in.readInt();
44+
45+
// GOOD: An ArrayList is used, which dynamically allocates memory as needed.
46+
ArrayList<Object> dataList = new ArrayList<Object>();
47+
48+
for (int i = 0; i < length; i++) {
49+
dataList.add(in.readObject());
50+
}
51+
52+
data = dataList.toArray();
53+
}
54+
}
55+
56+
57+
public void processData1(Socket sock) throws IOException {
58+
ObjectInputStream stream = new ObjectInputStream(sock.getInputStream());
59+
60+
int size = stream.readInt();
61+
// BAD: A user-controlled amount of memory is alocated
62+
byte[] buffer = new byte[size];
63+
64+
// ...
65+
}
66+
67+
public void processData2(Socket sock) throws IOException {
68+
ObjectInputStream stream = new ObjectInputStream(sock.getInputStream());
69+
70+
int size = stream.readInt();
71+
72+
if (size > 4096) {
73+
throw new IOException("Size too large");
74+
}
75+
76+
// GOOD: There is an upper bound on memory consumption.
77+
byte[] buffer = new byte[size];
78+
79+
// ...
80+
}
81+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
edges
2+
| Test.java:58:58:58:78 | getInputStream(...) : InputStream | Test.java:62:34:62:37 | size |
3+
nodes
4+
| Test.java:58:58:58:78 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
5+
| Test.java:62:34:62:37 | size | semmle.label | size |
6+
#select
7+
| Test.java:62:34:62:37 | size | Test.java:58:58:58:78 | getInputStream(...) : InputStream | Test.java:62:34:62:37 | size | Unbounded memory allocation |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Security/CWE/CWE-789/UnboundedAllocation.ql
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
edges
2+
| Test.java:19:33:19:60 | in : ObjectInputStream | Test.java:23:31:23:36 | length |
3+
nodes
4+
| Test.java:19:33:19:60 | in : ObjectInputStream | semmle.label | in : ObjectInputStream |
5+
| Test.java:23:31:23:36 | length | semmle.label | length |
6+
#select
7+
| Test.java:23:31:23:36 | length | Test.java:19:33:19:60 | in : ObjectInputStream | Test.java:23:31:23:36 | length | Unbounded memory allocation from deserialization |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Security/CWE/CWE-789/UnboundedAllocationDeserialization.ql

0 commit comments

Comments
 (0)