Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Increasingly, programmers view string data strings as a portable means of storing and communicating arbitrary data, including such as numeric values.   A real world example involved storing For example, a real-world system stores the binary values of encrypted passwords as strings in a database. While inefficient, it is generally feasible to convert numeric values to strings and then reverse the process.  However, the binary value Noncharacter data may not be representable in any particular character encodingas a string, because not all bit patterns represent valid characters in most character sets.   Consequently, programmers must never convert directly from a binary numeric value not convert noncharacter data to a string. 

Noncompliant Code Example

This noncompliant code example attempts to convert

...

a BigInteger

...

value to a String and then restore it

...

to a BigInteger value. The toByteArray() method used returns a byte array containing the two's-complement representation of this BigInteger. The byte array is in big-endian byte

...

order: the most significant byte is in the zeroth element.

...

The program uses the String(byte[] bytes) constructor to create the string from the byte array. The behavior of this constructor when the given bytes are not valid in the default character set is unspecified, which is likely to be the case. Specifying the character set as a string also has unspecified behavior, although the Java API [API 2014] document claims that the String(byte[], Charset) method always replaces malformed-input and unmappable-character sequences with this character set's default replacement string. In any case, converting the String back to a BigInteger

...

is unlikely to reproduce the original value. 

Code Block
bgColor#FFcccc
BigInteger x = new BigInteger("530500452766");
// convert x to a String
byte[] byteArray = x.toByteArray();
String s = new String(byteArray);
// convert s back to a BigInteger
byteArray = s.getBytes();
x = new BigInteger(byteArray);

When this program was run on a Linux platform where the default character encoding is US-ASCII, the string s got the value {?J??, because some of the characters were unprintable. When converted back to a BigInteger, x got the value 149830058370101340468658109.

Compliant Solution

This compliant solution first produces a String representation of the BigInteger object and then converts the String object to a byte array. This process is then reversed on input. Because the textual representation in the String object was is generated by the BigInteger class, it contains valid characterscharacter data in the default character set.

Code Block
bgColor#ccccff
BigInteger x = new BigInteger("530500452766");
String s = x.toString();  // validValid character data
try {
  byte[] byteArray = s.getBytes("UTF8");
  // ns prints as "530500452766"
  String ns = new String(byteArray, "UTF8");  
x = // construct the original BigInteger
  BigInteger x1 = new BigInteger(ns); 
} catch (UnsupportedEncodingException ex) {
  // handle error
}

Do not try to convert the String object to a byte array to obtain the original BigInteger. Character encoded data may yield a byte array that, when converted to a BigInteger, results in a completely different value.

 

Risk Assessment

new BigInteger(ns); 

Compliant Solution (Base64)

Although Java does not provide a character set that guarantees lossless encoding of byte data, many other solutions exist for safely converting an arbitrary byte array into a string and back. Java 8 introduced the java.util.Base64 class, which provides encoders and decoders for the Base64 encoding scheme. This compliant solution uses Base64 to safely convert a number to a string and back without corrupting the data:

Code Block
bgColor#ccccff
languagejava
BigInteger x = new BigInteger("530500452766");
byte[] byteArray = x.toByteArray();
String s = Base64.getEncoder().encodeToString(byteArray);
byteArray = Base64.getDecoder().decode(s);
x = new BigInteger(byteArray);

Risk Assessment

Encoding noncharacter data as a string is likely to result in a loss of data integrityAttempting to read a byte array containing binary data as if it were character data can produce erroneous results.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

STR05STR03-J

lowLow

unlikelyUnlikely

mediumMedium

P2

L3

Related Guidelines

MITRE CWE

CWE-838. , Inappropriate Encoding for Output Context

Bibliography

 

...

Image Modified Image Modified Image Modified