Skip to content

Commit 1ca43f9

Browse files
authored
.NET: Add security warnings to xml comments for core components (microsoft#4527)
* Add security warnings to xml comments for core components * Address build errors. * Fix formatting issue * Fix formatting issue * Supress formatting warning * Supress format issue in ChatHistoryMemoryProvider * Fix remarks paragraphs
1 parent b98880d commit 1ca43f9

10 files changed

Lines changed: 185 additions & 0 deletions

File tree

dotnet/src/Microsoft.Agents.AI.Abstractions/AIAgent.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,19 @@ namespace Microsoft.Agents.AI;
2020
/// <see cref="AIAgent"/> serves as the foundational class for implementing AI agents that can participate in conversations
2121
/// and process user requests. An agent instance may participate in multiple concurrent conversations, and each conversation
2222
/// may involve multiple agents working together.
23+
/// <para>
24+
/// <strong>Security considerations:</strong> An <see cref="AIAgent"/> orchestrates data flow across trust boundaries —
25+
/// messages are sent to external AI services, context providers, chat history stores, and function tools. Agent Framework
26+
/// passes messages through as-is without validation or sanitization. Developers must be aware that:
27+
/// <list type="bullet">
28+
/// <item><description>User-supplied messages may contain prompt injection attempts designed to manipulate LLM behavior.</description></item>
29+
/// <item><description>LLM responses should be treated as untrusted output — they may contain hallucinations, malicious payloads (e.g., scripts, SQL),
30+
/// or content influenced by indirect prompt injection. Always validate and sanitize LLM output before rendering in HTML, executing as code,
31+
/// or using in database queries.</description></item>
32+
/// <item><description>Messages with different roles carry different trust levels: <c>system</c> messages have the highest trust and must be developer-controlled;
33+
/// <c>user</c>, <c>assistant</c>, and <c>tool</c> messages should be treated as untrusted.</description></item>
34+
/// </list>
35+
/// </para>
2336
/// </remarks>
2437
[DebuggerDisplay("{DebuggerDisplay,nq}")]
2538
public abstract partial class AIAgent
@@ -165,6 +178,11 @@ public ValueTask<AgentSession> CreateSessionAsync(CancellationToken cancellation
165178
/// This method enables saving conversation sessions to persistent storage,
166179
/// allowing conversations to resume across application restarts or be migrated between
167180
/// different agent instances. Use <see cref="DeserializeSessionAsync"/> to restore the session.
181+
/// <para>
182+
/// <strong>Security consideration:</strong> Serialized sessions may contain conversation content, session identifiers,
183+
/// and other potentially sensitive data including PII. Ensure that serialized session data is stored securely with
184+
/// appropriate access controls and encryption at rest.
185+
/// </para>
168186
/// </remarks>
169187
public ValueTask<JsonElement> SerializeSessionAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
170188
=> this.SerializeSessionCoreAsync(session, jsonSerializerOptions, cancellationToken);
@@ -194,6 +212,12 @@ public ValueTask<JsonElement> SerializeSessionAsync(AgentSession session, JsonSe
194212
/// This method enables restoration of conversation sessions from previously saved state,
195213
/// allowing conversations to resume across application restarts or be migrated between
196214
/// different agent instances.
215+
/// <para>
216+
/// <strong>Security consideration:</strong> Restoring a session from an untrusted source is equivalent to accepting untrusted input.
217+
/// Serialized sessions may contain conversation content, session identifiers, and potentially sensitive data. A compromised
218+
/// storage backend could alter message roles to escalate trust, or inject adversarial content that influences LLM behavior.
219+
/// Treat serialized session data as sensitive and ensure it is stored and transmitted securely.
220+
/// </para>
197221
/// </remarks>
198222
public ValueTask<AgentSession> DeserializeSessionAsync(JsonElement serializedState, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
199223
=> this.DeserializeSessionCoreAsync(serializedState, jsonSerializerOptions, cancellationToken);
@@ -301,6 +325,11 @@ public Task<AgentResponse> RunAsync(
301325
/// The messages are processed in the order provided and become part of the conversation history.
302326
/// The agent's response will also be added to <paramref name="session"/> if one is provided.
303327
/// </para>
328+
/// <para>
329+
/// <strong>Security consideration:</strong> Agent Framework does not validate or sanitize message content — it is passed through
330+
/// to the underlying AI service as-is. If input messages include untrusted user content, developers should be aware of prompt injection risks.
331+
/// System-role messages must be developer-controlled and should never contain end-user input.
332+
/// </para>
304333
/// </remarks>
305334
public Task<AgentResponse> RunAsync(
306335
IEnumerable<ChatMessage> messages,
@@ -426,6 +455,11 @@ public IAsyncEnumerable<AgentResponseUpdate> RunStreamingAsync(
426455
/// Each <see cref="AgentResponseUpdate"/> represents a portion of the complete response, allowing consumers
427456
/// to display partial results, implement progressive loading, or provide immediate feedback to users.
428457
/// </para>
458+
/// <para>
459+
/// <strong>Security consideration:</strong> Agent Framework does not validate or sanitize message content — it is passed through
460+
/// to the underlying AI service as-is. If input messages include untrusted user content, developers should be aware of prompt injection risks.
461+
/// System-role messages must be developer-controlled and should never contain end-user input.
462+
/// </para>
429463
/// </remarks>
430464
public async IAsyncEnumerable<AgentResponseUpdate> RunStreamingAsync(
431465
IEnumerable<ChatMessage> messages,

dotnet/src/Microsoft.Agents.AI.Abstractions/AIContextProvider.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ namespace Microsoft.Agents.AI;
2828
/// <see cref="InvokingAsync"/> to provide context, and optionally called at the end of invocation via
2929
/// <see cref="InvokedAsync"/> to process results.
3030
/// </para>
31+
/// <para>
32+
/// <strong>Security considerations:</strong> Context providers may inject messages with any role, including <c>system</c>, which
33+
/// has the highest trust level and directly shapes LLM behavior. Developers must ensure that all providers attached to an agent
34+
/// are trusted. Agent Framework does not validate or filter the data returned by providers — it is accepted as-is and merged into
35+
/// the request context. If a provider retrieves data from an external source (e.g., a vector database or memory service), be aware
36+
/// that a compromised data source could introduce adversarial content designed to manipulate LLM behavior via indirect prompt injection.
37+
/// Implementers should validate and sanitize data retrieved from external sources before returning it.
38+
/// </para>
3139
/// </remarks>
3240
public abstract class AIContextProvider
3341
{
@@ -96,6 +104,11 @@ protected AIContextProvider(
96104
/// <item><description>Injecting contextual messages from conversation history</description></item>
97105
/// </list>
98106
/// </para>
107+
/// <para>
108+
/// <strong>Security consideration:</strong> Data retrieved from external sources (e.g., vector databases, memory services, or
109+
/// knowledge bases) may contain adversarial content designed to influence LLM behavior via indirect prompt injection.
110+
/// Implementers should validate data integrity and consider the trustworthiness of the data source.
111+
/// </para>
99112
/// </remarks>
100113
public ValueTask<AIContext> InvokingAsync(InvokingContext context, CancellationToken cancellationToken = default)
101114
=> this.InvokingCoreAsync(Throw.IfNull(context), cancellationToken);
@@ -195,6 +208,11 @@ protected virtual async ValueTask<AIContext> InvokingCoreAsync(InvokingContext c
195208
/// In contrast with <see cref="InvokingCoreAsync"/>, this method only returns additional context to be merged with the input,
196209
/// while <see cref="InvokingCoreAsync"/> is responsible for returning the full merged <see cref="AIContext"/> for the invocation.
197210
/// </para>
211+
/// <para>
212+
/// <strong>Security consideration:</strong> Any messages, tools, or instructions returned by this method will be merged into the
213+
/// AI request context. If data is retrieved from external or untrusted sources, implementers should validate and sanitize it
214+
/// to prevent indirect prompt injection attacks.
215+
/// </para>
198216
/// </remarks>
199217
/// <param name="context">Contains the request context including the caller provided messages that will be used by the agent for this invocation.</param>
200218
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
@@ -299,6 +317,10 @@ protected virtual ValueTask InvokedCoreAsync(InvokedContext context, Cancellatio
299317
/// <para>
300318
/// The default implementation of <see cref="InvokedCoreAsync"/> only calls this method if the invocation succeeded.
301319
/// </para>
320+
/// <para>
321+
/// <strong>Security consideration:</strong> Messages being processed/stored may contain PII and sensitive conversation content.
322+
/// Implementers should ensure appropriate encryption at rest and access controls for the storage backend.
323+
/// </para>
302324
/// </remarks>
303325
protected virtual ValueTask StoreAIContextAsync(InvokedContext context, CancellationToken cancellationToken = default) =>
304326
default;

dotnet/src/Microsoft.Agents.AI.Abstractions/AgentSession.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,15 @@ namespace Microsoft.Agents.AI;
4242
/// <see cref="JsonElement"/> and the <see cref="AIAgent.DeserializeSessionAsync(JsonElement, JsonSerializerOptions?, System.Threading.CancellationToken)"/> method
4343
/// can be used to deserialize the session.
4444
/// </para>
45+
/// <para>
46+
/// <strong>Security considerations:</strong> Serialized sessions may contain conversation content, session identifiers,
47+
/// and other potentially sensitive data including PII. Developers should:
48+
/// <list type="bullet">
49+
/// <item><description>Treat serialized session data as sensitive and store it securely with appropriate access controls and encryption at rest.</description></item>
50+
/// <item><description>Treat restoring a session from an untrusted source as equivalent to accepting untrusted input. A compromised storage backend
51+
/// could alter message roles to escalate trust, or inject adversarial content that influences LLM behavior.</description></item>
52+
/// </list>
53+
/// </para>
4554
/// </remarks>
4655
/// <seealso cref="AIAgent"/>
4756
/// <seealso cref="AIAgent.CreateSessionAsync(System.Threading.CancellationToken)"/>
@@ -67,6 +76,11 @@ protected AgentSession(AgentSessionStateBag stateBag)
6776
/// <summary>
6877
/// Gets any arbitrary state associated with this session.
6978
/// </summary>
79+
/// <remarks>
80+
/// Data stored in the <see cref="StateBag"/> will be included when the session is serialized.
81+
/// Avoid storing secrets, credentials, or highly sensitive data in the state bag without appropriate encryption,
82+
/// as this data may be persisted to external storage.
83+
/// </remarks>
7084
[JsonPropertyName("stateBag")]
7185
public AgentSessionStateBag StateBag { get; protected set; } = new();
7286

dotnet/src/Microsoft.Agents.AI.Abstractions/ChatHistoryProvider.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,14 @@ namespace Microsoft.Agents.AI;
3737
/// A <see cref="ChatHistoryProvider"/> is only relevant for scenarios where the underlying AI service that the agent is using
3838
/// does not use in-service chat history storage.
3939
/// </para>
40+
/// <para>
41+
/// <strong>Security considerations:</strong> Agent Framework does not validate or filter the messages returned by the provider
42+
/// during load — they are accepted as-is and treated identically to user-supplied messages. Implementers must ensure that only
43+
/// trusted data is returned. If the underlying storage is compromised, adversarial content could influence LLM behavior via
44+
/// indirect prompt injection — for example, injected messages could alter the conversation context or impersonate different roles.
45+
/// Messages stored in chat history may contain PII and sensitive conversation content; implementers should consider encryption
46+
/// at rest and appropriate access controls for the storage backend.
47+
/// </para>
4048
/// </remarks>
4149
public abstract class ChatHistoryProvider
4250
{
@@ -159,6 +167,11 @@ protected virtual async ValueTask<IEnumerable<ChatMessage>> InvokingCoreAsync(In
159167
/// Messages are returned in chronological order to maintain proper conversation flow and context for the agent.
160168
/// The oldest messages appear first in the collection, followed by more recent messages.
161169
/// </para>
170+
/// <para>
171+
/// <strong>Security consideration:</strong> Messages loaded from storage should be treated with the same caution as user-supplied
172+
/// messages. A compromised storage backend could alter message roles to escalate trust (e.g., changing <c>user</c> messages to
173+
/// <c>system</c> messages) or inject adversarial content that influences LLM behavior.
174+
/// </para>
162175
/// </remarks>
163176
/// <param name="context">Contains the request context including the caller provided messages that will be used by the agent for this invocation.</param>
164177
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
@@ -273,6 +286,10 @@ protected virtual ValueTask InvokedCoreAsync(InvokedContext context, Cancellatio
273286
/// <para>
274287
/// The default implementation of <see cref="InvokedCoreAsync"/> only calls this method if the invocation succeeded.
275288
/// </para>
289+
/// <para>
290+
/// <strong>Security consideration:</strong> Messages being stored may contain PII and sensitive conversation content.
291+
/// Implementers should ensure appropriate encryption at rest and access controls for the storage backend.
292+
/// </para>
276293
/// </remarks>
277294
protected virtual ValueTask StoreChatHistoryAsync(InvokedContext context, CancellationToken cancellationToken = default) =>
278295
default;

dotnet/src/Microsoft.Agents.AI.CosmosNoSql/CosmosChatHistoryProvider.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,24 @@ namespace Microsoft.Agents.AI;
1717
/// <summary>
1818
/// Provides a Cosmos DB implementation of the <see cref="ChatHistoryProvider"/> abstract class.
1919
/// </summary>
20+
/// <remarks>
21+
/// <para>
22+
/// <strong>Security considerations:</strong>
23+
/// <list type="bullet">
24+
/// <item><description><strong>PII and sensitive data:</strong> Chat history stored in Cosmos DB may contain PII, sensitive conversation
25+
/// content, and system instructions. Ensure the Cosmos DB account is configured with appropriate access controls, encryption at rest,
26+
/// and network security (e.g., private endpoints, virtual network rules). The <see cref="MessageTtlSeconds"/> property can be used to
27+
/// automatically expire messages and limit data retention.</description></item>
28+
/// <item><description><strong>Compromised store risks:</strong> Agent Framework does not validate or filter messages loaded from the
29+
/// store — they are accepted as-is. If the Cosmos DB store is compromised, adversarial content could be injected into the conversation
30+
/// context, potentially influencing LLM behavior via indirect prompt injection. Altered message roles (e.g., changing <c>user</c> to
31+
/// <c>system</c>) could escalate trust levels.</description></item>
32+
/// <item><description><strong>Authentication:</strong> Agent Framework does not manage authentication or encryption for the Cosmos DB
33+
/// connection — these are the responsibility of the <see cref="CosmosClient"/> configuration. Use managed identity
34+
/// or token-based authentication where possible, and avoid embedding connection strings with keys in source code.</description></item>
35+
/// </list>
36+
/// </para>
37+
/// </remarks>
2038
[RequiresUnreferencedCode("The CosmosChatHistoryProvider uses JSON serialization which is incompatible with trimming.")]
2139
[RequiresDynamicCode("The CosmosChatHistoryProvider uses JSON serialization which is incompatible with NativeAOT.")]
2240
public sealed class CosmosChatHistoryProvider : ChatHistoryProvider, IDisposable

dotnet/src/Microsoft.Agents.AI.Mem0/Mem0Provider.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,38 @@
1313

1414
namespace Microsoft.Agents.AI.Mem0;
1515

16+
#pragma warning disable IDE0001 // Simplify Names - Microsoft.Extensions.Logging.LogLevel.Trace doesn't get found in net472 when removing the namespace.
1617
/// <summary>
1718
/// Provides a Mem0 backed <see cref="MessageAIContextProvider"/> that persists conversation messages as memories
1819
/// and retrieves related memories to augment the agent invocation context.
1920
/// </summary>
2021
/// <remarks>
22+
/// <para>
2123
/// The provider stores user, assistant and system messages as Mem0 memories and retrieves relevant memories
2224
/// for new invocations using a semantic search endpoint. Retrieved memories are injected as user messages
2325
/// to the model, prefixed by a configurable context prompt.
26+
/// </para>
27+
/// <para>
28+
/// <strong>Security considerations:</strong>
29+
/// <list type="bullet">
30+
/// <item><description><strong>External service trust:</strong> This provider communicates with an external Mem0 service over HTTP.
31+
/// Agent Framework does not manage authentication, encryption, or connection details for this service — these are the responsibility
32+
/// of the <see cref="HttpClient"/> configuration. Ensure the HTTP client is configured with appropriate authentication
33+
/// and uses HTTPS to protect data in transit.</description></item>
34+
/// <item><description><strong>PII and sensitive data:</strong> Conversation messages (including user inputs, LLM responses, and system
35+
/// instructions) are sent to the external Mem0 service for storage. These messages may contain PII or sensitive information.
36+
/// Ensure the Mem0 service is configured with appropriate data retention policies and access controls.</description></item>
37+
/// <item><description><strong>Indirect prompt injection:</strong> Memories retrieved from the Mem0 service are injected into the LLM
38+
/// context as user messages. If the memory store is compromised, adversarial content could influence LLM behavior. The data
39+
/// returned from the service is accepted as-is without validation or sanitization.</description></item>
40+
/// <item><description><strong>Trace logging:</strong> When <see cref="Microsoft.Extensions.Logging.LogLevel.Trace"/> is enabled,
41+
/// full memory content (including search queries and results) may be logged. This data may contain PII and should not be enabled
42+
/// in production environments.</description></item>
43+
/// </list>
44+
/// </para>
2445
/// </remarks>
2546
public sealed class Mem0Provider : MessageAIContextProvider
47+
#pragma warning restore IDE0001 // Simplify Names
2648
{
2749
private const string DefaultContextPrompt = "## Memories\nConsider the following memories when answering user questions:";
2850

0 commit comments

Comments
 (0)