3

In an application we can output a report as a csv file and load it up similar to the following code:

Process.Start("C:\MyReport.csv") ' Not real path 

When running code analysis it produces the following error:

CA2122 Do not indirectly expose methods with link demands 'Form.Function(Definition)' calls into 'Process.Start(String)' which has a LinkDemand. By making this call, 'Process.Start(String)' is indirectly exposed to user code

I have seen somewhere to mark the assembly with the SecurityTransparentAttribute, does this just suppress the message? If so this is not what I would like. Is there another way of opening the file that would circumvent this message without suppressing it? I would ideally like to avoid Excel automation if I can as Excel is not used anywhere else at the moment.

Ideas?

Stuart Blackler
  • 3,732
  • 5
  • 35
  • 60

3 Answers3

7

I stumbled upon the same issue today and thought the following answer would be useful for others so thought to write it.

So basically, my code was to open up a given directory path in explorer, as shown below

public static void OpenDirectoryPath(string directoryPath)
{
    if (Directory.Exists(directoryPath))
    {
        Process.Start(directoryPath);
    }
}

The above code produced the following error

CA2122 : Microsoft.Security : 'Helper.OpenDirectoryPath(string)' calls into 'Process.Start(string)' which has a LinkDemand. By making this call, 'Process.Start(string)' is indirectly exposed to user code. Review the following call stack that might expose a way to circumvent security protection:

The question to ask is, do you really want this method to be public. In my case, the answer was "No". Changing the method to internal resolved the problem.

internal static void OpenDirectoryPath(string directoryPath)
{
    if (Directory.Exists(directoryPath))
    {
        Process.Start(directoryPath);
    }
}
Hamid Shahid
  • 4,486
  • 3
  • 32
  • 41
3

Process.Start() is having [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)] attribute.

All the functions in the hierarchy must have this attribute set.

Example

[PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)]
Method1()
{
    Process.Start(...);
}

[PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)]
Method2()
{
    Method1();
}

[PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)]
Method3()
{
    Method2();
}

[PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust", Unrestricted = false)]
Method4()
{
    Method3();
}

...
...

This fixes this issue. I did not test the security violation scenario, but I hope this must solve the issue.

Khavasi
  • 61
  • 9
  • 1
    Thanks for your answer, but I had already fixed the issue and no longer on the project. I have upvoted for your effort in either case :) – Stuart Blackler Apr 16 '13 at 14:08
1

You may do not care about it at all (suppress the message locally) or in global suppression. It depends on your security policy/requests.

What is means is: Process.Start has some security attributes applied but it has specified that the check should be done only for it and for its caller (SecurityAction.LinkDemand). This implies that if you call it in a public method the code that use your method will skip this security check. Your code may be trusted to call Process.Start but their code not but if they call your method they'll gain that privilege.

If you need to fix this you may apply the same security attributes to your code, this will require your caller to have that privileges (SecurityAction.LinkDemand doesn't walk the full stack so it's faster).

Adriano Repetti
  • 65,416
  • 20
  • 137
  • 208