Dependency Property Security
Dependency properties should generally be considered to be public properties. The nature of the property system prevents being able to make security guarantees about a dependency property value.
Access and Security of Wrappers and Dependency Properties
Typically, dependency properties are implemented along with "wrapper" common language runtime (CLR) properties that simplify getting or setting the property from an instance. But the wrappers are really just convenience methods that implement the underlying GetValue and SetValue static calls that are used when interacting with dependency properties. Thinking it in another way, the properties are exposed as common language runtime (CLR) properties that happen to be backed by a dependency property rather than by a private field. Security mechanisms applied to the wrappers do not parallel the property system behavior and access of the underlying dependency property. Placing a security demand on the wrapper would only prevent the usage of the convenience method but will not prevent calls to GetValue / SetValue.·Similarly, placing protected or private access level on the wrappers does not provide any effective security.
If you are writing your own dependency properties, you should declare the wrappers and the DependencyProperty identifier field as public members, so that callers do not get misleading information about the true access level of that property. For a custom dependency property, you can register your property as a read-only dependency property, and this does provide an effective means of preventing a property set by anyone that does not hold a reference to the DependencyPropertyKey for that property. For more information, see Read-Only Dependency Properties.
Declaring a DependencyProperty identifier field private is not forbidden, and can conceivably be used to help reduce the immediately exposed namespace of a custom class, but such a property should not be considered "private" in the same sense as the common language runtime (CLR) language definitions mean it, for reasons as described in the next section.
Property System Exposure of Dependency Properties
It is not generally useful, and potentially misleading, to declare a DependencyProperty as any access level other than public. That access level setting only prevents someone from being able to get a reference of the instance from the declaring class. But there are several aspects of the property system that will return a DependencyProperty as the means of identifying a particular property as it exists on an instance or subclass instance, and this identifier would still be usable in a SetValue call even if the original static identifier was declared as nonpublic. Also, OnPropertyChanged virtuals will receive information of any existing dependency property that changed value. Or, GetLocalValueEnumerator will return identifiers for any property on instances with a locally set value.
Validation and Security
Applying a demand to a ValidateValueCallback and expecting the validation failure on a demand failure to prevent a property set is not an adequate security mechanism. Set-value invalidation enforced through ValidateValueCallback could also be suppressed by malicious callers, if those callers are operating within the application domain.