CA2108: Controllare la sicurezza dichiarativa sui tipi di valori
TypeName |
ReviewDeclarativeSecurityOnValueTypes |
CheckId |
CA2108 |
Category |
Microsoft.Security |
Breaking Change |
Non sostanziale |
Causa
Un tipo di valore pubblico o protetto è protetto da Accesso ai dati e modellazione o Richieste di collegamento.
Descrizione della regola
I tipi di valore vengono allocati e inizializzati dai relativi costruttori predefiniti prima dell'esecuzione di altri costruttori. Se un tipo di valore è protetto da Demand o LinkDemand e il chiamante non dispone di autorizzazioni sufficienti per il controllo di sicurezza, qualsiasi costruttore diverso da quello predefinito avrà esito negativo e verrà generata un'eccezione di sicurezza. Il tipo di valore non viene deallocato, ma viene lasciato nello stato impostato dal relativo costruttore predefinito. Non presupporre che un chiamante che passa un'istanza del tipo di valore disponga dell'autorizzazione a creare o ad accedere all'istanza.
Come correggere le violazioni
Non è possibile correggere una violazione di questa regola se non rimuovendo il controllo di sicurezza dal tipo e utilizzando in sostituzione controlli di sicurezza a livello di metodo. Si noti che questa correzione della violazione non impedisce ai chiamanti con autorizzazioni non adeguate di ottenere istanze del tipo di valore. È necessario assicurarsi che un'istanza del tipo di valore, nello stato predefinito, non esponga informazioni riservate e non possa essere utilizzata in modo dannoso.
Esclusione di avvisi
È possibile escludere un avviso da questa regola se qualsiasi chiamante può ottenere istanze del tipo di valore nello stato predefinito senza causare una minaccia alla sicurezza.
Esempio
Nell'esempio riportato di seguito viene illustrata una libreria contenente un tipo di valore che viola questa regola. Si noti che il tipo StructureManager presuppone che un chiamante che passa un'istanza del tipo di valore disponga dell'autorizzazione a creare o ad accedere all'istanza.
using System;
using System.Security;
using System.Security.Permissions;
[assembly:AllowPartiallyTrustedCallers]
namespace SecurityRulesLibrary
{
// Violates rule: ReviewDeclarativeSecurityOnValueTypes.
[System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]
public struct SecuredTypeStructure
{
internal double xValue;
internal double yValue;
public SecuredTypeStructure(double x, double y)
{
xValue = x;
yValue = y;
Console.WriteLine("Creating an instance of SecuredTypeStructure.");
}
public override string ToString()
{
return String.Format ("SecuredTypeStructure {0} {1}", xValue, yValue);
}
}
public class StructureManager
{
// This method asserts trust, incorrectly assuming that the caller must have
// permission because they passed in instance of the value type.
[System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Assert, Name="FullTrust")]
public static SecuredTypeStructure AddStepValue(SecuredTypeStructure aStructure)
{
aStructure.xValue += 100;
aStructure.yValue += 100;
Console.WriteLine ("New values {0}", aStructure.ToString());
return aStructure;
}
}
}
Nella seguente applicazione vengono illustrati i punti deboli della libreria.
using System;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using SecurityRulesLibrary;
// Run this test code with partial trust.
[assembly: System.Security.Permissions.PermissionSetAttribute(
System.Security.Permissions.SecurityAction.RequestRefuse,
Name="FullTrust")]
namespace TestSecurityExamples
{
public class TestDemandOnValueType
{
static SecuredTypeStructure mystruct;
[STAThread]
public static void Main()
{
try
{
mystruct = new SecuredTypeStructure(10,10);
}
catch (SecurityException e)
{
Console.WriteLine(
"Structure custom constructor: {0}", e.Message);
}
// The call to the default constructor
// does not throw an exception.
try
{
mystruct = StructureManager.AddStepValue(
new SecuredTypeStructure());
}
catch (SecurityException e)
{
Console.WriteLine(
"Structure default constructor: {0}", e.Message);
}
try
{
StructureManager.AddStepValue(mystruct);
}
catch (Exception e)
{
Console.WriteLine(
"StructureManager add step: {0}", e.Message);
}
}
}
}
Questo esempio produce l'output che segue.