Nothing Special   »   [go: up one dir, main page]

Asterisx Limpio Results - Fortify Security Report

Download as pdf or txt
Download as pdf or txt
You are on page 1of 46

prueba1

Jan 30, 2023


XiamLuquez
prueba1

Executive Summary
Issues Overview
On Jul 5, 2018, a source code review was performed over the analisis_id code base. 1,169 files, 86,844 LOC (Executable) were
scanned and reviewed for defects that could lead to potential security vulnerabilities. A total of 2802 reviewed findings were
uncovered during the analysis.

Issues by Fortify Priority Order


High 1028
Low 902
Critical 872

Recommendations and Conclusions


The Issues Category section provides Fortify recommendations for addressing issues at a generic level. The recommendations for
specific fixes can be extrapolated from those generic recommendations by the development group.

Copyright 2021 Micro Focus or one of its affiliates. Page 2 of 46


prueba1

Project Summary
Code Base Summary
Code location: /usr/src/asterisk-15.4.1/pjproject
Number of Files: 1169
Lines of Code: 86844
Build Label: <No Build Label>

Scan Information
Scan time: 23:07
SCA Engine version: 6.21.0005
Machine Name: jhairofc-pc
Username running scan: root

Results Certification
Results Certification Valid

Details:

Results Signature:

SCA Analysis Results has Valid signature

Rules Signature:

There were no custom rules used in this scan

Attack Surface
Attack Surface:
Private Information:
null.null.null

System Information:
null.null.gethostname
null.null.strerror
null.null.strerror_r
null.null.uname

Filter Set Summary


Current Enabled Filter Set:
Security Auditor View

Filter Set Details:

Folder Filters:
If [fortify priority order] contains critical Then set folder to Critical
If [fortify priority order] contains high Then set folder to High
If [fortify priority order] contains medium Then set folder to Medium

Copyright 2021 Micro Focus or one of its affiliates. Page 3 of 46


prueba1
If [fortify priority order] contains low Then set folder to Low

Audit Guide Summary


Audit guide not enabled

Copyright 2021 Micro Focus or one of its affiliates. Page 4 of 46


prueba1

Results Outline
Overall number of results
The scan found 2802 issues.

Vulnerability Examples by Category


Category: Buffer Overflow (1053 Issues)

Number of Issues

<Unaudited>

Not an Issue

Reliability Issue

Bad Practice

Suspicious

Exploitable

Abstract:
The function server_thread() in http_client.c might be able to write outside the bounds of allocated memory on line 140, which
could corrupt data, cause the program to crash, or lead to the execution of malicious code.
Explanation:
Buffer overflow is probably the best known form of software security vulnerability. Most software developers know what a
buffer overflow vulnerability is, but buffer overflow attacks against both legacy and newly-developed applications are still quite
common. Part of the problem is due to the wide variety of ways buffer overflows can occur, and part is due to the error-prone
techniques often used to prevent them.
In a classic buffer overflow exploit, the attacker sends data to a program, which it stores in an undersized stack buffer. The result
is that information on the call stack is overwritten, including the function's return pointer. The data sets the value of the return
pointer so that when the function returns, it transfers control to malicious code contained in the attacker's data.
Although this type of stack buffer overflow is still common on some platforms and in some development communities, there are
a variety of other types of buffer overflow, including heap buffer overflows and off-by-one errors among others. There are a
number of excellent books that provide detailed information on how buffer overflow attacks work, including Building Secure
Software [1], Writing Secure Code [2], and The Shellcoder's Handbook [3].
At the code level, buffer overflow vulnerabilities usually involve the violation of a programmer's assumptions. Many memory
manipulation functions in C and C++ do not perform bounds checking and can easily overwrite the allocated bounds of the
buffers they operate upon. Even bounded functions, such as strncpy(), can cause vulnerabilities when used incorrectly. The
combination of memory manipulation and mistaken assumptions about the size or makeup of a piece of data is the root cause of
most buffer overflows.
Buffer overflow vulnerabilities typically occur in code that:
- Relies on external data to control its behavior.
- Depends upon properties of the data that are enforced outside of the immediate scope of the code.
- Is so complex that a programmer cannot accurately predict its behavior.

The following examples demonstrate all three of the scenarios.


Example 1: This is an example of the second scenario in which the code depends on properties of the data that are not verified
locally. In this example a function named lccopy() takes a string as its argument and returns a heap-allocated copy of the string
with all uppercase letters converted to lowercase. The function performs no bounds checking on its input because it expects str to
always be smaller than BUFSIZE. If an attacker bypasses checks in the code that calls lccopy(), or if a change in that code makes
the assumption about the size of str untrue, then lccopy() will overflow buf with the unbounded call to strcpy().

char *lccopy(const char *str) {


char buf[BUFSIZE];
char *p;

Copyright 2021 Micro Focus or one of its affiliates. Page 5 of 46


prueba1
strcpy(buf, str);
for (p = buf; *p; p++) {
if (isupper(*p)) {
*p = tolower(*p);
}
}
return strdup(buf);
}

Example 2.a: The following sample code demonstrates a simple buffer overflow that is often caused by the first scenario in
which the code relies on external data to control its behavior. The code uses the gets() function to read an arbitrary amount of
data into a stack buffer. Because there is no way to limit the amount of data read by this function, the safety of the code depends
on the user to always enter fewer than BUFSIZE characters.

...
char buf[BUFSIZE];
gets(buf);
...

Example 2.b: This example shows how easy it is to mimic the unsafe behavior of the gets() function in C++ by using the >>
operator to read input into a char[] string.

...
char buf[BUFSIZE];
cin >> (buf);
...

Example 3: The code in this example also relies on user input to control its behavior, but it adds a level of indirection with the
use of the bounded memory copy function memcpy(). This function accepts a destination buffer, a source buffer, and the number
of bytes to copy. The input buffer is filled by a bounded call to read(), but the user specifies the number of bytes that memcpy()
copies.

...
char buf[64], in[MAX_SIZE];
printf("Enter buffer contents:\n");
read(0, in, MAX_SIZE-1);
printf("Bytes to copy:\n");
scanf("%d", &bytes);
memcpy(buf, in, bytes);
...

Note: This type of buffer overflow vulnerability (where a program reads data and then trusts a value from the data in subsequent
memory operations on the remaining data) has turned up with some frequency in image, audio, and other file processing libraries.
Example 4: The following code demonstrates the third scenario in which the code is so complex its behavior cannot be easily
predicted. This code is from the popular libPNG image decoder, which is used by a wide array of applications, including Mozilla
and some versions of Internet Explorer.
The code appears to safely perform bounds checking because it checks the size of the variable length, which it later uses to
control the amount of data copied by png_crc_read(). However, immediately before it tests length, the code performs a check on
png_ptr->mode, and if this check fails a warning is issued and processing continues. Since length is tested in an else if block,
length would not be tested if the first check fails, and is used blindly in the call to png_crc_read(), potentially allowing a stack
buffer overflow.
Although the code in this example is not the most complex we have seen, it demonstrates why complexity should be minimized
in code that performs memory operations.

if (!(png_ptr->mode & PNG_HAVE_PLTE)) {


/* Should be an error, but we can cope with it */
png_warning(png_ptr, "Missing PLTE before tRNS");
}
else if (length > (png_uint_32)png_ptr->num_palette) {
png_warning(png_ptr, "Incorrect tRNS chunk length");
png_crc_finish(png_ptr, length);

Copyright 2021 Micro Focus or one of its affiliates. Page 6 of 46


prueba1
return;
}
...
png_crc_read(png_ptr, readbuf, (png_size_t)length);

Example 5: This example also demonstrates the third scenario in which the program's complexity exposes it to buffer overflows.
In this case, the exposure is due to the ambiguous interface of one of the functions rather than the structure of the code (as was
the case in the previous example).
The getUserInfo() function takes a username specified as a multibyte string and a pointer to a structure for user information, and
populates the structure with information about the user. Since Windows authentication uses Unicode for usernames, the
username argument is first converted from a multibyte string to a Unicode string. This function then incorrectly passes the size of
unicodeUser in bytes rather than characters. The call to MultiByteToWideChar() may therefore write up to
(UNLEN+1)*sizeof(WCHAR) wide characters, or
(UNLEN+1)*sizeof(WCHAR)*sizeof(WCHAR) bytes, to the unicodeUser array, which has only (UNLEN+1)*sizeof(WCHAR)
bytes allocated. If the username string contains more than UNLEN characters, the call to MultiByteToWideChar() will overflow
the buffer unicodeUser.

void getUserInfo(char *username, struct _USER_INFO_2 info){


WCHAR unicodeUser[UNLEN+1];
MultiByteToWideChar(CP_ACP, 0, username, -1,
unicodeUser, sizeof(unicodeUser));
NetUserGetInfo(NULL, unicodeUser, 2, (LPBYTE *)&info);
}
Recommendations:
Never use inherently unsafe functions, such as gets(), and avoid the use of functions that are difficult to use safely such as
strcpy(). Replace unbounded functions like strcpy() with their bounded equivalents, such as strncpy() or the WinAPI functions
defined in strsafe.h [4].
Although the careful use of bounded functions can greatly reduce the risk of buffer overflow, this migration cannot be done
blindly and does not go far enough on its own to ensure security. Whenever you manipulate memory, especially strings,
remember that buffer overflow vulnerabilities typically occur in code that:
- Relies on external data to control its behavior
- Depends upon properties of the data that are enforced outside of the immediate scope of the code
- Is so complex that a programmer cannot accurately predict its behavior.
Additionally, consider the following principles:
- Never trust an external source to provide correct control information to a memory operation.
- Never trust that properties about the data your program is manipulating will be maintained throughout the program. Sanity
check data before you operate on it.
- Limit the complexity of memory manipulation and bounds-checking code. Keep it simple and clearly document the checks you
perform, the assumptions that you test, and what the expected behavior of the program is in the case that input validation fails.
- When input data is too large, be leery of truncating the data and continuing to process it. Truncation can change the meaning of
the input.
- Do not rely on tools, such as StackGuard, or non-executable stacks to prevent buffer overflow vulnerabilities. These approaches
do not address heap buffer overflows and the more subtle stack overflows that can change the contents of variables that control
the program. Additionally, many of these approaches are easily defeated, and even when they are working properly, they address
the symptom of the problem and not its cause.
Tips:
1. On Windows, less secure functions like memcpy() can be replaced with their more secure versions, such as memcpy_s().
However, this still needs to be done with caution. Because parameter validation provided by the _s family of functions varies,
relying on it can lead to unexpected behavior. Furthermore, incorrectly specifying the size of the destination buffer can still result
in buffer overflows.

http_client.c, line 140 (Buffer Overflow)


Fortify Priority: High Folder High
Kingdom: Input Validation and Representation
Abstract: The function server_thread() in http_client.c might be able to write outside the bounds
of allocated memory on line 140, which could corrupt data, cause the program to
crash, or lead to the execution of malicious code.
Source: sock_bsd.c:725 recv()

Copyright 2021 Micro Focus or one of its affiliates. Page 7 of 46


prueba1
723 PJ_ASSERT_RETURN(buf && len, PJ_EINVAL);
724
725 *len = recv(sock, (char*)buf, (int)(*len), flags);
726
727 if (*len < 0)

Sink: http_client.c:140 Assignment to pkt[]()


138 pj_create_random_string(pkt, pkt_len);
139 pj_ansi_sprintf(pkt, "\nPacket: %d", ++ctr);
140 pkt[pj_ansi_strlen(pkt)] = '\n';
141 rc = pj_sock_send(newsock, pkt, &pkt_len, 0);
142 if (rc != PJ_SUCCESS)

Copyright 2021 Micro Focus or one of its affiliates. Page 8 of 46


prueba1
Category: Buffer Overflow: Format String (422 Issues)

Number of Issues
01234567
10
8
11
9
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
100
97
101
98
102
99
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443

<Unaudited>

Not an Issue

Reliability Issue

Bad Practice

Suspicious

Exploitable

Abstract:
The format string argument to snprintf() at os_info.c line 331 does not properly limit the amount of data the function can write,
which allows the program to write outside the bounds of allocated memory. This behavior could corrupt data, crash the program,
or lead to the execution of malicious code
Explanation:
Buffer overflow is probably the best known form of software security vulnerability. Most software developers know what a
buffer overflow vulnerability is, but buffer overflow attacks against both legacy and newly-developed applications are still quite
common. Part of the problem is due to the wide variety of ways buffer overflows can occur, and part is due to the error-prone
techniques often used to prevent them.
In a classic buffer overflow exploit, the attacker sends data to a program, which it stores in an undersized stack buffer. The result
is that information on the call stack is overwritten, including the function's return pointer. The data sets the value of the return
pointer so that when the function returns, it transfers control to malicious code contained in the attacker's data.
Although this type of stack buffer overflow is still common on some platforms and in some development communities, there are
a variety of other types of buffer overflow, including heap buffer overflows and off-by-one errors among others. There are a
number of excellent books that provide detailed information on how buffer overflow attacks work, including Building Secure
Software [1], Writing Secure Code [2], and The Shellcoder's Handbook [3].
At the code level, buffer overflow vulnerabilities usually involve the violation of a programmer's assumptions. Many memory
manipulation functions in C and C++ do not perform bounds checking and can easily exceed the allocated bounds of the buffers
they operate upon. Even bounded functions, such as strncpy(), can cause vulnerabilities when used incorrectly. The combination
of memory manipulation and mistaken assumptions about the size or makeup of a piece of data is the root cause of most buffer
overflows.
In this case, an improperly constructed format string causes the program to write beyond the bounds of allocated memory.
Example: The following code overflows c because the double type requires more space than is allocated for c.

void formatString(double d) {
char c;
scanf("%d", &c)
}
Recommendations:
Although the careful use of bounded functions can greatly reduce the risk of buffer overflow, this migration cannot be done
blindly and does not go far enough on its own to ensure security. Whenever you manipulate memory, especially strings,
remember that buffer overflow vulnerabilities typically occur in code that:
- Relies on external data to control its behavior.
- Depends upon properties of the data that are enforced outside of the immediate scope of the code.
- Is so complex that a programmer cannot accurately predict its behavior.
Additionally, consider the following principles:
- Never trust an external source to provide correct control information to a memory operation.
- Never trust that properties about the data your program is manipulating will be maintained throughout the program. Sanity
check data before you operate on it.

Copyright 2021 Micro Focus or one of its affiliates. Page 9 of 46


prueba1
- Limit the complexity of memory manipulation and bounds-checking code. Keep it simple and clearly document the checks you
perform, the assumptions that you test, and what the expected behavior of the program is in the case that input validation fails.
- When input data is too large, be leery of truncating the data and continuing to process it. Truncation can change the meaning of
the input.
- Do not rely on tools, such as StackGuard, or non-executable stacks to prevent buffer overflow vulnerabilities. These approaches
do not address heap buffer overflows and the more subtle stack overflows that can change the contents of variables that control
the program. Additionally, many of these approaches are easily defeated, and even when they are working properly, they address
the symptom of the problem and not its cause.
Tips:
1. On Windows, less secure functions like memcpy() can be replaced with their more secure versions, such as memcpy_s().
However, this still needs to be done with caution. Because parameter validation provided by the _s family of functions varies,
relying on it can lead to unexpected behavior. Furthermore, incorrectly specifying the size of the destination buffer can still result
in buffer overflows.

os_info.c, line 331 (Buffer Overflow: Format String)


Fortify Priority: High Folder High
Kingdom: Input Validation and Representation
Abstract: The format string argument to snprintf() at os_info.c line 331 does not properly limit
the amount of data the function can write, which allows the program to write outside
the bounds of allocated memory. This behavior could corrupt data, crash the program,
or lead to the execution of malicious code
Sink: os_info.c:331 snprintf()
329 int cnt;
330
331 cnt = pj_ansi_snprintf(tmp, sizeof(tmp),
332 "%s%s%s%s%s%s%s",
333 si.os_name.ptr,

Copyright 2021 Micro Focus or one of its affiliates. Page 10 of 46


prueba1
Category: Type Mismatch: Signed to Unsigned (151 Issues)

Number of Issues
0123456789
111
12
013
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
100
99
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158

<Unaudited>

Not an Issue

Reliability Issue

Bad Practice

Suspicious

Exploitable

Abstract:
The function http_on_data_read() in http_client.c is declared to return an unsigned value, but on line 421 it returns a signed
value.
Explanation:
It is dangerous to rely on implicit casts between signed and unsigned numbers because the result can take on an unexpected value
and violate weak assumptions made elsewhere in the program.
Example: In this example, depending on the return value of accecssmainframe(), the variable amount can hold a negative value
when it is returned. Because the function is declared to return an unsigned value, amount will be implicitly cast to an unsigned
number.

unsigned int readdata () {


int amount = 0;
...
amount = accessmainframe();
...
return amount;
}

If the return value of accessmainframe() is -1, then the return value of readdata() will be 4,294,967,295 on a system that uses 32-
bit integers.
Conversion between signed and unsigned values can lead to a variety of errors, but from a security standpoint is most commonly
associated with integer overflow and buffer overflow vulnerabilities.
Recommendations:
Although unexpected conversion between signed and unsigned quantities typically creates general quality problems, depending
on the assumptions that a conversion violates, it can lead to serious security risks. Pay attention to compiler warnings related to
signed/unsigned conversions. Some programmers may believe that these warnings are innocuous, but in some cases they point
out potential integer overflow problems.

http_client.c, line 421 (Type Mismatch: Signed to Unsigned)


Fortify Priority: High Folder High
Kingdom: Code Quality
Abstract: The function http_on_data_read() in http_client.c is declared to return an unsigned
value, but on line 421 it returns a signed value.
Sink: http_client.c:421 AssignmentStatement()
419 * it later if necessary.
420 */
421 hreq->response.size = (hreq->response.content_length == -1 ?
422 INITIAL_DATA_BUF_SIZE :
423 hreq->response.content_length);

Copyright 2021 Micro Focus or one of its affiliates. Page 11 of 46


prueba1
Category: Path Manipulation (75 Issues)

Number of Issues
012345678910
111
2131
4151
6171
8292
02122
3242
5262
7283
9303
13233
4353
6373
8494
0414
24344
5464
7485
9505
1525
35455
6575
8696
0616
2636
46566
7687
9707
1727
3747
5767

<Unaudited>

Not an Issue

Reliability Issue

Bad Practice

Suspicious

Exploitable

Abstract:
Attackers are able to control the file system path argument to fopen() at file_io_ansi.c line 63, which allows them to access or
modify otherwise protected files.
Explanation:
Path manipulation errors occur when the following two conditions are met:
1. An attacker is able to specify a path used in an operation on the file system.
2. By specifying the resource, the attacker gains a capability that would not otherwise be permitted.
For example, the program may give the attacker the ability to overwrite the specified file or run with a configuration controlled
by the attacker.

Example 1: The following code uses input from a CGI request to create a file name. The programmer has not considered the
possibility that an attacker could provide a file name such as "../../apache/conf/httpd.conf", which will cause the application to
delete the specified configuration file.

char* rName = getenv("reportName");


...
unlink(rName);

Example 2: The following code uses input from the command line to determine which file to open and echo back to the user. If
the program runs with adequate privileges and malicious users can create soft links to the file, they can use the program to read
the first part of any file on the system.

ifstream ifs(argv[0]);
string s;
ifs >> s;
cout << s;
Recommendations:
The best way to prevent path manipulation is with a level of indirection: create a list of legitimate resource names that a user is
allowed to specify, and only allow the user to select from the list. With this approach the input provided by the user is never used
directly to specify the resource name.
In some situations this approach is impractical because the set of legitimate resource names is too large or too hard to keep track
of. Programmers often resort to blacklisting in these situations. Blacklisting selectively rejects or escapes potentially dangerous
characters before using the input. However, any such list of unsafe characters is likely to be incomplete and will almost certainly
become out of date. A better approach is to create a whitelist of characters that are allowed to appear in the resource name and
accept input composed exclusively of characters in the approved set.
Tips:
1. If the program is performing custom input validation you are satisfied with, use the Fortify Custom Rules Editor to create a
cleanse rule for the validation routine.
2. Implementation of an effective blacklist is notoriously difficult. One should be skeptical if validation logic requires
blacklisting. Consider different types of input encoding and different sets of meta-characters that might have special meaning
when interpreted by different operating systems, databases, or other resources. Determine whether or not the blacklist can be
updated easily, correctly, and completely if these requirements ever change.

file_io_ansi.c, line 63 (Path Manipulation)

Copyright 2021 Micro Focus or one of its affiliates. Page 12 of 46


prueba1
Fortify Priority: Critical Folder Critical
Kingdom: Input Validation and Representation
Abstract: Attackers are able to control the file system path argument to fopen() at file_io_ansi.c
line 63, which allows them to access or modify otherwise protected files.
Source: client_main.c:556 main(1)
554 }
555
556 int main(int argc, char *argv[])
557 {
558 struct pj_getopt_option long_options[] = {

Sink: file_io_ansi.c:63 fopen()


61 *p++ = '\0';
62
63 *fd = fopen(pathname, mode);
64 if (*fd == NULL)
65 return PJ_RETURN_OS_ERROR(errno);

Copyright 2021 Micro Focus or one of its affiliates. Page 13 of 46


prueba1
Category: String Termination Error (46 Issues)

Number of Issues
0 1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930313233343536373839404142434445464748

<Unaudited>

Not an Issue

Reliability Issue

Bad Practice

Suspicious

Exploitable

Abstract:
The function server_thread() in http_client.c relies on proper string termination when it calls strlen() on line 122, but the source
buffer might not contain a null terminator. A buffer overflow is possible.
Explanation:
String termination errors occur when:
1. Data enters a program via a function that does not null terminate its output.
2. The data is passed to a function that requires its input to be null terminated.

Example 1: The following code reads from cfgfile and copies the input into inputbuf using strcpy(). The code mistakenly
assumes that inputbuf will always contain a null terminator.

#define MAXLEN 1024


...
char *pathbuf[MAXLEN];
...
read(cfgfile,inputbuf,MAXLEN); //does not null terminate
strcpy(pathbuf,inputbuf); //requires null terminated input
...

The code in Example 1 will behave correctly if the data read from cfgfile is null terminated on disk as expected. But if an
attacker is able to modify this input so that it does not contain the expected null character, the call to strcpy() will continue
copying from memory until it encounters an arbitrary null character. This will likely overflow the destination buffer and, if the
attacker may control the contents of memory immediately following inputbuf, can leave the application susceptible to a buffer
overflow attack.
Example 2: In the following code, readlink() expands the name of a symbolic link stored in the buffer path so that the buffer buf
contains the absolute path of the file referenced by the symbolic link. The length of the resulting value is then calculated using
strlen().

...
char buf[MAXPATH];
...
readlink(path, buf, MAXPATH);
int length = strlen(buf);
...

The code in Example 2 will not behave correctly because the value read into buf by readlink() will not be null terminated. In
testing, vulnerabilities like this one might not be caught because the unused contents of buf and the memory immediately
following it may be null, thereby causing strlen() to appear as if it is behaving correctly. However, in the wild strlen() will
continue traversing memory until it encounters an arbitrary null character on the stack, which results in a value of length that is
much larger than the size of buf and may cause a buffer overflow in subsequent uses of this value.
Traditionally, strings are represented as a region of memory containing data terminated with a null character. Older string-
handling methods frequently rely on this null character to determine the length of the string. If a buffer that does not contain a
null terminator is passed to one of these functions, the function will read past the end of the buffer.

Copyright 2021 Micro Focus or one of its affiliates. Page 14 of 46


prueba1
Malicious users typically exploit this type of vulnerability by injecting data with unexpected size or content into the application.
They may provide the malicious input either directly as input to the program or indirectly by modifying application resources,
such as configuration files. In the event that an attacker causes the application to read beyond the bounds of a buffer, the attacker
may be able to use a resulting buffer overflow to inject and execute arbitrary code on the system.
Recommendations:
If the program is written for Windows(R), replace all calls to strlen() with the strsafe.h equivalents StringCbLength(), which
takes a maximum buffer size in bytes, or StringCchLength(), which takes a maximum buffer size in characters. If the length of
the provided string is greater than the specified buffer size, these functions return an error; otherwise they behave in the same
way as strlen().
If the program is written for a platform where these bounded replacements are not available, consider implementing a proprietary
bounded equivalent to strlen() that behaves in the same way as the strsafe.h functions described above. If strlen() must be used,
perform careful manual null termination of strings before they are passed to strlen() and audit occurrences of strlen() to ensure
the correct usage. You can use a custom rule to unconditionally flag this function for audit. See the Fortify SCA Custom Rules
Guide for more information.
Tips:
1. At first glance, the following code might appear to correctly handle the fact that readlink() does not null terminate its output.
But read the code carefully; this is an off-by-one error.

...
char buf[MAXPATH];
int size = readlink(path, buf, MAXPATH);
if (size != -1){
buf[size] = '\0';
strncpy(filename, buf, MAXPATH);
length = strlen(filename);
}
...

By calling strlen(), the programmer relies on a string terminator. The programmer has attempted to explicitly null terminate the
buffer in order to guarantee that this dependency is always satisfied. The problem with this approach is that it is error-prone. In
this example, if readlink() returns MAXPATH, then buf[size] will refer to a location outside of the buffer; strncpy() will fail to
null terminate filename; and strlen() will return an incorrect (and potentially huge) value.
2. On Windows, less secure functions like strcpy() can be replaced with their more secure versions, such as strcpy_s(). However,
this still needs to be done with caution. Because parameter validation provided by the _s family of functions varies, relying on it
can lead to unexpected behavior. Furthermore, incorrectly specifying the size of the destination buffer can still result in buffer
overflows and null termination errors.

http_client.c, line 122 (String Termination Error)


Fortify Priority: High Folder High
Kingdom: Input Validation and Representation
Abstract: The function server_thread() in http_client.c relies on proper string termination when
it calls strlen() on line 122, but the source buffer might not contain a null terminator.
A buffer overflow is possible.
Source: sock_bsd.c:725 recv()
723 PJ_ASSERT_RETURN(buf && len, PJ_EINVAL);
724
725 *len = recv(sock, (char*)buf, (int)(*len), flags);
726
727 if (*len < 0)

Sink: http_client.c:122 strlen()


120 pj_ansi_sprintf(pkt, "HTTP/1.0 200 OK\r\n");
121 if (srv->send_content_length) {
122 pj_ansi_sprintf(pkt + pj_ansi_strlen(pkt),
123 "Content-Length: %d\r\n",
124 srv->data_size);

Copyright 2021 Micro Focus or one of its affiliates. Page 15 of 46


prueba1
Category: Use After Free (36 Issues)

Number of Issues
0 1 2 3 4 5 6 7 8 9 10111213141516171819202122232425262728293031323334353637

<Unaudited>

Not an Issue

Reliability Issue

Bad Practice

Suspicious

Exploitable

Abstract:
The function https_client_test() in ssl_sock.c references a freed memory location on line 454.
Explanation:
Use after free errors occur when a program continues to use a pointer after it has been freed. Like double free errors and memory
leaks, use after free errors have two common and sometimes overlapping causes:
- Error conditions and other exceptional circumstances.
- Confusion over which part of the program is responsible for freeing the memory
Use after free errors sometimes have no effect and other times cause a program to crash. While it is technically feasible for the
freed memory to be re-allocated and for an attacker to use this reallocation to launch a buffer overflow attack, we are unaware of
any exploits based on this type of attack.
Example: The following code illustrates a use after free error:

char* ptr = (char*)malloc (SIZE);


...
if (err) {
abrt = 1;
free(ptr);
}
...
if (abrt) {
logError("operation aborted before commit", ptr);
}
Recommendations:
Guard against using memory after it has been freed by giving up all references to the memory immediately after calling free().
This is commonly achieved by replacing calls to free() with a macro that assigns NULL to the pointer immediately after it is
freed:

#define FREE( ptr ) {free(ptr); ptr = NULL;}

While this technique prevents the freed memory from being used again, if there is still confusion about when the memory is
supposed to be freed, assigning the NULL to the pointer can result in a null pointer dereference. In most cases this is probably an
improvement, because the error is more likely to be caught during testing and is less likely to lead to an exploitable vulnerability.
It transforms an error with unpredictable behavior into an error that is easier to debug.

ssl_sock.c, line 454 (Use After Free)


Fortify Priority: High Folder High
Kingdom: Code Quality
Abstract: The function https_client_test() in ssl_sock.c references a freed memory location on
line 454.
Sink: ssl_sock.c:454 pj_ssl_sock_start_connect(..., pool, ...) : Pointer pool used
after it was previously freed()

Copyright 2021 Micro Focus or one of its affiliates. Page 16 of 46


prueba1
452 pj_sockaddr_init(PJ_AF_INET, &local_addr, pj_strset2(&tmp_st, "0.0.0.0"), 0);
453 pj_sockaddr_init(PJ_AF_INET, &rem_addr, pj_strset2(&tmp_st, HTTP_SERVER_ADDR),
HTTP_SERVER_PORT);
454 status = pj_ssl_sock_start_connect(ssock, pool, &local_addr, &rem_addr,
sizeof(rem_addr));
455 if (status == PJ_SUCCESS) {
456 ssl_on_connect_complete(ssock, PJ_SUCCESS);

Copyright 2021 Micro Focus or one of its affiliates. Page 17 of 46


prueba1
Category: Null Dereference (28 Issues)

Number of Issues
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29

<Unaudited>

Not an Issue

Reliability Issue

Bad Practice

Suspicious

Exploitable

Abstract:
The function on_read_complete() in resolver.c can crash the program by dereferencing a null pointer on line 1724.
Explanation:
Null pointer exceptions usually occur when one or more of the programmer's assumptions is violated. There are at least three
flavors of this problem: check-after-dereference, dereference-after-check, and dereference-after-store. A check-after-dereference
error occurs when a program dereferences a pointer that can be null before checking if the pointer is null. Dereference-after-
check errors occur when a program makes an explicit check for null, but proceeds to dereference the pointer when it is known to
be null. Errors of this type are often the result of a typo or programmer oversight. A dereference-after-store error occurs when a
program explicitly sets a pointer to null and dereferences it later. This error is often the result of a programmer initializing a
variable to null when it is declared.
Most null pointer issues result in general software reliability problems, but if an attacker can intentionally trigger a null pointer
dereference, the attacker may be able to use the resulting exception to bypass security logic in order to mount a denial of service
attack, or to cause the application to reveal debugging information that will be valuable in planning subsequent attacks.
Example 1: In the following code, the programmer assumes that the variable ptr is not NULL. That assumption is made explicit
when the programmer dereferences the pointer. This assumption is later contradicted when the programmer checks ptr against
NULL. If ptr can be NULL when it is checked in the if statement then it can also be NULL when it dereferenced and may cause
a segmentation fault.

ptr->field = val;
...
if (ptr != NULL) {
...
}

Example 2: In the following code, the programmer confirms that the variable ptr is NULL and subsequently dereferences it
erroneously. If ptr is NULL when it is checked in the if statement, then a null dereference will occur, thereby causing a
segmentation fault.

if (ptr == null) {
ptr->field = val;
...
}

Example 3: In the following code, the programmer forgets that the string '\0' is actually 0 or NULL, thereby dereferencing a null
pointer and causing a segmentation fault.

if (ptr == '\0') {
*ptr = val;
...
}

Example 4: In the following code, the programmer explicitly sets the variable ptr to NULL. Later, the programmer dereferences
ptr before checking the object for a null value.

*ptr = NULL;

Copyright 2021 Micro Focus or one of its affiliates. Page 18 of 46


prueba1
...
ptr->field = val;
...
}
Recommendations:
Security problems caused by dereferencing NULL pointers almost always take the form of denial of service attacks. If an
attacker can consistently trigger a null pointer dereference then other users may be prevented from gaining legitimate access to
the application. Apart from situations where an attacker may deliberately trigger a segmentation fault, dereferencing a null
pointer may cause sporadic crashes that can be hard to track down.
Implement careful checks before dereferencing objects that might be null. When possible, abstract null checks into wrappers
around code that manipulates resources to ensure that they are applied in all cases and to minimize the places where mistakes can
occur.

resolver.c, line 1724 (Null Dereference)


Fortify Priority: High Folder High
Kingdom: Code Quality
Abstract: The function on_read_complete() in resolver.c can crash the program by
dereferencing a null pointer on line 1724.
Sink: resolver.c:1724 Dereferenced : dns_pkt()
1722 /* Find the query based on the transaction ID */
1723 q = (pj_dns_async_query*)
1724 pj_hash_get(resolver->hquerybyid, &dns_pkt->hdr.id,
1725 sizeof(dns_pkt->hdr.id), NULL);
1726 if (!q) {

Copyright 2021 Micro Focus or one of its affiliates. Page 19 of 46


prueba1
Category: Password Management: Empty Password (21 Issues)

Number of Issues
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

<Unaudited>

Not an Issue

Reliability Issue

Bad Practice

Suspicious

Exploitable

Abstract:
Empty passwords may compromise system security in a way that cannot be easily remedied.
Explanation:
It is never a good idea to assign an empty string to a password variable. If the empty password is used to successfully
authenticate against another system, then the corresponding account's security is likely compromised because it accepts an empty
password. If the empty password is merely a placeholder until a legitimate value can be assigned to the variable, then it can
confuse anyone unfamiliar with the code and potentially cause problems on unexpected control flow paths.

Example 1: The code below attempts to connect to a database with an empty password.
...
rc = SQLConnect(*hdbc, server, SQL_NTS, "scott", SQL_NTS, "", SQL_NTS);
...

If the code in Example 1 succeeds, it indicates that the database user account "scott" is configured with an empty password,
which can be easily guessed by an attacker. Even worse, once the program has shipped, updating the account to use a non-empty
password will require a code change.
Example 2: The code below initializes a password variable to an empty string, attempts to read a stored value for the password,
and compares it against a user-supplied value.

...
char *stored_password = "";
readPassword(stored_password);
if(safe_strcmp(stored_password, user_password))
// Access protected resources
...
}
...

If readPassword() fails to retrieve the stored password due to a database error or another problem, then an attacker could trivially
bypass the password check by providing an empty string for user_password.
Recommendations:
Always read stored password values from encrypted, external resources and assign password variables meaningful values.
Ensure that sensitive resources are never protected with empty or null passwords.
Starting with Microsoft(R) Windows(R) 2000, Microsoft(R) provides Windows Data Protection Application Programming
Interface (DPAPI), which is an OS-level service that protects sensitive application data, such as passwords and private keys [1].
Tips:
1. When identifying null, empty, or hardcoded passwords, default rules only consider fields and variables that contain the word
password. However, the Fortify Custom Rules Editor provides the Password Management wizard that makes it easy to create
rules for detecting password management issues on custom-named fields and variables.

http_client.c, line 270 (Password Management: Empty Password)


Fortify Priority: High Folder High

Copyright 2021 Micro Focus or one of its affiliates. Page 20 of 46


prueba1
Kingdom: Security Features
Abstract: Empty passwords may compromise system security in a way that cannot be easily
remedied.
Sink: http_client.c:270 FieldAccess: passwd()
268 int port;
269 const char *path;
270 } test_data[] =
271 {
272 /* Simple URL without '/' in the end */

Copyright 2021 Micro Focus or one of its affiliates. Page 21 of 46


prueba1
Category: Privacy Violation (21 Issues)

Number of Issues
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

<Unaudited>

Not an Issue

Reliability Issue

Bad Practice

Suspicious

Exploitable

Abstract:
The function console_write_log() in cli_console.c mishandles confidential information on line 65. The program could
compromise user privacy.
Explanation:
Privacy violations occur when:
1. Private user information enters the program.
2. The data is written to an external location, such as the console, file system, or network.
Example: The following code contains a logging statement that tracks the contents of records added to a database by storing them
in a log file. Among other values that are stored, the get_password() function returns the user-supplied plaintext password
associated with the account.

pass = get_password();
...
fprintf(dbms_log, "%d:%s:%s:%s", id, pass, type, tstamp);

The code in the example above logs a plaintext password to the file system. Although many developers trust the file system as a
safe storage location for any and all data, it should not be trusted implicitly, particularly when privacy is a concern.
Private data can enter a program in a variety of ways:
- Directly from the user in the form of a password or personal information.
- Accessed from a database or other data store by the application.
- Indirectly from a partner or other third party.
Sometimes data that is not labeled as private can have a privacy implication in a different context. For example, student
identification numbers are usually not considered private because there is no explicit and publicly-available mapping to an
individual student's personal information. However, if a school generates student identification based on student social security
numbers, then the identification numbers should be considered private.
Security and privacy concerns often seem to compete with each other. From a security perspective, you should record all
important operations so that any anomalous activity can later be identified. However, when private data is involved, this practice
can create additional risk.
Although there are many ways in which private data can be handled unsafely, a common risk stems from misplaced trust.
Programmers often trust the operating environment in which a program runs, and therefore believe that it is acceptable to store
private information on the file system, in the registry, or in other locally-controlled resources. However, even if access to certain
resources is restricted, it does not guarantee that the individuals who do have access can be trusted with certain data. For
example, in 2004, an unscrupulous employee at AOL sold approximately 92 million private customer e-mail addresses to a
spammer marketing an offshore gambling web site [1].
In response to such high-profile exploits, the collection and management of private data is becoming increasingly regulated.
Depending on its location, the type of business it conducts, and the nature of any private data it handles, an organization may be
required to comply with one or more of the following federal and state regulations:
- Safe Harbor Privacy Framework [3]
- Gramm-Leach Bliley Act (GLBA) [4]
- Health Insurance Portability and Accountability Act (HIPAA) [5]

Copyright 2021 Micro Focus or one of its affiliates. Page 22 of 46


prueba1
- California SB-1386 [6]
Despite these regulations, privacy violations continue to occur with alarming frequency.
Recommendations:
When security and privacy demands clash, privacy should usually be given the higher priority. To accomplish this and still
maintain required security information, cleanse any private information before it exits the program.
To enforce good privacy management, develop and strictly adhere to internal privacy guidelines. The guidelines should
specifically describe how an application should handle private data. If your organization is regulated by federal or state law,
ensure that your privacy guidelines are sufficiently strenuous to meet the legal requirements. Even if your organization is not
regulated, you must protect private information or risk losing customer confidence.
The best policy with respect to private data is to minimize its exposure. Applications, processes, and employees should not be
granted access to any private data unless the access is required for the tasks that they are to perform. Just as the principle of least
privilege dictates that no operation should be performed with more than the necessary privileges, access to private data should be
restricted to the smallest possible group.
Tips:
1. As part of any thorough audit for privacy violations, ensure that custom rules have been written to identify all sources of
private or otherwise sensitive information entering the program. Most sources of private data cannot be identified automatically.
Without custom rules, your check for privacy violations is likely to be substantially incomplete.

cli_console.c, line 65 (Privacy Violation)


Fortify Priority: Critical Folder Critical
Kingdom: Security Features
Abstract: The function console_write_log() in cli_console.c mishandles confidential
information on line 65. The program could compromise user privacy.
Source: sip_uri.c:278 Read url->passwd()
276 if (url->passwd.slen) {
277 copy_advance_char_check(buf, ':');
278 copy_advance_escape(buf, url->passwd, pc->pjsip_PASSWD_SPEC);
279 }

Sink: cli_console.c:65 printf()


63
64 if (cfe->sess->log_level > level)
65 printf("%.*s", (int)len, data);
66 }

Copyright 2021 Micro Focus or one of its affiliates. Page 23 of 46


prueba1
Category: Integer Overflow (16 Issues)

Number of Issues
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

<Unaudited>

Not an Issue

Reliability Issue

Bad Practice

Suspicious

Exploitable

Abstract:
The function default_block_alloc() in pool_policy_malloc.c does not account for integer overflow, which can result in a logic
error or a buffer overflow.
Explanation:
Integer overflow errors occur when a program fails to account for the fact that an arithmetic operation can result in a quantity
either greater than a data type's maximum value or less than its minimum value. These errors often cause problems in memory
allocation functions, where user input intersects with an implicit conversion between signed and unsigned values. If an attacker
can cause the program to under-allocate memory or interpret a signed value as an unsigned value in a memory operation, the
program may be vulnerable to a buffer overflow.
Example 1: The following code excerpt from OpenSSH 3.3 demonstrates a classic case of integer overflow:

nresp = packet_get_int();
if (nresp > 0) {
response = xmalloc(nresp*sizeof(char*));
for (i = 0; i < nresp; i++)
response[i] = packet_get_string(NULL);
}

If nresp has the value 1073741824 and sizeof(char*) has its typical value of 4, then the result of the operation
nresp*sizeof(char*) overflows, and the argument to xmalloc() will be 0. Most malloc() implementations will allow for the
allocation of a 0-byte buffer, causing the subsequent loop iterations to overflow the heap buffer response.
Example 2: This example processes user input comprised of a series of variable-length structures. The first 2 bytes of input
dictate the size of the structure to be processed.

char* processNext(char* strm) {


char buf[512];
short len = *(short*) strm;
strm += sizeof(len);
if (len <= 512) {
memcpy(buf, strm, len);
process(buf);
return strm + len;
} else {
return -1;
}
}

The programmer has set an upper bound on the structure size: if it is larger than 512, the input will not be processed. The
problem is that len is a signed integer, so the check against the maximum structure length is done with signed integers, but len is
converted to an unsigned integer for the call to memcpy(). If len is negative, then it will appear that the structure has an
appropriate size (the if branch will be taken), but the amount of memory copied by memcpy() will be quite large, and the attacker
will be able to overflow the stack with data in strm.
Recommendations:

Copyright 2021 Micro Focus or one of its affiliates. Page 24 of 46


prueba1
There are no simple guidelines that allow you to avoid every integer overflow problem, but these recommendations will help
prevent the most egregious cases:
- Pay attention to compiler warnings related to signed/unsigned conversions. Some programmers may believe that these warnings
are innocuous, but they sometimes point out potential integer overflow problems.
- Be vigilant about checking reasonable upper and lower bounds for all program input. Even if the program should only be
dealing with positive integers, check to be sure that the values you are processing are not less than zero. (You can eliminate the
need for a lower bounds check by using unsigned data types.)
- Be conservative about the range of values you allow.
- Be cognizant of the implicit typecasting that takes place when you call functions,
perform arithmetic operations or compare values of different types.
Example 3: The code below implements a wrapper function designed to allocate memory for an array safely by performing an
appropriate check on its arguments prior to making a call to malloc().

void* arrmalloc(uint sz, uint nelem) {


void *p;
if(sz > 0 && nelem >= UINT_MAX / sz)
return 0;
return malloc(sz * nelem);
}
Tips:
1. Consider whether or not the integer that might overflow has been derived from the length of a string. If it has, it is safe to
assume that the string fits inside the process's address space, which puts an upper bound on the string's length. This fact alone
does not make integer overflow impossible, but it does put additional constraints on the arithmetic that must be performed in
order to cause an overflow.

pool_policy_malloc.c, line 46 (Integer Overflow)


Fortify Priority: High Folder High
Kingdom: Input Validation and Representation
Abstract: The function default_block_alloc() in pool_policy_malloc.c does not account for
integer overflow, which can result in a logic error or a buffer overflow.
Source: siprtp.c:2072 main(0)
2070 * main()
2071 */
2072 int main(int argc, char *argv[])
2073 {
2074 unsigned i;

Sink: pool_policy_malloc.c:46 malloc()


44 }
45
46 p = malloc(size+(SIG_SIZE << 1));
47
48 if (p == NULL) {

Copyright 2021 Micro Focus or one of its affiliates. Page 25 of 46


prueba1
Category: Buffer Overflow: Off-by-One (5 Issues)

Number of Issues
0 1 2 3 4 5

<Unaudited>

Not an Issue

Reliability Issue

Bad Practice

Suspicious

Exploitable

Abstract:
The function base64_test() in encryption.c writes one location past the bounds of output on line 602, which could corrupt data,
cause the program to crash, or lead to the execution of malicious code.
Explanation:
Buffer overflow is probably the best known form of software security vulnerability. Most software developers know what a
buffer overflow vulnerability is, but buffer overflow attacks against both legacy and newly-developed applications are still quite
common. Part of the problem is due to the wide variety of ways buffer overflows can occur, and part is due to the error-prone
techniques often used to prevent them.
In a classic buffer overflow exploit, the attacker sends data to a program, which it stores in an undersized stack buffer. The result
is that information on the call stack is overwritten, including the function's return pointer. The data sets the value of the return
pointer so that when the function returns, it transfers control to malicious code contained in the attacker's data.
Although this type of off-by-one error is still common on some platforms and in some development communities, there are a
variety of other types of buffer overflow, including stack and heap buffer overflows among others. There are a number of
excellent books that provide detailed information on how buffer overflow attacks work, including Building Secure Software [1],
Writing Secure Code [2], and The Shellcoder's Handbook [3].
At the code level, buffer overflow vulnerabilities usually involve the violation of a programmer's assumptions. Many memory
manipulation functions in C and C++ do not perform bounds checking and can easily exceed the allocated bounds of the buffers
they operate upon. Even bounded functions, such as strncpy(), can cause vulnerabilities when used incorrectly. The combination
of memory manipulation and mistaken assumptions about the size or makeup of a piece of data is the root cause of most buffer
overflows.
Example: The following code contains an off-by-one buffer overflow, which occurs when recv returns the maximum allowed
sizeof(buf) bytes read. In this case, the subsequent dereference of buf[nbytes] will write the null byte outside the bounds of
allocated memory.

void receive(int socket) {


char buf[MAX];
int nbytes = recv(socket, buf, sizeof(buf), 0);
buf[nbytes] = '\0';
...
}
Recommendations:
Although the careful use of bounded functions can greatly reduce the risk of buffer overflow, this migration cannot be done
blindly and does not go far enough on its own to ensure security. Whenever you manipulate memory, especially strings,
remember that buffer overflow vulnerabilities typically occur in code that:
- Relies on external data to control its behavior.
- Depends upon properties of the data that are enforced outside of the immediate scope of the code.
- Is so complex that a programmer cannot accurately predict its behavior.
Additionally, consider the following principles:
- Never trust an external source to provide correct control information to a memory operation.
- Never trust that properties about the data your program is manipulating will be maintained throughout the program. Sanity
check data before you operate on it.

Copyright 2021 Micro Focus or one of its affiliates. Page 26 of 46


prueba1
- Limit the complexity of memory manipulation and bounds-checking code. Keep it simple and clearly document the checks you
perform, the assumptions that you test, and what the expected behavior of the program is in the case that input validation fails.
- When input data is too large, be leery of truncating the data and continuing to process it. Truncation can change the meaning of
the input.
- Do not rely on tools, such as StackGuard, or non-executable stacks to prevent buffer overflow vulnerabilities. These approaches
do not address heap buffer overflows and the more subtle stack overflows that can change the contents of variables that control
the program. Additionally, many of these approaches are easily defeated, and even when they are working properly, they address
the symptom of the problem and not its cause.
Tips:
1. On Windows, less secure functions like memcpy() can be replaced with their more secure versions, such as memcpy_s().
However, this still needs to be done with caution. Because parameter validation provided by the _s family of functions varies,
relying on it can lead to unexpected behavior. Furthermore, incorrectly specifying the size of the destination buffer can still result
in buffer overflows.

encryption.c, line 602 (Buffer Overflow: Off-by-One)


Fortify Priority: Critical Folder Critical
Kingdom: Input Validation and Representation
Abstract: The function base64_test() in encryption.c writes one location past the bounds of
output on line 602, which could corrupt data, cause the program to crash, or lead to
the execution of malicious code.
Sink: encryption.c:602 Assignment to output()
600 return -91;
601
602 output[out_len] = '\0';
603 if (strcmp(output, base64_test_vec[i].base64) != 0)
604 return -92;

Copyright 2021 Micro Focus or one of its affiliates. Page 27 of 46


prueba1
Category: Insecure Randomness (5 Issues)

Number of Issues
0 1 2 3 4 5

<Unaudited>

Not an Issue

Reliability Issue

Bad Practice

Suspicious

Exploitable

Abstract:
The random number generator implemented by srand() cannot withstand a cryptographic attack.
Explanation:
Insecure randomness errors occur when a function that can produce predictable values is used as a source of randomness in a
security-sensitive context.
Computers are deterministic machines, and as such are unable to produce true randomness. Pseudorandom Number Generators
(PRNGs) approximate randomness algorithmically, starting with a seed from which subsequent values are calculated.
There are two types of PRNGs: statistical and cryptographic. Statistical PRNGs provide useful statistical properties, but their
output is highly predictable and form an easy to reproduce numeric stream that is unsuitable for use in cases where security
depends on generated values being unpredictable. Cryptographic PRNGs address this problem by generating output that is more
difficult to predict. For a value to be cryptographically secure, it must be impossible or highly improbable for an attacker to
distinguish between the generated random value and a truly random value. In general, if a PRNG algorithm is not advertised as
being cryptographically secure, it is probably a statistical PRNG and should not be used in security-sensitive contexts, where its
use can lead to serious vulnerabilities such as easy-to-guess temporary passwords, predictable cryptographic keys, session
hijacking, and DNS spoofing.
Example: The following code uses a statistical PRNG to create a URL for a receipt that remains active for some period of time
after a purchase.

char* CreateReceiptURL() {
int num;
time_t t1;
char *URL = (char*) malloc(MAX_URL);
if (URL) {
(void) time(&t1);
srand48((long) t1); /* use time to set seed */
sprintf(URL, "%s%d%s", "http://test.com/", lrand48(), ".html");
}
return URL;
}

This code uses the lrand48() function to generate "unique" identifiers for the receipt pages it generates. Since lrand48() is a
statistical PRNG, it is easy for an attacker to guess the strings it generates. Although the underlying design of the receipt system
is also faulty, it would be more secure if it used a random number generator that did not produce predictable receipt identifiers.
Recommendations:
When unpredictability is critical, as is the case with most security-sensitive uses of randomness, use a cryptographic PRNG.
Regardless of the PRNG you choose, always use a value with sufficient entropy to seed the algorithm. (Values such as the
current time offer only negligible entropy and should not be used.)
There are various cross-platform solutions for C and C++ programs that offer cryptographically secure PRNGs, such as Yarrow
[1], CryptLib [2], Crypt++ [3], BeeCrypt [4] and OpenSSL [5].
On Windows(R) systems, C and C++ programs can use the CryptGenRandom() function in the CryptoAPI [6]. To avoid the
overhead of pulling in the entire CryptoAPI, access the underlying RtlGenRandom() function directly [7].

Copyright 2021 Micro Focus or one of its affiliates. Page 28 of 46


prueba1
In the Windows .NET framework, use the GetBytes() function in any class that implements
System.Security.Cryptography.RandomNumberGenerator, such as System.Security.Cryptography.RNGCryptoServiceProvider
[8].

rand.c, line 27 (Insecure Randomness)


Fortify Priority: High Folder High
Kingdom: Security Features
Abstract: The random number generator implemented by srand() cannot withstand a
cryptographic attack.
Sink: rand.c:27 srand()
25 {
26 PJ_CHECK_STACK();
27 platform_srand(seed);
28 }

Copyright 2021 Micro Focus or one of its affiliates. Page 29 of 46


prueba1
Category: Insecure Transport: Weak SSL Protocol (4 Issues)

Number of Issues
0 1 2 3 4

<Unaudited>

Not an Issue

Reliability Issue

Bad Practice

Suspicious

Exploitable

Abstract:
The SSLv2, SSLv23, and SSLv3 protocols contain several flaws that make them insecure, so they should not be used to transmit
sensitive data.
Explanation:
The Transport Layer Security (TLS) and Secure Sockets Layer (SSL) protocols provide a protection mechanism to ensure the
authenticity, confidentiality and integrity of data transmitted between a client and web server. Both TLS and SSL have
undergone revisions resulting in periodic version updates. Each new revision was designed to address the security weaknesses
discovered in the previous versions. Use of an insecure version of TLS/SSL will weaken the strength of the data protection and
could allow an attacker to compromise, steal, or modify sensitive information.
Weak versions of TLS/SSL may exhibit one or more of the following properties:
- No protection against man-in-the-middle attacks
- Same key used for authentication and encryption
- Weak message authentication control
- No protection against TCP connection closing
The presence of these properties may allow an attacker to intercept, modify, or tamper with sensitive data.
Recommendations:
It is highly recommended to force the client to only use the most secure protocols.
Example 1:
c->sslContext = SSL_CTX_new (TLSv1_2_method());

The example above demonstrates how to enforce communication over the TLSv1.2 protocol.

ssl_sock_ossl.c, line 576 (Insecure Transport: Weak SSL Protocol)


Fortify Priority: Critical Folder Critical
Kingdom: Security Features
Abstract: The SSLv2, SSLv23, and SSLv3 protocols contain several flaws that make them
insecure, so they should not be used to transmit sensitive data.
Sink: ssl_sock_ossl.c:576 SSLv3_server_method()
574 #ifndef OPENSSL_NO_SSL3_METHOD
575 if (!meth)
576 meth = (SSL_METHOD*)SSLv3_server_method();
577 #endif
578 #ifndef OPENSSL_NO_SSL2

Copyright 2021 Micro Focus or one of its affiliates. Page 30 of 46


prueba1
Category: Format String (3 Issues)

Number of Issues
0 1 2 3

<Unaudited>

Not an Issue

Reliability Issue

Bad Practice

Suspicious

Exploitable

Abstract:
An attacker may control the format string argument to vsnprintf() at log.c line 442, allowing an attack much like a buffer
overflow.
Explanation:
Format string vulnerabilities occur when:
1. Data enters the application from an untrusted source.

2. The data is passed as the format string argument to a function like sprintf(), FormatMessageW(), or syslog().

Example 1: The following code copies a command line argument into a buffer using snprintf().

int main(int argc, char **argv){


char buf[128];
...
snprintf(buf,128,argv[1]);
}

This code allows an attacker to view the contents of the stack and write to the stack using a command line argument containing a
sequence of formatting directives. The attacker may read from the stack by providing more formatting directives, such as %x,
than the function takes as arguments to be formatted. (In this example, the function takes no arguments to be formatted.) By
using the %n formatting directive, the attacker may write to the stack, causing snprintf() to write the number of bytes output thus
far to the specified argument (rather than reading a value from the argument, which is the intended behavior). A sophisticated
version of this attack will use four staggered writes to completely control the value of a pointer on the stack.
Example 2: Certain implementations make more advanced attacks even easier by providing format directives that control the
location in memory to read from or write to. An example of these directives is shown in the following code, written for glibc:

printf("%d %d %1$d %1$d\n", 5, 9);

This code produces the following output:

5955

It is also possible to use half-writes (%hn) to accurately control arbitrary DWORDS in memory, which greatly reduces the
complexity needed to execute an attack that would otherwise require four staggered writes, such as the one mentioned in
Example 1.
Example 3: Simple format string vulnerabilities often result from seemingly innocuous shortcuts. The use of some such shortcuts
is so ingrained that programmers might not even realize that the function they are using expects a format string argument.
For example, the syslog() function is sometimes used as follows:

...
syslog(LOG_ERR, cmdBuf);
...

Because the second parameter to syslog() is a format string, any formatting directives included in cmdBuf are interpreted as
described in Example 1.

Copyright 2021 Micro Focus or one of its affiliates. Page 31 of 46


prueba1
The following code shows a correct usage of syslog():

...
syslog(LOG_ERR, "%s", cmdBuf);
...
Recommendations:
Whenever possible, pass static format strings to functions that accept a format string argument. If format strings must be
constructed dynamically, define a set of valid format strings and make selections from this safe set. Finally, always verify that
the number of formatting directives in the selected format string corresponds to the number of arguments to be formatted.

log.c, line 442 (Format String)


Fortify Priority: High Folder High
Kingdom: Input Validation and Representation
Abstract: An attacker may control the format string argument to vsnprintf() at log.c line 442,
allowing an attack much like a buffer overflow.
Source: file_io_ansi.c:103 fread()
101
102 clearerr((FILE*)fd);
103 bytes = fread(data, 1, *size, (FILE*)fd);
104 if (ferror((FILE*)fd)) {
105 *size = -1;

Sink: log.c:442 vsnprintf()


440
441 /* Print the whole message to the string log_buffer. */
442 print_len = pj_ansi_vsnprintf(pre, sizeof(log_buffer)-len, format,
443 marker);
444 if (print_len < 0) {

Copyright 2021 Micro Focus or one of its affiliates. Page 32 of 46


prueba1
Category: Race Condition: File System Access (3 Issues)

Number of Issues
0 1 2 3

<Unaudited>

Not an Issue

Reliability Issue

Bad Practice

Suspicious

Exploitable

Abstract:
The window of time between the call to <a href="location://pjlib/src/pj/file_access_unistd.c###49###0###0">pj_file_size()</a>
and <a href="location://pjlib/src/pj/file_io_ansi.c###26###0###0">pj_file_open()</a> can be exploited to launch a privilege
escalation attack.
Explanation:
File access race conditions, known as time-of-check, time-of-use (TOCTOU) race conditions, occur when:
1. The program checks a property of a file, referencing the file by name.
2. The program later performs a file system operation using the same filename and assumes that the previously-checked property
still holds.

Example 1: The following code is from a program installed setuid root. The program performs certain file operations on behalf of
non-privileged users, and uses access checks to ensure that it does not use its root privileges to perform operations that should
otherwise be unavailable the current user. The program uses the access() system call to check if the person running the program
has permission to access the specified file before it opens the file and performs the necessary operations.

if (!access(file,W_OK)) {
f = fopen(file,"w+");
operate(f);
...
}
else {
fprintf(stderr,"Unable to open file %s.\n",file);
}

The call to access() behaves as expected, and returns 0 if the user running the program has the necessary permissions to write to
the file, and -1 otherwise. However, because both access() and fopen() operate on filenames rather than on file handles, there is
no guarantee that the file variable still refers to the same file on disk when it is passed to fopen() that it did when it was passed to
access(). If an attacker replaces file after the call to access() with a symbolic link to a different file, the program will use its root
privileges to operate on the file even if it is a file that the attacker would otherwise be unable to modify. By tricking the program
into performing an operation that would otherwise be impermissible, the attacker has gained elevated privileges.
This type of vulnerability is not limited to programs with root privileges. If the application is capable of performing any
operation that the attacker would not otherwise be allowed perform, then it is a possible target.
The window of vulnerability for such an attack is the period of time between when the property is tested and when the file is
used. Even if the use immediately follows the check, modern operating systems offer no guarantee about the amount of code that
will be executed before the process yields the CPU. Attackers have a variety of techniques for expanding the length of the
window of opportunity in order to make exploits easier, but even with a small window, an exploit attempt can simply be repeated
over and over until it is successful.
Example 2: The following code creates a file and then changes the owner of the file.

fd = creat(FILE, 0644); /* Create file */


if (fd == -1)
return;
if (chown(FILE, UID, -1) < 0) { /* Change file owner */

Copyright 2021 Micro Focus or one of its affiliates. Page 33 of 46


prueba1
...
}

The code assumes that the file operated upon by the call to chown() is the same as the file created by the call to creat(), but that is
not necessarily the case. Since chown() operates on a file name and not on a file handle, an attacker may be able to replace the
file with a link to file the attacker does not own. The call to chown() would then give the attacker ownership of the linked file.
Recommendations:
To prevent file access race conditions, you must ensure that a file cannot be replaced or modified once the program has begun a
series of operations on it. Avoid functions that operate on filenames, since they are not guaranteed to refer to the same file on
disk outside of the scope of a single function call. Open the file first and then use functions that operate on file handles rather
than filenames.
The most effective way to check file access permissions is to drop to the privilege of the current user and attempt to open the file
with those reduced privileges. If the file open succeeds, additional access checks can be performed atomically using the resulting
file handle. If the file open fails, then the user does not have access to the file and the operation should be aborted. By dropping
to the user's privilege before attempting a series of file operations, the program cannot be easily tricked by changes to the
underlying file system.
Tips:
1. Be careful, a race condition can still exist after the file is opened if later operations depend on a property that was checked
before the file was opened. For example, if a stat structure is populated before a file is opened, and then a later decision about
whether to operate on the file is based on a value read from the stat structure, the file could be modified prior to being opened,
rendering the stat information stale. Always verify that file operations are performed on open file handles rather than filenames.
2. Some file system APIs do not have alternatives that operate on file handles. For example, there is no way to delete a file via a
file handle using standard C functions. Thus, some race conditions can only be avoided by placing the file in a directory path that
is completely under the control of the program. If this mitigation is taken, then otherwise unsafe system calls can be used safely.

wav_player.c, line 230 (Race Condition: File System Access)


Fortify Priority: High Folder High
Kingdom: Time and State
Abstract: The window of time between the call to <a
href="location://pjlib/src/pj/file_access_unistd.c###49###0###0">pj_file_size()</a>
and <a
href="location://pjlib/src/pj/file_io_ansi.c###26###0###0">pj_file_open()</a> can
be exploited to launch a privilege escalation attack.
Sink: wav_player.c:230 pj_file_open(?, filename, ?, ?) : Symbolic filename filename
used to operate on a file()
228
229 /* Open file. */
230 status = pj_file_open( pool, filename, PJ_O_RDONLY, &fport->fd);
231 if (status != PJ_SUCCESS)
232 return status;

Copyright 2021 Micro Focus or one of its affiliates. Page 34 of 46


prueba1
Category: Weak Encryption: Insecure Initialization Vector (3 Issues)

Number of Issues
0 1 2 3

<Unaudited>

Not an Issue

Reliability Issue

Bad Practice

Suspicious

Exploitable

Abstract:
Initialization vectors should be created using a cryptographic pseudorandom number generator.
Explanation:
Initialization vectors (IVs) should be created using a cryptographic pseudorandom number generator. Not using a random IV
makes the resulting ciphertext much more predictable and susceptible to a dictionary attack.
Example 1: The following code creates a non-random IV using a hardcoded string.

unsigned char * iv = "12345678";


EVP_EncryptInit_ex(&ctx, EVP_idea_cbc(), NULL, key, iv);
Recommendations:
Use an initialization vector (IV) of sufficient length with bytes from a suitable random data source.
Example 2: The following code creates a sufficiently random IV using /dev/random as an entropy source:
unsigned char * iv;
int fd = open("/dev/random", O_RDONLY);
if (fd != -1) {
(void) read(fd, (void *)&iv, ivlength);
(void) close(fd);
}
EVP_EncryptInit_ex(&ctx, EVP_idea_cbc(), NULL, key, iv);

aes_gcm_ossl.c, line 203 (Weak Encryption: Insecure Initialization Vector)


Fortify Priority: High Folder High
Kingdom: Security Features
Abstract: Initialization vectors should be created using a cryptographic pseudorandom number
generator.
Sink: aes_gcm_ossl.c:203 FunctionCall: EVP_CipherInit_ex()
201 }
202
203 if (!EVP_CipherInit_ex(c->ctx, evp, NULL, key, NULL, 0)) {
204 return (srtp_err_status_init_fail);
205 }

Copyright 2021 Micro Focus or one of its affiliates. Page 35 of 46


prueba1
Category: Password Management: Hardcoded Password (2 Issues)

Number of Issues
0 1 2

<Unaudited>

Not an Issue

Reliability Issue

Bad Practice

Suspicious

Exploitable

Abstract:
Hardcoded passwords may compromise system security in a way that cannot be easily remedied.
Explanation:
It is never a good idea to hardcode a password. Not only does hardcoding a password allow all of the project's developers to view
the password, it also makes fixing the problem extremely difficult. Once the code is in production, the password cannot be
changed without patching the software. If the account protected by the password is compromised, the owners of the system will
be forced to choose between security and availability.
Example: The following code uses a hardcoded password to connect to a database:

...
rc = SQLConnect(*hdbc, server, SQL_NTS, "scott",
SQL_NTS, "tiger", SQL_NTS);
...

This code will run successfully, but anyone who has access to it will have access to the password. Once the program has shipped,
there is likely no way to change the database user "scott" with a password of "tiger" unless the program is patched. An employee
with access to this information could use it to break into the system. Even worse, if attackers have access to the executable for
the application they can disassemble the code, which will contain the values of the passwords used.
Recommendations:
Passwords should never be hardcoded and should generally be obfuscated and managed in an external source. Storing passwords
in plaintext anywhere on the system allows anyone with sufficient permissions to read and potentially misuse the password.
Starting with Microsoft(R) Windows(R) 2000, Microsoft(R) provides Windows Data Protection Application Programming
Interface (DPAPI), which is an OS-level service that protects sensitive application data, such as passwords and private keys [1].
Tips:
1. When identifying null, empty, or hardcoded passwords, default rules only consider fields and variables that contain the word
password. However, the Fortify Custom Rules Editor provides the Password Management wizard that makes it easy to create
rules for detecting password management issues on custom-named fields and variables.

http_client.c, line 270 (Password Management: Hardcoded Password)


Fortify Priority: Critical Folder Critical
Kingdom: Security Features
Abstract: Hardcoded passwords may compromise system security in a way that cannot be easily
remedied.
Sink: http_client.c:270 FieldAccess: passwd()
268 int port;
269 const char *path;
270 } test_data[] =
271 {
272 /* Simple URL without '/' in the end */

Copyright 2021 Micro Focus or one of its affiliates. Page 36 of 46


prueba1
Category: Unreleased Resource: Synchronization (2 Issues)

Number of Issues
0 1 2

<Unaudited>

Not an Issue

Reliability Issue

Bad Practice

Suspicious

Exploitable

Abstract:
The function pj_thread_create() in os_core_unix.c fails to release a lock it acquires on line 610, which might lead to deadlock.
Explanation:
The program can potentially fail to release a system resource.
Resource leaks have at least two common causes:
- Error conditions and other exceptional circumstances.
- Confusion over which part of the program is responsible for releasing the resource.
Most unreleased resource issues result in general software reliability problems, but if an attacker can intentionally trigger a
resource leak, the attacker may be able to launch a denial of service by depleting the resource pool.
Example: The following function does destroy the condition variable it allocates if an error occurs. If the process is long-lived,
the process can run out of file handles.

int helper(char* fName)


{
int status;
...
pthread_cond_init (&count_threshold_cv, NULL);
pthread_mutex_init(&count_mutex, NULL);
status = perform_operation();
if (status) {
printf("%s", "cannot perform operation");
return OPERATION_FAIL;
}
pthread_mutex_destroy(&count_mutex);
pthread_cond_destroy(&count_threshold_cv);
return OPERATION_SUCCESS;
}
Recommendations:
Because resource leaks can be hard to track down, establish a set of resource management patterns and idioms for your software
and do not tolerate deviations from your conventions.
One good pattern for addressing the error handling mistake in this example is to use forward-reaching goto statements so that the
function has a single well-defined region for handling errors, as follows:

int helper(char* fName)


{
int status;
...
pthread_cond_init (&count_threshold_cv, NULL);

Copyright 2021 Micro Focus or one of its affiliates. Page 37 of 46


prueba1
pthread_mutex_init(&count_mutex, NULL);
status = perform_operation();
if (status) {
goto ERR;
}
pthread_mutex_destroy(&count_mutex);
pthread_cond_destroy(&count_threshold_cv);
return OPERATION_SUCCESS;
ERR:
printf("%s", "cannot perform operation");
pthread_mutex_destroy(&count_mutex);
pthread_cond_destroy(&count_threshold_cv);
return OPERATION_FAIL;
}

os_core_unix.c, line 610 (Unreleased Resource: Synchronization)


Fortify Priority: High Folder High
Kingdom: Code Quality
Abstract: The function pj_thread_create() in os_core_unix.c fails to release a lock it acquires on
line 610, which might lead to deadlock.
Sink: os_core_unix.c:610 pthread_attr_init((&thread_attr))
608
609 /* Init thread attributes */
610 pthread_attr_init(&thread_attr);
611
612 #if defined(PJ_THREAD_SET_STACK_SIZE) && PJ_THREAD_SET_STACK_SIZE!=0

Copyright 2021 Micro Focus or one of its affiliates. Page 38 of 46


prueba1
Category: Insecure Randomness: User-Controlled Seed (1 Issues)

Number of Issues
0 1

<Unaudited>

Not an Issue

Reliability Issue

Bad Practice

Suspicious

Exploitable

Abstract:
The function pj_srand() in rand.c is passed a tainted value for the seed. Functions that generate random or pseudorandom values,
which are passed a seed, should not be called with a tainted argument.
Explanation:
Functions that generate random or pseudorandom values (such as rand()), which are passed a seed (such as srand()); should not
be called with a tainted argument. Doing so allows an attacker to control the value used to seed the pseudorandom number
generator, and therefore predict the sequence of values (usually integers) produced by calls to the pseudorandom number
generator.

Recommendations:
Use a cryptographic PRNG seeded with hardware-based sources of randomness, such as ring oscillators, disk drive timing,
thermal noise, or radioactive decay, for instance, in Unix-like platforms, use /dev/random if you require a high entropy-seeded
pseudorandom number generator. Doing so makes the sequence of data produced by rand() and similar methods much harder to
predict.

rand.c, line 27 (Insecure Randomness: User-Controlled Seed)


Fortify Priority: High Folder High
Kingdom: Security Features
Abstract: The function pj_srand() in rand.c is passed a tainted value for the seed. Functions that
generate random or pseudorandom values, which are passed a seed, should not be
called with a tainted argument.
Source: sock_bsd.c:466 gethostname()
464 if (hostname.ptr == NULL) {
465 hostname.ptr = buf;
466 if (gethostname(buf, sizeof(buf)) != 0) {
467 hostname.ptr[0] = '\0';
468 hostname.slen = 0;

Sink: rand.c:27 srand()


25 {
26 PJ_CHECK_STACK();
27 platform_srand(seed);
28 }

Copyright 2021 Micro Focus or one of its affiliates. Page 39 of 46


prueba1
Category: Insecure Randomness: Weak Entropy Source (1 Issues)

Number of Issues
0 1

<Unaudited>

Not an Issue

Reliability Issue

Bad Practice

Suspicious

Exploitable

Abstract:
The random or pseudorandom number generator implemented by srand() relies on a weak entropy source.
Explanation:
The lack of a proper source of entropy for use by the random or pseudorandom number generator may lead to denial of service or
generation of predictable sequences of numbers. If the random or pseudorandom number generator uses the source of entropy
that runs out, the program may pause or even crash, leading to denial of service. Alternatively, the random or pseudorandom
number generator may produce predictable numbers. A weak source of random or pseudorandom numbers may lead to
vulnerabilities such as easy-to-guess temporary passwords, predictable cryptographic keys, session hijacking, and DNS spoofing.
Example 1: The following code uses the system clock as the entropy source:
...
srand (time(NULL));
r = (rand() % 6) + 1;
...

Since system clock generates predictable values, it is not a good source of entropy. Same goes for other non-hardware-based
sources of randomness, including system/input/output buffers, user/system/hardware/network serial numbers or addresses, as
well as user input.
Recommendations:
Avoid using non-hardware-based sources of randomness. Whenever possible, use hardware-based sources of randomess, such as
ring oscillators, disk drive timing, thermal noise, or radioactive decay.
On Unix-like platforms, the character special files /dev/random and /dev/urandom (present since Linux 1.3.30) provide an
interface to the kernel's random number generator. The random number generator gathers environmental noise from device
drivers and other sources into an entropy pool. When the entropy pool is empty, reads from /dev/random will block until
additional environmental noise is gathered. However, reads from /dev/urandom will not block waiting for more entropy. As a
result, if there is not sufficient entropy in the entropy pool, the returned values are theoretically vulnerable to a cryptographic
attack on the algorithms used by the driver. Always favor /dev/random over /dev/urandom.

rand.c, line 27 (Insecure Randomness: Weak Entropy Source)


Fortify Priority: High Folder High
Kingdom: Security Features
Abstract: The random or pseudorandom number generator implemented by srand() relies on a
weak entropy source.
Source: os_core_unix.c:281 getpid()
279 {
280 PJ_CHECK_STACK();
281 return getpid();
282 }

Sink: rand.c:27 srand()


25 {
26 PJ_CHECK_STACK();
27 platform_srand(seed);
28 }

Copyright 2021 Micro Focus or one of its affiliates. Page 40 of 46


prueba1
Category: Memory Leak (1 Issues)

Number of Issues
0 1

<Unaudited>

Not an Issue

Reliability Issue

Bad Practice

Suspicious

Exploitable

Abstract:
The function fromPj() in siptypes.cpp allocates memory on line 376 and fails to free it.
Explanation:
Memory leaks have two common and sometimes overlapping causes:
- Error conditions and other exceptional circumstances.
- Confusion over which part of the program is responsible for freeing the memory.
Most memory leaks result in general software reliability problems, but if an attacker can intentionally trigger a memory leak, the
attacker may be able to launch a denial of service attack (by crashing the program) or take advantage of other unexpected
program behavior resulting from a low memory condition [1].
Example 1: The following C function leaks a block of allocated memory if the call to read() fails to return the expected number
of bytes:

char* getBlock(int fd) {


char* buf = (char*) malloc(BLOCK_SIZE);
if (!buf) {
return NULL;
}
if (read(fd, buf, BLOCK_SIZE) != BLOCK_SIZE) {
return NULL;
}
return buf;
}
Recommendations:
Because memory leaks can be difficult to track down, you should establish a set of memory management patterns and idioms for
your software. Do not tolerate deviations from your conventions.
One good pattern for addressing the error handling mistake in the example is to use forward-reaching goto statements so that the
function has a single well-defined region for handling errors, as follows:

char* getBlock(int fd) {


char* buf = (char*) malloc(BLOCK_SIZE);
if (!buf) {
goto ERR;
}
if (read(fd, buf, BLOCK_SIZE) != BLOCK_SIZE) {
goto ERR;
}
return buf;
ERR:
if (buf) {

Copyright 2021 Micro Focus or one of its affiliates. Page 41 of 46


prueba1
free(buf);
}
return NULL;
}
Tips:
1. Managed pointer objects, such as C++ auto_ptr and Boost smart pointers, are used to ensure that referenced memory
allocations are freed. However, memory leaks can still occur when auto_ptrs or certain types of Boost smart pointers are used to
reference arrays, Boost array pointers reference individual objects, and the auto_ptr release method is used.

siptypes.cpp, line 376 (Memory Leak)


Fortify Priority: High Folder High
Kingdom: Code Quality
Abstract: The function fromPj() in siptypes.cpp allocates memory on line 376 and fails to free
it.
Sink: siptypes.cpp:376 buf = malloc(...)
374 do {
375 buf_size <<= 1;
376 buf = (char*)malloc(buf_size);
377 if (!buf)
378 PJSUA2_RAISE_ERROR(PJ_ENOMEM);

Copyright 2021 Micro Focus or one of its affiliates. Page 42 of 46


prueba1
Category: Often Misused: Authentication (1 Issues)

Number of Issues
0 1

<Unaudited>

Not an Issue

Reliability Issue

Bad Practice

Suspicious

Exploitable

Abstract:
The information returned by the call to gethostbyname() is not trustworthy. Attackers may spoof DNS entries. Do not rely on
DNS for security.
Explanation:
Many DNS servers are susceptible to spoofing attacks, so you should assume that your software will someday run in an
environment with a compromised DNS server. If attackers are allowed to make DNS updates (sometimes called DNS cache
poisoning), they can route your network traffic through their machines or make it appear as if their IP addresses are part of your
domain. Do not base the security of your system on DNS names.
Example 1: The following code uses a DNS lookup to determine whether or not an inbound request is from a trusted host. If an
attacker can poison the DNS cache, they can gain trusted status.

struct hostent *hp;


struct in_addr myaddr;
char* tHost = "trustme.trusty.com";
myaddr.s_addr=inet_addr(ip_addr_string);
hp = gethostbyaddr((char *) &myaddr,
sizeof(struct in_addr), AF_INET);
if (hp && !strncmp(hp->h_name, tHost, sizeof(tHost))) {
trusted = true;
} else {
trusted = false;
}

IP addresses are more reliable than DNS names, but they can also be spoofed. Attackers may easily forge the source IP address
of the packets they send, but response packets will return to the forged IP address. To see the response packets, the attacker has
to sniff the traffic between the victim machine and the forged IP address. In order to accomplish the required sniffing, attackers
typically attempt to locate themselves on the same subnet as the victim machine. Attackers may be able to circumvent this
requirement by using source routing, but source routing is disabled across much of the Internet today. In summary, IP address
verification can be a useful part of an authentication scheme, but it should not be the single factor required for authentication.
Recommendations:
You can increase confidence in a domain name lookup if you check to make sure that the host's forward and backward DNS
entries match. Attackers will not be able to spoof both the forward and the reverse DNS entries without controlling the
nameservers for the target domain. However, this is not a foolproof approach: attackers may be able to convince the domain
registrar to turn over the domain to a malicious nameserver. Basing authentication on DNS entries is simply a risky practice.
While no authentication mechanism is foolproof, there are better alternatives than host-based authentication. Password systems
offer decent security, but are susceptible to bad password choices, insecure password transmission, and bad password
management. A cryptographic scheme like SSL is worth considering, but such schemes are often so complex that they bring with
them the risk of significant implementation errors, and key material can always be stolen. In many situations, multi-factor
authentication including a physical token offers the most security available at a reasonable price.
Tips:
1. Check how the DNS information is being used. In addition to considering whether or not the program's authentication
mechanisms can be defeated, consider how DNS spoofing can be used in a social engineering attack. For example, if attackers
can make it appear that a posting came from an internal machine, can they gain credibility?

Copyright 2021 Micro Focus or one of its affiliates. Page 43 of 46


prueba1
addr_resolv_sock.c, line 45 (Often Misused: Authentication)
Fortify Priority: High Folder High
Kingdom: API Abuse
Abstract: The information returned by the call to gethostbyname() is not trustworthy. Attackers
may spoof DNS entries. Do not rely on DNS for security.
Sink: addr_resolv_sock.c:45 gethostbyname()
43 copy[ hostname->slen ] = '\0';
44
45 he = gethostbyname(copy);
46 if (!he) {
47 return PJ_ERESOLVE;

Copyright 2021 Micro Focus or one of its affiliates. Page 44 of 46


prueba1

Issue Count by Category


Issues by Category
Buffer Overflow 1053
Buffer Overflow: Format String 422
Poor Style: Value Never Read 339
Dead Code 163
Type Mismatch: Signed to Unsigned 151
Password Management: Password in Comment 98
Path Manipulation 75
Dangerous Function: strcpy() 70
String Termination Error 46
Use After Free 36
Redundant Null Check 31
Null Dereference 28
Poor Style: Variable Never Used 25
Poor Style: Redundant Initialization 23
Format String 22
Illegal Pointer Value 21
Password Management: Empty Password 21
Privacy Violation 21
Unchecked Return Value 20
Integer Overflow 17
System Information Leak: Internal 16
Denial of Service 15
Missing Check against Null 14
Resource Injection 13
Obsolete 11
Uninitialized Variable 11
Buffer Overflow: Off-by-One 5
Heap Inspection 5
Insecure Randomness 5
Out-of-Bounds Read 5
Insecure Transport: Weak SSL Protocol 4
Race Condition: File System Access 3
Weak Encryption: Insecure Initialization Vector 3
Password Management: Hardcoded Password 2
Unreleased Resource: Synchronization 2
Insecure Compiler Optimization 1
Insecure Randomness: User-Controlled Seed 1
Insecure Randomness: Weak Entropy Source 1
Memory Leak 1
Often Misused: Authentication 1
Weak Cryptographic Hash 1

Copyright 2021 Micro Focus or one of its affiliates. Page 45 of 46


prueba1

Issue Breakdown by Analysis


Issues by Analysis

Exploitable: (1,
0%)

<none>: (2,801,
100%)

Exploitable <none>

Copyright 2021 Micro Focus or one of its affiliates. Page 46 of 46

You might also like