node/src/node_revert.h
Ben Noordhuis 9095c914ed src: disallow direct .bat and .cmd file spawning
An undocumented feature of the Win32 CreateProcess API allows spawning
batch files directly but is potentially insecure because arguments are
not escaped (and sometimes cannot be unambiguously escaped), hence why
they are refused starting today.

PR-URL: https://github.com/nodejs-private/node-private/pull/562
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
CVE-ID: CVE-2024-27980
2024-04-10 09:18:30 -03:00

83 lines
2.2 KiB
C++

#ifndef SRC_NODE_REVERT_H_
#define SRC_NODE_REVERT_H_
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
#include "node.h"
/**
* Note that it is expected for this list to vary across specific LTS and
* Stable versions! Only CVE's whose fixes require *breaking* changes within
* a given LTS or Stable may be added to this list, and only with TSC
* consensus.
*
* For *master* this list should always be empty!
**/
namespace node {
#define SECURITY_REVERSIONS(XX) \
XX(CVE_2023_46809, "CVE-2023-46809", "Marvin attack on PKCS#1 padding") \
XX(CVE_2024_27980, "CVE-2024-27980", "Unsafe Windows batch file execution")
enum reversion {
#define V(code, ...) SECURITY_REVERT_##code,
SECURITY_REVERSIONS(V)
#undef V
};
namespace per_process {
extern unsigned int reverted_cve;
}
#ifdef _MSC_VER
#pragma warning(push)
// MSVC C4065: switch statement contains 'default' but no 'case' labels
#pragma warning(disable : 4065)
#endif
inline const char* RevertMessage(const reversion cve) {
#define V(code, label, msg) case SECURITY_REVERT_##code: return label ": " msg;
switch (cve) {
SECURITY_REVERSIONS(V)
default:
return "Unknown";
}
#undef V
}
#ifdef _MSC_VER
#pragma warning(pop)
#endif
inline void Revert(const reversion cve) {
per_process::reverted_cve |= 1 << cve;
printf("SECURITY WARNING: Reverting %s\n", RevertMessage(cve));
}
inline void Revert(const char* cve, std::string* error) {
#define V(code, label, _) \
if (strcmp(cve, label) == 0) return Revert(SECURITY_REVERT_##code);
SECURITY_REVERSIONS(V)
#undef V
*error = "Error: Attempt to revert an unknown CVE [";
*error += cve;
*error += ']';
}
inline bool IsReverted(const reversion cve) {
return per_process::reverted_cve & (1 << cve);
}
inline bool IsReverted(const char* cve) {
#define V(code, label, _) \
if (strcmp(cve, label) == 0) return IsReverted(SECURITY_REVERT_##code);
SECURITY_REVERSIONS(V)
return false;
#undef V
}
} // namespace node
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
#endif // SRC_NODE_REVERT_H_