Key Takeaways

  • Comprehensive vulnerability mapping: Reflection in Java and C# introduces a flexible but dangerous pathway for dynamic code execution. Without careful input validation, it can lead to remote code execution, privilege escalation, or data exfiltration.
  • Proactive mitigation strategies: From implementing class whitelisting to securing deserialization pathways and disabling reflective access to private members, proactive defenses significantly reduce risk.
  • Security-by-design principles: Reflection should never bypass the fundamental tenets of application security. Developers must integrate secure coding practices from the ground up to ensure long-term resilience.

As the software development ecosystem leans into dynamic architectures and runtime flexibility, reflection has become an integral part of modern programming in Java, C#, JavaScript, Python, and related languages. Reflection allows developers to write more flexible and extensible applications by inspecting types, creating instances, and invoking methods at runtime. To this end, reflection is used in modern programming languages as an integral part of deserialization – classes are loaded, objects instantiated, and then variables set using reflection (à la Apache Struts and Spring; ASP.NET and .NET Core) – and is a vital part of how web frameworks, regardless of the content type or the data being in the body, headers, or address, accept user input.

While reflection allows powerful programming constructs, it comes with tremendous computational and memory costs. Just as important, though, are the threat vectors inherent to reflection, some of which our whitepaper, A Primer on Insecure Reflection Practices in Java and C# Applications: Mapping Vulnerabilities and Proposing Effective Mitigation Strategies, touch upon that, when left unchecked, become conduits for some of the most severe application-layer vulnerabilities.

Notably, while our work focuses on Java and C#, the principles thereof can be extended to any system that allows dynamic flow control or code modifications.

Understanding the Attack Surface of Reflection

Reflection enables runtime interaction with code that would otherwise require compile-time coupling. This capability is powerful — but when misused, creates serious risks.

Unsafe Input Patterns in Reflection-Based Code Execution

Insecure reflection typically arises when untrusted input is used directly to determine classes, methods, or fields at runtime. Below are some real-world patterns and examples.

Dynamic Class Loading in Java

String className = request.getParameter("class");

Class clazz = Class.forName(className); // Dangerous

Object obj = clazz.newInstance();

If attackers can control “className”, they can set it to arbitrary values. Attackers can use this to load arbitrary classes, executing any code, in this case, in the default constructor. It is this kind of reflection that is leveraged by tools such as ysoserial, rather than true insecure deserialization, as the vulnerable deserializers insecurely expose the reflection used by the deserializer.

Type Resolution in C#

String typeName = context.Request.Query["type"];

Type type = Type.GetType(typeName); // Dangerous

Object instance = Activator.CreateInstance(type);

Similarly to the above Java code, if attackers control “typeName”, they can load arbitrary classes, executing any code in the default constructor. Here, too, is the actual vulnerability being exploited by ysoserial.net and similar tools, which, again, are exploiting insecure reflection within vulnerable deserializers that improperly expose the reflection used by the deserializer.

Exploiting Reflection Through Deserialization

Reflection often plays a key role in deserialization vulnerabilities, enabling attackers to execute arbitrary code during the deserialization process. When an application accepts serialized input and uses reflection to reconstruct objects, it may inadvertently invoke methods that were never intended to be exposed — especially if the classpath includes complex third-party libraries.

Java Deserialization and Reflection

ObjectInputStream in = new ObjectInputStream(inputStream);

Object obj = in.readObject(); // May invoke reflection during deserialization

If the input includes references to classes from libraries like Apache Commons Collections or Spring, certain method invocations may be triggered automatically during object reconstruction. These method calls often rely on reflection internally, and if crafted carefully by an attacker, they can be used to perform unauthorized operations — even remote code execution — without ever explicitly invoking dangerous code in the application itself.

Sensitive Information Exposure via Reflection

Reflection isn't just about input-based threats. Improper handling of reflective output or error messages can expose sensitive data or internal application logic.

Unauthorized Exposure of Internal Application Structures

for (Field field : clazz.getDeclaredFields()) {

field.setAccessible(true);

System.out.println("Field: " + field.getName() + " = " + field.get(obj));

}

In a debug environment or admin panel, this could leak credentials, private keys, or user PII if the reflected object isn't sanitized.

Real-World Case Study: CVE-2025-53770 – Reflection-Powered Deserialization RCE in SharePoint

Overview

CVE-2025-53770 is a critical vulnerability affecting Microsoft SharePoint Server (2016, 2019, Subscription Edition). It enables unauthenticated remote code execution (RCE) because the ViewState parameter allows attackers to reflect into arbitrary classes and objects.

Microsoft confirmed that this vulnerability is being actively exploited in the wild, and it forms part of a broader attack chain involving related issues like CVE-2025-49704 and CVE-2025-49706.

Vulnerability Mechanics

At the core of CVE-2025-53770 is the unsafe reflection used by the deserializer during the deserialization process. In short, ASP.NET and the .NET Framework utilizes the LosFormatter to serialize and deserialize the ViewState parameter. The LosFormatter, in turn, makes use of the ObjectStateFormatter. The ObjectStateFormatter has optimized deserializers for 22 object types but uses the BinaryFormatter for all other object types. Importantly, the PageStatePersister also leverages the ObjectStateFormatter, thereby allowing the same kind of insecure reflection through the BinaryFormatter.

ViewState Attack Scenario (Alternative Perspective)

Rather than focusing on the internal mechanics of a specific tool, it's helpful to understand how a ViewState deserialization-based reflection attack unfolds in practice when protection mechanisms like MAC validation are misconfigured or bypassed.

Imagine an attacker has gained access to the machine key for a SharePoint server. This key is used to cryptographically validate the integrity of the ViewState. With it, the attacker can generate a forged payload that embeds a malicious object graph.

A sample sequence might look like this:

  1. The attacker crafts a payload containing a gadget chain (e.g., one that ultimately invokes Process.Start).
  2. That payload is serialized using the same configuration the server expects (e.g., legacy ViewState format, no encryption).
  3. The attacker embeds the serialized blob into the __VIEWSTATE parameter of a URL pointing to an exposed SharePoint .aspx page.

GET /_layouts/15/success.aspx?__VIEWSTATE= HTTP/1.1

Host: vulnerable-sharepoint.internal

If the server processes the request and deserializes the ViewState without verifying its authenticity or validating its types, arbitrary code execution can occur — all without authentication.

Reflection in Action

.NET deserializers like ObjectStateFormatter, LosFormatter, and even NetDataContractSerializer use the following reflection mechanisms:

Reflection Method

Role in Exploit

Type.GetType()

Resolves attacker-supplied type name

Activator.CreateInstance()

Instantiates attacker-defined type

MethodInfo.Invoke()

Executes method like Start()

FieldInfo.SetValue()

Sets field values reflectively

Lessons Reinforced

CVE-2025-53770 illustrates how heavily the deserialization process relies upon reflection and how, if the deserializer doesn’t control the reflection process and, instead, allows attackers to use reflection to call arbitrary code, attackers can leverage the reflection calls that deserializers make to wreak havoc across applications and websites alike. This CVE also underscores how fundamental design and architecture flaws can pose a critical risk and create vulnerabilities, but also how those decisions can be inherited through major frameworks and even the underlying languages – the ViewState vulnerability in this CVE actually applies to any system using ViewState, as well as to any system using the LosFormatter, ObjectStateFormatter, or other any other formatter that, ultimately, relies on the BinaryFormatter.

Mitigating Reflection Risks

Security must be integrated into the design phase when dealing with reflective APIs. Here's how you can minimize risk:

Mitigation Strategies

  • Whitelisting:
    Always validate against a known-safe list of classes or methods.
  • Restrict Access to Internal Members:
    Avoid setAccessible(true) unless absolutely required. Use module boundaries or sealed types in Java 17+.
  • Use Reflection Permission Controls:
    In C#, restrict reflective access with BindingFlags.Public and avoid BindingFlags.NonPublic.
  • Secure Error Handling:
    Never expose full stack traces or reflective type names in client responses. Mask or log sensitive data securely.

Building Secure Software Through Reflection Hygiene

Reflection is a powerful tool in modern software development, enabling dynamic behavior that can make systems more flexible and extensible. But that same flexibility comes with risk. Used carelessly, reflection can expose critical vulnerabilities that affect not just individual applications but the broader systems and businesses they support.

Security isn’t about reacting to threats — it’s about anticipating them. By understanding how reflection can be misused and applying safeguards early in the development process, teams can build applications that are not only more adaptable, but also far more secure.

Download the full whitepaper: A Primer on Insecure Reflection Practices in Java and C# Applications