Versions Compared

Key

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

APIS should have security options enabled by default– for example, having best practice cipher suites enabled by default (something that changes over time) while disabling out-of-favor cipher suites by default. When interface stability is also a design requirement, an interface can meet both goals by providing off-by-default options that produce stable behavior, such as TLS_ENABLE_Y2015_BEST_PRACTICE_CIPHERS_ONLY.

Noncompliant Code Example

If the caller of this API in this noncompliant example doesn't understand what the options mean, they will pass 0 or TLS_DEFAULT_OPTIONS and get a connection vulnerable to man-in-the-middle attacks and using old versions of TLS.

Strings (both character and wide-character) are often subject to buffer overflows, which will overwrite the memory immediately past the string. Many rules warn against buffer overflows, including STR31-C. Guarantee that storage for strings has sufficient space for character data and the null terminator and VOID STR35-C. Do not copy data from an unbounded source to a fixed-length array. Sometimes the danger of buffer overflows can be minimized by ensuring that arranging memory such that data that might be corrupted by a buffer overflow is not sensitive.

Noncompliant Code Example

This noncompliant code example stores a set of strings using a linked list:

Code Block
bgColor#ffcccc
langc
constint size_t String_Size = 20;
struct node_s {
  char name[String_Size];
  struct node_s* next;
}

A buffer overflow on name would overwrite the next pointer, which could then be used to read or write to arbitrary memory.

Compliant Solution

This compliant solution creates a linked list of strings but stores the next pointer before the string:

Code Block
bgColor#ccccff
langc
const size_t String_Size = 20;
struct node_s {
  struct node_s* next;
  char name[String_Size];
}

If buffer overflow occurs on name, the next pointer remains uncorrupted.

Compliant Solution

tls_connect_by_name(const char *host, int port, int option_bitmask);
#define TLS_DEFAULT_OPTIONS 0
#define TLS_VALIDATE_HOST 0x0001
#define TLS_DISABLE_V1_0 0x0002
#define TLS_DISABLE_V1_1 0x0004

Compliant Solution

If the caller of this API doesn't understand the options and passes 0 or TLS_DEFAULT_OPTIONS they will get certificate validation with only the current version of TLS enabledIn this compliant solution, the linked list stores pointers to strings that are stored elsewhere. Storing the strings elsewhere protects the next pointer from buffer overflows on the strings.

Code Block
bgColor#ccccff
langc
constint sizetls_t String_Size = 20;
struct node_s {
  struct node_s* next;
  char* name;
}

Exceptions

API01-EX1: Using a string before sensitive data such as pointers is permitted when it is not practical to segregate the strings from the sensitive data.

Each of the following code examples creates a linked list of strings, but each node is actually stored inside an array. This practice ensures that the string is always in front of a next pointer regardless of how they are ordered in the struct.

Code Block
bgColor#ccccff
langc
const size_t String_Size = 20;
struct node_s {
  char name[String_Size];
  struct node_s* next;
}
struct node_s list[10];
Code Block
bgColor#ccccff
langc
const size_t String_Size = 20;
struct node_s {
  struct node_s* next;
  char name[String_Size];
}
struct node_s list[10];

 

connect_by_name(const char *host, int port, int option_bitmask);
#define TLS_DEFAULT_OPTIONS 0
#define TLS_DISABLE_HOST_VALIDATION 0x0001  // use rarely, subject to man-in-the-middle attack
#define TLS_ENABLE_V1_0 0x0002
#define TLS_ENABLE_V1_1 0x0004

 

 

...

Image Added Image Added Image Added

 Image Removed Image Removed Image Removed