|
1 | 1 | <!DOCTYPE qhelp PUBLIC |
2 | | - "-//Semmle//qhelp//EN" |
3 | | - "qhelp.dtd"> |
| 2 | +"-//Semmle//qhelp//EN" |
| 3 | +"qhelp.dtd"> |
4 | 4 | <qhelp> |
5 | 5 |
|
6 | | - <overview> |
| 6 | +<overview> |
7 | 7 |
|
8 | | - </overview> |
| 8 | + <p> |
9 | 9 |
|
10 | | - <recommendation> |
| 10 | + Servers handle requests from clients until terminated |
| 11 | + deliberately by a server administrator. A client request that results |
| 12 | + in an uncaught server-side exception causes the current server |
| 13 | + response generation to fail, and should not have an effect on |
| 14 | + subsequent client requests. |
11 | 15 |
|
12 | | - </recommendation> |
| 16 | + </p> |
13 | 17 |
|
14 | | - <example> |
| 18 | + <p> |
15 | 19 |
|
16 | | - </example> |
| 20 | + Under some circumstances, uncaught exceptions can however |
| 21 | + cause the entire server to terminate abruptly. Such a behavior is |
| 22 | + highly undesirable, especially if it gives malicious users the ability |
| 23 | + to turn off the server at will, which is an efficient |
| 24 | + denial-of-service attack. |
17 | 25 |
|
18 | | - <references> |
| 26 | + </p> |
19 | 27 |
|
20 | | - </references> |
| 28 | +</overview> |
| 29 | + |
| 30 | +<recommendation> |
| 31 | + |
| 32 | + <p> |
| 33 | + |
| 34 | + Ensure that the processing of client requests can not cause |
| 35 | + uncaught exceptions to terminate the entire server abruptly. |
| 36 | + |
| 37 | + </p> |
| 38 | + |
| 39 | +</recommendation> |
| 40 | + |
| 41 | +<example> |
| 42 | + |
| 43 | + <p> |
| 44 | + |
| 45 | + The following server implementation checks if a client-provided |
| 46 | + file path is valid and throws an exception if the check fails. It can |
| 47 | + be seen that the exception is uncaught, and it is therefore reasonable to |
| 48 | + expect the server to respond with an error response to client requests |
| 49 | + that cause the check to fail. |
| 50 | + |
| 51 | + But since the exception is uncaught in the context of an |
| 52 | + asynchronous callback invocation (<code>fs.access(...)</code>), the |
| 53 | + entire server will terminate instead. |
| 54 | + |
| 55 | + </p> |
| 56 | + |
| 57 | + <sample src="examples/server-crash.BAD.js"/> |
| 58 | + |
| 59 | + <p> |
| 60 | + To remedy this, the server can catch the exception explicitly with |
| 61 | + a <code>try/catch</code> block, and generate an appropriate error |
| 62 | + response instead: |
| 63 | + |
| 64 | + </p> |
| 65 | + |
| 66 | + <sample src="examples/server-crash.GOOD-A.js"/> |
| 67 | + |
| 68 | + <p> |
| 69 | + |
| 70 | + An alternative is to use an <code>async</code> and |
| 71 | + <code>await</code> for the asynchronous behavior, since the server |
| 72 | + will then print warning messages about uncaught exceptions instead of |
| 73 | + terminating, unless the server was started with the commandline option |
| 74 | + <code>--unhandled-rejections=strict</code>: |
| 75 | + |
| 76 | + </p> |
| 77 | + |
| 78 | + <sample src="examples/server-crash.GOOD-B.js"/> |
| 79 | + |
| 80 | +</example> |
| 81 | + |
| 82 | +<references> |
| 83 | + |
| 84 | +</references> |
21 | 85 |
|
22 | 86 | </qhelp> |
0 commit comments