You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

Increasingly, programmers view string data as a portable means of storing and communicating data, including numeric values.  A real world example involved storing 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 may not be representable in any particular character encoding, because not all bit patterns represent valid characters.  Consequently, programmers must never convert directly from a binary numeric value to a string.

Noncompliant Code Example

This noncompliant code example attempts to convert the byte array representing a BigInteger into a String and then restore it again. 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.  Because some of the bytes do not denote valid characters, the resulting String representation loses information. Converting the String back to a BigInteger produces a different value.

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 reversed on input. Because the textual representation in the String object was generated by the BigInteger class, it contains valid characters.

BigInteger x = new BigInteger("530500452766");
String s = x.toString();  // valid character data
try {
  byte[] byteArray = s.getBytes("UTF8");
  // ns prints as "530500452766"
  String ns = new String(byteArray, "UTF8");  
  // 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

Attempting 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

STR05-J

low

unlikely

medium

P2

L3

Related Guidelines

MITRE CWE

CWE-838. Inappropriate Encoding for Output Context

Bibliography

 

  • No labels