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
83 lines
2.2 KiB
C++
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_
|