Skip to main content
๐Ÿ“œ WAYPOINT LESSON

Reflection and security

โญโญโญ advancedโณ 12 min read๐Ÿ“ Lesson 178 of 265

Why reflection defeats static analysis, what it leaks, and the discipline that keeps it safe.

Reflection and security

Reflection is power with a bill. Three duties in modern .NET:

1. It bypasses static guarantees. A private member is a compile-time promise; BindingFlags.NonPublic breaks it silently. Style says: never reflect into private of types you don't own โ€” you are coupling to implementation details that any refactor will break, and (on trimmed or AOT-compiled apps, Module 19) members unused by "real" code may not exist at runtime at all.

2. It is a deserialization hazard. Activator.CreateInstance(type) where type comes from user input is arbitrary construction โ€” the class-history of .NET vulnerabilities includes exactly this. Whitelist: map trusted names to types in your own assembly; never Type.GetType user strings without validation.

3. Trim/AOT compatibility is now a correctness issue. Every GetProperty("Name") with a literal is invisible to the IL trimmer unless you annotate [DynamicallyAccessedMembers] or use nameof. In this course's sandbox (full framework, no trimming) reflection runs fine โ€” but code you ship to NativeAOT will not, so keep reflection at the edges of your design and prefer source generation (Module 8) for the hot middle.