Windows Defender Severe alert from Codex-generated pwsh reflection command
What version of the Codex App are you using?
26.527.31326
What subscription do you have?
ChatGPT Plus
What platform is your computer?
Microsoft Windows NT 10.0.26200.0 x64
---
What issue are you seeing?
On Windows, Codex generated and attempted to run a PowerShell command that Windows Defender blocked as a Severe threat.
Windows Defender alert:
Detected: Trojan:Win32/Steanoz.Z!MTB
Severity: Severe
Status: Removed
Message: A threat or app was removed from this device.
````
Windows Security versions:
```text
Windows Security Application Version: 1000.29573.0.1002
Windows Security Service Version: 10.0.29573.1002-0
Antimalware Client Version: 4.18.26050.15
Engine Version: 1.1.26050.11
Antivirus Version: 1.451.249.0
Antispyware Version: 1.451.249.0
The issue appears to be Codex's generated PowerShell execution strategy rather than a user-authored script or downloaded binary.
The blocked command used this pattern:
pwsh.exe -Command[Console]::OutputEncoding = UTF8Resolve-Pathto a built .NET DLL[System.Reflection.Assembly]::LoadFrom(...)GetType(...)GetMethod(... BindingFlags NonPublic, Static)Invoke(...)- large inline JSON here-string
This command shape is likely what triggered Defender, because it combines PowerShell, dynamic assembly loading, reflection, non-public method invocation, and an inline payload.
I do not have a file sample to attach because Defender removed/quarantined the affected item before I could preserve it. The actionable issue is that Codex chose a PowerShell reflection-based execution path on Windows for routine .NET validation.
Command shown by Defender / generated by Codex, with project identifiers redacted:
C:\Program Files\WindowsApps\Microsoft.PowerShell_7.6.2.0_x64__8wekyb3d8bbwe\pwsh.exe -Command [Console]::OutputEncoding=[System.Text.Encoding]::UTF8;
$assemblyPath = (Resolve-Path '[REDACTED_PROJECT]\bin\Release\net10.0\linux-x64\[REDACTED_ASSEMBLY].dll').Path
$assembly = [System.Reflection.Assembly]::LoadFrom($assemblyPath)
$type = $assembly.GetType('[REDACTED_NAMESPACE].Evaluation.PilotCallReviewService')
$method = $type.GetMethod('ParseReviewWithReason', [System.Reflection.BindingFlags] 'NonPublic, Static')
$json = @'
{
"verdict": {
"result": "not_ok",
"severity": "medium",
"summary": " The caller was transferred before the order was completed. "
},
"outcome": {
"resolution": "transfer_other",
"furthest_stage": "order_taking",
"order_match": "incomplete",
"caller_frustration_detected": false
},
"diagnosis": {
"customer_impact": "incomplete_order",
"primary_failure_mode": "escalation_decision",
"root_cause_guess": "tooling",
"investigation_tags": ["unnecessary_escalation", "unnecessary_escalation"],
"uncertainty_reason": "none",
"evidence_sources": ["transcript", "terminal_tool", "transcript"]
},
"operator_action": {
"primary_action": "review_call",
"issue": " Order was not submitted. ",
"evidence": " The terminal tool escalated the call. ",
"next_step": " Review why the assistant escalated. "
}
}
'@
$result = $method.Invoke($null, @($json))
$review = $result.GetType().GetProperty('Review').GetValue($result)
$verdict = $review.GetType().GetProperty('Verdict').GetValue($review)
$diagnosis = $review.GetType().GetProperty('Diagnosis').GetValue($review)
$operatorAction = $review.GetType().GetProperty('OperatorAction').GetValue($review)
$resultValue = $verdict.GetType().GetProperty('Result').GetValue($verdict)
$summary = $verdict.GetType().GetProperty('Summary').GetValue($verdict)
$tags = $diagnosis.GetType().GetProperty('InvestigationTags').GetValue($diagnosis)
$evidenceSources = $diagnosis.GetType().GetProperty('EvidenceSources').GetValue($diagnosis)
$issue = $operatorAction.GetType().GetProperty('Issue').GetValue($operatorAction)
"result=$resultValue; summary=$summary; tags=$($tags.Count); evidenceSources=$($evidenceSources.Count); issue=$issue"
---
What steps can reproduce the bug?
I cannot provide a fully deterministic reproduction because this depends on Codex choosing this execution strategy, but the observed flow was:
- Use Codex App on Windows.
- Work in a .NET project.
- Ask Codex to validate behavior of an internal/non-public static .NET method.
- Codex generated a PowerShell command that:
- loaded a built DLL using
[System.Reflection.Assembly]::LoadFrom(...) - looked up a type using
GetType(...) - looked up a non-public static method using
GetMethod(... BindingFlags NonPublic, Static) - invoked it using
MethodInfo.Invoke(...) - passed a large JSON payload through a PowerShell here-string
- Windows Defender immediately reported a Severe detection:
Trojan:Win32/Steanoz.Z!MTB
- Defender removed/quarantined the affected item.
Session ID:
019e8ead-ab84-7ba3-9281-dad3789fd523
Token limit usage:
N/A
Context window usage:
N/A
Important: I did not ask Codex to execute suspicious PowerShell. Codex chose this command shape as a way to test .NET behavior.
---
What is the expected behavior?
Codex should avoid generating Windows PowerShell commands that resemble fileless/scripted malware execution when safer alternatives exist.
In particular, Codex should avoid using pwsh.exe with:
Assembly.LoadFrom(...)- reflection into non-public methods
BindingFlags.NonPublicMethodInfo.Invoke(...)- large inline here-string payloads
Expected safer alternatives:
- use
dotnet test - generate a temporary C# test harness and run it with
dotnet run - add or run an explicit unit test
- invoke public CLI/test entry points
- ask for explicit confirmation before using reflection-heavy PowerShell on Windows
- avoid large inline PowerShell here-strings when passing test data
The expected behavior is that Codex tests .NET code through normal .NET tooling instead of generating PowerShell commands that Windows Defender classifies as Severe malware-like behavior.
---
Additional information
I believe this should be treated as a Codex command-generation issue rather than only as a Microsoft Defender file false-positive issue.
Reasoning:
- Defender appears to have reacted to the
pwsh.exeexecution path and/or the reflected .NET invocation pattern. - The suspicious behavior was dynamic assembly loading plus reflection-based invocation.
- I do not have a persistent suspicious file to submit to Microsoft.
- The triggering command was generated by Codex during a normal development workflow.
- Codex was operating with full access enabled.
Please advise whether Codex on Windows can avoid this execution strategy and prefer a safer .NET-native test path.
Screenshots attached:
<img width="317" height="492" alt="Image" src="https://github.com/user-attachments/assets/f6b79e9a-8823-4958-b7c1-4d0b4fb3eeac" />
<img width="505" height="264" alt="Image" src="https://github.com/user-attachments/assets/dc581fb5-d236-4f5e-9eb5-9732720869bc" />
Environment details:
Codex surface used: Codex App
Codex access mode: Full access
OS: Windows
PowerShell package shown in Defender command line:
Microsoft.PowerShell_7.6.2.0_x64__8wekyb3d8bbwe
Codex self-report after the Defender alert
After the alert, I asked Codex what it had executed. Codex reported that it used pwsh.exe on Windows with PowerShell 7.6.2 and .NET 10.0.8.
Codex stated that the loaded assembly was a locally built project DLL produced by:
dotnet build [REDACTED_PROJECT]\[REDACTED_PROJECT].csproj -c Release
````
Codex reported that its main command pattern was reflection-based schema inspection against the compiled app assembly:
```pwsh
$assemblyPath = (Resolve-Path '[REDACTED_PROJECT]\bin\Release\net10.0\linux-x64\[REDACTED_ASSEMBLY].dll').Path
$assembly = [System.Reflection.Assembly]::LoadFrom($assemblyPath)
$type = $assembly.GetType('[REDACTED_NAMESPACE].Evaluation.PilotCallReviewService')
$field = $type.GetField('ReviewSchema', [System.Reflection.BindingFlags] 'NonPublic, Static')
$schema = $field.GetValue($null)
$schema.GetRawText()
Codex also reported attempting parse smoke checks with this pattern:
$type = $assembly.GetType('[REDACTED_NAMESPACE].Evaluation.PilotCallReviewService')
$method = $type.GetMethod('ParseReviewWithReason', [System.Reflection.BindingFlags] 'NonPublic, Static')
$result = $method.Invoke($null, @($json))
Codex reported that the purpose was to inspect generated JSON schema and smoke-test JSON parsing behavior in the local compiled assembly.
Codex stated that it did not:
- download a payload
- run encoded PowerShell
- disable Defender
- intentionally write outside the repository
- start the ASP.NET app
- call
Program.cs - connect to the database
This self-report supports the theory that Defender reacted to the PowerShell execution pattern itself: pwsh.exe + Assembly.LoadFrom(...) + reflection + BindingFlags.NonPublic, Static + invoking or reading non-public members from a locally built DLL.
I understand this self-report is not independent proof of safety. I am including it to clarify what Codex says it generated and why this appears to be a Codex command-generation issue on Windows.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗