Dependency Property Security
Dependency properties should generally be considered to be public properties. The nature of the Windows Presentation Foundation (WPF) property system prevents the ability to make security guarantees about a dependency property value.
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 of 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 will only prevent the usage of the convenience method but will not prevent calls to GetValue or 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 (because of its store being implemented as a dependency 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 being 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 it 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 define that access level, for reasons described in the next section.
It is not generally useful, and it is 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 to 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 of a class or a derived class instance, and this identifier is still usable in a SetValue call even if the original static identifier is declared as nonpublic. Also, OnPropertyChanged virtual methods receive information of any existing dependency property that changed value. In addition, the GetLocalValueEnumerator method returns identifiers for any property on instances with a locally set value.
Applying a demand to a ValidateValueCallback and expecting the validation failure on a demand failure to prevent a property from being 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.