Baseline for Ed 2 of tr 24772


Programming Language Vulnerabilities



Yüklə 0,54 Mb.
səhifə6/54
tarix16.08.2018
ölçüsü0,54 Mb.
#63136
1   2   3   4   5   6   7   8   9   ...   54

6. Programming Language Vulnerabilities

6.1 General


This clause provides language-independent descriptions of vulnerabilities in programming languages that can lead to application vulnerabilities. Each description provides:

  • a summary of the vulnerability,

  • characteristics of languages where the vulnerability may be found,

  • typical mechanisms of failure,

  • techniques that programmers can use to avoid the vulnerability, and

  • ways that language designers can modify language specifications in the future to help programmers mitigate the vulnerability.

Descriptions of how vulnerabilities are manifested in particular programming languages are provided in annexes of this Technical Report. In each case, the behaviour of the language is assumed to be as specified by the standard cited in the annex. Clearly, programs could have different vulnerabilities in a non-standard implementation. Examples of non-standard implementations include:

  • compilers written to implement some specification other than the standard,

  • use of non-standard vendor extensions to the language, and

  • use of compiler switches providing alternative semantics.

The following descriptions are written in a language-independent manner except when specific languages are used in examples. The annexes may be consulted for language specific descriptions.

This clause will, in general, use the terminology that is most natural to the description of each individual vulnerability. Hence terminology may differ from description to description.

6.2 Type System [IHN]

6.2.1 Description of application vulnerability


When data values are converted from one data type to another, even when done intentionally, unexpected results can occur.

6.2.2 Cross reference


JSF AV Rules: 148 and 183
MISRA C 2012: 4.6, 10.1, 10.3, and 10.4

MISRA C++ 2008: 3-9-2, 5-0-3 to 5-0-14

CERT C guidelines: DCL07-C, DCL11-C, DCL35-C, EXP05-C and EXP32-C

Ada Quality and Style Guide: 3.4


6.2.3 Mechanism of failure


The type of a data object informs the compiler how values should be represented and which operations may be applied. The type system of a language is the set of rules used by the language to structure and organize its collection of types. Any attempt to manipulate data objects with inappropriate operations is a type error. A program is said to be type safe (or type secure) if it can be demonstrated that it has no type errors [27].

Every programming language has some sort of type system. A language is statically typed if the type of every expression is known at compile time. The type system is said to be strong if it guarantees type safety and weak if it does not. There are strongly typed languages that are not statically typed because they enforce type safety with runtime checks [27].

In practical terms, nearly every language falls short of being strongly typed (in an ideal sense) because of the inclusion of mechanisms to bypass type safety in particular circumstances. For that reason and because every language has a different type system, this description will focus on taking advantage of whatever features for type safety may be available in the chosen language.

Sometimes it is appropriate for a data value to be converted from one type to another compatible one. For example, consider the following program fragment, written in no specific language:

float a;
integer i;
a := a + i;

The variable "i" is of integer type. It is converted to the float type before it is added to the data value. This is an implicit type conversion. If, on the other hand, the conversion must be specified by the program, for example, "a := a + float(i)", then it is an explicit type conversion.

Type equivalence is the strictest form of type compatibility; two types are equivalent if they are compatible without using implicit or explicit conversion. Type equivalence is usually characterized in terms of name type equivalence—two variables have the same type if they are declared in the same declaration or declarations that use the same type name—or structure type equivalence—two variables have the same type if they have identical structures. There are variations of these approaches and most languages use different combinations of them [28]. Therefore, a programmer skilled in one language may very well code inadvertent type errors when using a different language.

It is desirable for a program to be type safe because the application of operations to operands of an inappropriate type may produce unexpected results. In addition, the presence of type errors can reduce the effectiveness of static analysis for other problems. Searching for type errors is a valuable exercise because their presence often reveals design errors as well as coding errors. Many languages check for type errors—some at compile-time, others at run-time. Obviously, compile-time checking is more valuable because it can catch errors that are not executed by a particular set of test cases.

Making the most use of the type system of a language is useful in two ways. First, data conversions always bear the risk of changing the value. For example, a conversion from integer to float risks the loss of significant digits while the inverse conversion risks the loss of any fractional value. Conversion of an integer value from a type with a longer representation to a type with a shorter representation risks the loss of significant digits. This can produce particularly puzzling results if the value is used to index an array. Conversion of a floating-point value from a type with a longer representation to a type with a shorter representation risks the loss of precision. This can be particularly severe in computations where the number of calculations increases as a power of the problem size. (It should be noted that similar surprises can occur when an application is retargeted to a machine with different representations of numeric values.)

Second, a programmer can use the type system to increase the probability of catching design errors or coding blunders. For example, the following Ada fragment declares two distinct floating-point types:

type Celsius is new Float;
type Fahrenheit is new Float;

The declaration makes it impossible to add a value of type Celsius to a value of type Fahrenheit without explicit conversion.


6.2.4 Applicable language characteristics


This vulnerability is intended to be applicable to languages with the following characteristics:

  • Languages that support multiple types and allow conversions between types.

6.2.5 Avoiding the vulnerability or mitigating its effects


Software developers can avoid the vulnerability or mitigate its ill effects in the following ways:

  • Take advantage of any facility offered by the programming language to declare distinct types and use any mechanism provided by the language processor and related tools to check for or enforce type compatibility.

  • Use available language and tools facilities to preclude or detect the occurrence of implicit type conversions, such as those in mixed type arithmetic. If it is not possible, use human review to assist in searching for implicit conversions.

  • Avoid explicit type conversion of data values except when there is no alternative. Document such occurrences so that the justification is made available to maintainers.

  • Use the most restricted data type that suffices to accomplish the job. For example, use an enumeration type to select from a limited set of choices (such as, a switch statement or the discriminant of a union type) rather than a more general type, such as integer. This will make it possible for tooling to check if all possible choices have been covered.

  • Treat every compiler, tool, or run-time diagnostic concerning type compatibility as a serious issue. Do not resolve the problem by modifying the code to include an explicit conversion, without further analysis; instead examine the underlying design to determine if the type error is a symptom of a deeper problem.

  • Never ignore instances of implicit type conversion; if the conversion is necessary, change it to an explicit conversion and document the rationale for use by maintainers.

  • Analyze the problem to be solved to learn the magnitudes and/or the precisions of the quantities needed as auxiliary variables, partial results and final results.

6.2.6 Implications for standardization


In future standardization activities, the following items should be considered:

    • Language specifiers should standardize on a common, uniform terminology to describe their type systems so that programmers experienced in other languages can reliably learn the type system of a language that is new to them.

    • Provide a mechanism for selecting data types with sufficient capability for the problem at hand.

    • Provide a way for the computation to determine the limits of the data types actually selected.

    • Language implementers should consider providing compiler switches or other tools to provide the highest possible degree of checking for type errors.

Yüklə 0,54 Mb.

Dostları ilə paylaş:
1   2   3   4   5   6   7   8   9   ...   54




Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©www.genderi.org 2024
rəhbərliyinə müraciət

    Ana səhifə