mal-2026-4821
Vulnerability from ossf_malicious_packages
-= Per source details. Do not edit below this line.=-
Source: amazon-inspector (6db77876bf3b13e55750748761841f7ab77f17bd951bdc1c749e1e56d4416d7e)
pywingui 6.0.1 advertises itself as a Win32 UI automation framework but ships only Nuitka-compiled cp311-win32.pyd binaries (the 4.py files are trivial re-exports). Two undisclosed behaviors are embedded in those binaries:
1) Silent relay of OCR data: ui/ocr_utils.cp311-win32.pyd embeds a hardcoded Nanonets bearer token ('Bearer bc65bc5e-1ba4-4284-96ec-3320920b32cd') and an OCR.space API key ('K83196308188957'), and config sets DEFAULT_OCR_PROVIDER='nanonets'. The OCR helpers (read_form_smart and related) upload caller-supplied window screenshots to https://extraction-api.nanonets.com/api/v1/extract/sync and https://api.ocr.space/Parse/Image using the author's own accounts, so any image the consumer OCRs through the documented API is delivered to the author's Nanonets dashboard. The README (which emphasizes Progress OpenEdge ERP automation) does not disclose this. The hardcoded third-party API keys are also redistributed to every installer.
2) Undisclosed phone-home / kill-switch: core/runtime_guard.cp311-win32.pyd builds a machine fingerprint from socket.gethostname() + getpass.getuser() hashed with SHA-256 and POSTs {action:'check', app:'PYWINGUI', machine_id} to a hardcoded Google Apps Script endpoint (script.google.com/macros/s/AKfycbw_wxvGol9xUpiwvIJYSvV488bUzKt5-2n6Q9mw8_hSG9N22zUUce2hw0mbUgB4lDqB/exec). RuntimeGuard().validate() is invoked from Engine.init, which is constructed by the AppContext every consumer instantiates, so the beacon fires on normal first use. The result is cached Fernet-encrypted under ~/.pywingui/. README mentions no licensing or telemetry, and the server can deny access (kill-switch).
The compiled-only distribution hides both behaviors from source audit. This satisfies the silent-relay class (caller-supplied OCR data flowing to author-controlled SaaS via author credentials) and adds an undisclosed identifier-beacon with remote-disable capability.
{
"affected": [
{
"database_specific": {
"cwes": [
{
"cweId": "CWE-506",
"description": "The product contains code that appears to be malicious in nature.",
"name": "Embedded Malicious Code"
},
{
"cweId": "CWE-506",
"description": "The product contains code that appears to be malicious in nature.",
"name": "Embedded Malicious Code"
}
],
"indicators": {
"evidence_files": [
{
"path": "pywingui/core/runtime_guard.cp311-win32.pyd",
"sha256": "4831a42966744dd917b614204d742218f44755999157bc6445d66b1a429b70e2",
"tlsh": "9f146c21b74a30bde4ca27f937df4afa1cb1614c072790c3a6d50d9ad221ae3573a58d"
},
{
"path": "pywingui/ui/ocr_utils.cp311-win32.pyd",
"sha256": "993d09706c36b6b58af5801fe9e4364e6d9bda48d13f28e0fce9e72c2c82399d",
"tlsh": "21146c19a24a707dd4ca23f677eb16f71db2a14a473750c3b6c80d8ac311ae36b3519d"
}
],
"package_integrity": [
{
"filename": "pywingui-6.0.0-cp311-cp311-win32.whl",
"hashes": {
"blake2b_256": "9331728dc7e8e1191123944697ba9cdb8cdfda432effea43c5eab0518c843955",
"md5": "16b1d7aa5e12e89667ab18b85e82c756",
"sha256": "a2d766d7717bc006bb0740e8c09a312e15a10434af708d1e5ca434d63c9778d0"
}
},
{
"filename": "pywingui-6.0.0-cp311-cp311-win_amd64.whl",
"hashes": {
"blake2b_256": "9084b6e8ff2c8a733d90d519ae1b5ac626a03799295b50d2e1c0a43c7d747e82",
"md5": "41aee266f2beb095d70f937f24e7ae0a",
"sha256": "0f21522248ca8baaa8bd816d92866f2532b92e1b06438677ffa8c43052b5283e"
}
},
{
"filename": "pywingui-6.0.0-cp312-cp312-win32.whl",
"hashes": {
"blake2b_256": "115b2b8929714e0bb1b3ad2d846e7af565fd096bfaec88724228ed2679075bd0",
"md5": "322c88f220fee32dbfa7b8d5a762b949",
"sha256": "ed7e8c3acd0fbcc8f2b1a6487006a6572adc84354ce6a3e9a921b51735d3bb51"
}
},
{
"filename": "pywingui-6.0.0-cp312-cp312-win_amd64.whl",
"hashes": {
"blake2b_256": "4e58bc040841e2c3484e27ead1a6e7eda83c3bdded489fd848a3ab7a8ce7e323",
"md5": "85a7206ac0f11890d3a5688511960c3e",
"sha256": "282ad59422641cdcd4ca06ecdbd6e9b938429c775463f161aca0b5222f2172ab"
}
},
{
"filename": "pywingui-6.0.0-cp313-cp313-win32.whl",
"hashes": {
"blake2b_256": "950098eeb89fb123e78591acbe933207caba44bbe405246ccd1ace24ee8ca01f",
"md5": "4aad9b47f9145c4f5309146f7b0a9825",
"sha256": "c4b05effe877aad6003e8a2b216dfeec5fa6041e0236ae66a4a91224e4a35680"
}
},
{
"filename": "pywingui-6.0.0-cp313-cp313-win_amd64.whl",
"hashes": {
"blake2b_256": "867045b5be21d8decf2b2c53a3e89b6972f6bf02eed707d94d7e315f4ac7f9ff",
"md5": "01e2b5ec07f65b8671f4f9484f38f0a8",
"sha256": "0a48fa82e59a2e45afbb41251033f5a8bf631fc9aa17e50a5869c8adb39de008"
}
}
]
}
},
"package": {
"ecosystem": "PyPI",
"name": "pywingui"
},
"versions": [
"6.0.0",
"6.0.1"
]
}
],
"credits": [
{
"contact": [
"actran@amazon.com"
],
"name": "Amazon Inspector",
"type": "FINDER"
}
],
"database_specific": {
"malicious-packages-origins": [
{
"id": "IN-MAL-2026-004920",
"import_time": "2026-05-26T15:07:43.101013624Z",
"modified_time": "2026-05-26T14:39:03Z",
"sha256": "8e7061d7b21cda355cda7d210c2e2ddee7b556762417b0463905367d359d1c03",
"source": "amazon-inspector",
"versions": [
"6.0.0"
]
},
{
"id": "IN-MAL-2026-004926",
"import_time": "2026-05-26T16:47:31.475265594Z",
"modified_time": "2026-05-26T15:10:20Z",
"sha256": "6db77876bf3b13e55750748761841f7ab77f17bd951bdc1c749e1e56d4416d7e",
"source": "amazon-inspector",
"versions": [
"6.0.1"
]
}
]
},
"details": "\n---\n_-= Per source details. Do not edit below this line.=-_\n\n## Source: amazon-inspector (6db77876bf3b13e55750748761841f7ab77f17bd951bdc1c749e1e56d4416d7e)\npywingui 6.0.1 advertises itself as a Win32 UI automation framework but ships only Nuitka-compiled cp311-win32.pyd binaries (the 4.py files are trivial re-exports). Two undisclosed behaviors are embedded in those binaries:\n\n1) Silent relay of OCR data: ui/ocr_utils.cp311-win32.pyd embeds a hardcoded Nanonets bearer token (\u0027Bearer bc65bc5e-1ba4-4284-96ec-3320920b32cd\u0027) and an OCR.space API key (\u0027K83196308188957\u0027), and config sets DEFAULT_OCR_PROVIDER=\u0027nanonets\u0027. The OCR helpers (read_form_smart and related) upload caller-supplied window screenshots to https://extraction-api.nanonets.com/api/v1/extract/sync and https://api.ocr.space/Parse/Image using the author\u0027s own accounts, so any image the consumer OCRs through the documented API is delivered to the author\u0027s Nanonets dashboard. The README (which emphasizes Progress OpenEdge ERP automation) does not disclose this. The hardcoded third-party API keys are also redistributed to every installer.\n\n2) Undisclosed phone-home / kill-switch: core/runtime_guard.cp311-win32.pyd builds a machine fingerprint from socket.gethostname() + getpass.getuser() hashed with SHA-256 and POSTs {action:\u0027check\u0027, app:\u0027PYWINGUI\u0027, machine_id} to a hardcoded Google Apps Script endpoint (script.google.com/macros/s/AKfycbw_wxvGol9xUpiwvIJYSvV488bUzKt5-2n6Q9mw8_hSG9N22zUUce2hw0mbUgB4lDqB/exec). RuntimeGuard().validate() is invoked from Engine.__init__, which is constructed by the AppContext every consumer instantiates, so the beacon fires on normal first use. The result is cached Fernet-encrypted under ~/.pywingui/. README mentions no licensing or telemetry, and the server can deny access (kill-switch).\n\nThe compiled-only distribution hides both behaviors from source audit. This satisfies the silent-relay class (caller-supplied OCR data flowing to author-controlled SaaS via author credentials) and adds an undisclosed identifier-beacon with remote-disable capability.\n",
"id": "MAL-2026-4821",
"modified": "2026-05-26T16:49:26Z",
"published": "2026-05-26T14:39:03Z",
"references": [
{
"type": "PACKAGE",
"url": "https://pypi.org/project/pywingui/6.0.0/"
},
{
"type": "PACKAGE",
"url": "https://pypi.org/project/pywingui/6.0.1/"
}
],
"schema_version": "1.7.4",
"summary": "Malicious code in pywingui (PyPI)"
}
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.