1 #ifndef SRC_NODE_REVERT_H_
2 #define SRC_NODE_REVERT_H_
3
4 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5
6 #include "node.h"
7
8 /**
9 * Note that it is expected for this list to vary across specific LTS and
10 * Stable versions! Only CVE's whose fixes require *breaking* changes within
11 * a given LTS or Stable may be added to this list, and only with TSC
12 * consensus.
13 *
14 * For *master* this list should always be empty!
15 **/
16 namespace node {
17
18 #define SECURITY_REVERSIONS(XX) \
19 XX(CVE_2021_44531, "CVE-2021-44531", "Cert Verif Bypass via URI SAN") \
20 XX(CVE_2021_44532, "CVE-2021-44532", "Cert Verif Bypass via Str Inject") \
21 // XX(CVE_2016_PEND, "CVE-2016-PEND", "Vulnerability Title")
22
23 enum reversion {
24 #define V(code, ...) SECURITY_REVERT_##code,
25 SECURITY_REVERSIONS(V)
26 #undef V
27 };
28
29 namespace per_process {
30 extern unsigned int reverted_cve;
31 }
32
33 #ifdef _MSC_VER
34 #pragma warning(push)
35 // MSVC C4065: switch statement contains 'default' but no 'case' labels
36 #pragma warning(disable : 4065)
37 #endif
38
RevertMessage(const reversion cve)39 inline const char* RevertMessage(const reversion cve) {
40 #define V(code, label, msg) case SECURITY_REVERT_##code: return label ": " msg;
41 switch (cve) {
42 SECURITY_REVERSIONS(V)
43 default:
44 return "Unknown";
45 }
46 #undef V
47 }
48
49 #ifdef _MSC_VER
50 #pragma warning(pop)
51 #endif
52
Revert(const reversion cve)53 inline void Revert(const reversion cve) {
54 per_process::reverted_cve |= 1 << cve;
55 printf("SECURITY WARNING: Reverting %s\n", RevertMessage(cve));
56 }
57
Revert(const char * cve,std::string * error)58 inline void Revert(const char* cve, std::string* error) {
59 #define V(code, label, _) \
60 if (strcmp(cve, label) == 0) return Revert(SECURITY_REVERT_##code);
61 SECURITY_REVERSIONS(V)
62 #undef V
63 *error = "Error: Attempt to revert an unknown CVE [";
64 *error += cve;
65 *error += ']';
66 }
67
IsReverted(const reversion cve)68 inline bool IsReverted(const reversion cve) {
69 return per_process::reverted_cve & (1 << cve);
70 }
71
IsReverted(const char * cve)72 inline bool IsReverted(const char* cve) {
73 #define V(code, label, _) \
74 if (strcmp(cve, label) == 0) return IsReverted(SECURITY_REVERT_##code);
75 SECURITY_REVERSIONS(V)
76 return false;
77 #undef V
78 }
79
80 } // namespace node
81
82 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
83
84 #endif // SRC_NODE_REVERT_H_
85