How to provide extra trust for an Internet Explorer hosted assembly
A common scenario for developers is that they create an assembly that is to be hosted
by Internet Explorer, but requires more trust than would be given to it by default
by the Internet or LocalIntranet zone code groups. Often the first attempt at
fixing this involves signing the assembly with a strong name or an X509 certificate
and then creating a code group that gives that signature full trust. Developers
are often surprised when they continue to see security exceptions thrown even after
they do this.
The reasoning behind the security exception is AppDomains. Before IE can load
your assembly, it must create an AppDomain to load the assembly into. When it
creates this AppDomain, it assigns it all the evidence it knows without loading your
assembly, the URL and zone that it is loading from. Since the AppDomain itself
does not get any evidence about the signature that your assembly has (it can't since
the assembly is not loaded yet), it will not match the code group that you created
giving extra trust. Now when a security demand occurs, a stack walk begins.
When your assembly is checked for correct permissions, it passes, and the stack walk
continues until it gets to the AppDomain. Since the AppDomain doesn't have the
permissions that are required by this demand, it causes the SecurityException to be
thrown.
There are two ways to work around this problem. The first way is to create a
code group that matches the evidence that the AppDomain is getting, using a SiteMembershipCondition
or a ZoneMembershipCondition, and trust that. The other is to Assert() all the
permissions that your assembly needs at its entry points. This prevents the
stack walk from getting to the AppDomain level, therefore preventing the AppDomain
from causing a SecurityException to be thrown.
Comments
Anonymous
January 28, 2004
I have a application, embedded in IE (html assambly).
That aplication need to connect back to the server in order to get some
data.
What are conditions to succeed without requesting any special permissions
from client? As an applet do it....
Should I connect back to the server only using port 80?
Right now the client app is serverd by Apache and connection back is tryed
to another aplication on port 9500
Changing security permission by the client is not an option.. same for stron names.Anonymous
January 29, 2004
This depends on which version of the framework your embedded assembly is targeting. With v1.0 of the framework, this is not possible without having the client trust your code. However, with v1.1 and higher, all code run off the internet has same site web access back to where they are hosted from. You can use the System.Web.HttpWebRequest class to gain access back to this site.Anonymous
February 03, 2004
The comment has been removedAnonymous
February 03, 2004
The comment has been removedAnonymous
March 02, 2004
How can I give a SocketPermission to managed code in IE( winform UserControl) so that the UserControl can open an IP socket to the server that it came from??
I will appreciate ur answer!Anonymous
March 03, 2004
This is an interesting question, which I'll write a blog post about this week. The quick answer is that using the default security objects you can't. The best you can do is grant same-site web access, and communicate using HTTP or HTTPS. However, if you write a custom security object to create same-site socket permissions, this is achievable. I'll post a link back here when I write the blog.Anonymous
March 10, 2004
Greetings!
I need help. I am trying to load a usercontrol in IE. I know that the AppDomain has not enough security permissions. I don't think that asserting permissons works for me. Everything works fine for me when I use the site condition with my machine name. When I try with the strong name condition it doesnt load at all. Can you provide a full source of a window control than can be load in IE using ONLY his strong name as a security condition? There is no documentation on this. Thank you for your time.Anonymous
March 11, 2004
Just saw this on the newsgroups too, so I'll copy and paste my answer from there:
Unfortunately, you can't just use the strong name, for reasons I mention in my blog (which I see you've already found ;-) ): http://blogs.msdn.com/shawnfa/archive/2003/06/26/57026.aspx
I see that you understand that the problem is with the permission set associated with the AppDomain, and not with the assembly itself. Now what you need to think about are what evidence is available to IE at the time the AppDomain is created (and its PermissionSet assigned). Since the AppDomain must be created before the assembly is loaded into it, nothing specific about the assembly is available (including the strong name, or authenticode signature). Instead, you have only the site, URL, and zone evidence to work with. In order to get your control to work, you'll need to use a membership condition that matches one of these types of evidence to grant trust to your control. Since you say that you've gotten this to work already on your dev machine with the site membership condition, I see that you didn't have a problem getting that far.
Is there a specific reason you need to move away from using the site membership condition?Anonymous
June 23, 2004
Hi, I'm not very familiar with .NET security (or .NET for that matter), but I did develop a user control that is embedded in IE and am getting the problems that you described in the blog.
I'm not sure how to word this, but calling Assert() on a Permission will only work if my user control is allowed to be able to get access to whatever I'm asking permission for right? For example, I tried new WebPermission(PermissionState.Unrestricted).Assert() and got a SecurityException. I found that only when I add my dll to a code group in the client machine with some sort of trust would the Assert() method call work.
Am I completely off track here?
So is it even possible for the client machines (anywhere on the internet) to load my application (a dll embedded in a webpage) without making changes to their security policy on their machine?
ThanksAnonymous
June 23, 2004
Hi Wendy,
You're correct, Asserting a permission requires that you be granted the permission in the first place. This post is mostly about getting the control to not throw once it has already been granted permissions.
If you need to have the user's machines trust your code, you have two options. The easiest would be to simply code with only those permissions that appear in the Internet code group. If that's not a possibility, then another option is for you to modify the policy of your local machine so that your control is trusted (see my post here for information on that: http://blogs.msdn.com/shawnfa/archive/2003/06/20/57023.aspx ... I recommend trusting based on strong name), and then creating an .MSI deployment file out of the policy, and placing that on your website. Have users install the custom policy before running your control, and then your Asserts should work fine.
-ShawnAnonymous
June 23, 2004
Hi Shawn,
Thanks for such a quick reply.
I don't think that the .MSI deployment file is a viable solution since we don't want our users to have to deliberately download and install something.
The actual problem I'm having is that my windows control needs to access an .aspx page that is located on the same web server that the control .dll is from. If the user (who could be connecting from anywhere on the internet) who downloaded the .dll is not connected to the internet through a proxy server, everything works perfectly. But if the user is connected through a proxy server, I get a HTTP 407 Authorization Required error when my code does a httpwebrequest.GetResponse(). I realized that HttpWebRequest has a Proxy property, however whenever I try to access that property, I get a SecurityException stating that the request for type WebPermission has failed. I tried to Assert a WebPermission with PermissionState.Unrestricted as parameter, but that caused a SecurityException as well. I'm assuming this is because my application isn't granted unrestricted WebPermission. Given this information, do you know if I need any kind of extra permissions that are not available just by adding the site that the control .dll is from to the Trusted Sites list in IE?
Thanks,
WendyAnonymous
June 24, 2004
Right, your application is not granted unrestricted web permission, but you should have same site web access. Try just asserting for access back to your site.
The reason you can't go unrestriced is if we allowed all web controls to have unrestricted web access by default, it would open up huge cross-site scripting holes.
-ShanAnonymous
June 29, 2004
Excellent! Thanks a Million. This really helped me sort out my problem!Anonymous
April 18, 2005
The comment has been removedAnonymous
April 18, 2005
Hi, thanks for the info. Was tearing my hair out trying to understand how this works. But I still have issues...
Issue #1. I've granted UIPermission.AllWindows to my assembly using URL method. I call
new UIPermission(UIPermissionWindow.AllWindows).Assert()
in my constructor and it passes (doesn't throw an exception).
However, as soon as I override PreTranslateMessage in my class my control fails to load - I just get the red X. From the docs this just requires UIPermissionWindow.AllWindows. I really need these lower-level overrides for my control.
Issue #2. If I use the strong name method my control fails to load - red X again. Doesn't matter what code I put in the class (ie. I don't call any code that requires special permissions).
Any help much appreciated.
Alfie.Anonymous
April 18, 2005
Ok, I think I understand(?) what's going on from a bit of digging.
The second issue is the AllowPartiallyTrustedCallers problem. Once I added that it went away.
The first issue seems to be a documentation error. If I use Reflector, ProcessCmdKey seems to require UnmanagedCode access. It has:
[SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode=true), SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode=true)]
By the way, the Message struct which is one of the parameters also has UnmanagedCode=true.
Is this correct? Do I really need full trust to use a control that overrides ProcessCmdKey (and others)?
What's annoying is that I rewrote a lot of code to use GDI+ rather than PInvoke to avoid requiring full trust and now I find I need it anyway!
Thanks, Alfie.Anonymous
March 13, 2006
FYI, in answer to the "How can I give a SocketPermission to managed code in IE?" question, you can assert multiple stack walk modifiers / permission sets simultaneously to create a socket by doing something like this:
PermissionSet ps = new PermissionSet(PermissionState.None);
ps.AddPermission(new SocketPermission(PermissionState.Unrestricted));
ps.AddPermission(new SecurityPermission(PermissionState.Unrestricted));
ps.Assert();Anonymous
March 16, 2006
The comment has been removedAnonymous
March 16, 2006
I have below code, without any attribute assertion, I got RegistryPermission failed at Internet Zone.
when I added [RegistryPermission(SecurityAction.Assert, Unrestricted = true)]
, I got SecurityPermission failed at My computer zone.
After I added [SecurityPermission(SecurityAction.Assert, Unrestricted = true)]
, I still got same exception.
Both internet zone and my computer zone has full trust to its own zone.
Can you help me out with this?
Thanks.
private void btnJoin_Click(object sender, System.EventArgs e)
{
Microsoft.Win32.RegistryKey rk;
rk = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(
"Software\Microsoft.NetFramework",false);
string[] skNames = rk.GetSubKeyNames();
for (int i=0;i<skNames.Length;++i)
{
Console.WriteLine("Registry Key: {0}", skNames[i]);
}
rk.Close();
}Anonymous
March 16, 2006
I reccomend strong naming your assembly and creating a new code group that specifies the strong name and not worry about the other zones.
If you set the keyfile into your project for Wrapper Assembly Key File when you add your reference it will strong name the wrapper using your key.
Also if you need to use tlbimp or aximp you can also set your keyfile.
I was having problems using the attribute assertions, so I just use
PermissionSet ps = new PermissionSet(PermissionState.None);
ps.AddPermission(new SocketPermission(PermissionState.Unrestricted));
ps.AddPermission(new SecurityPermission(PermissionState.Unrestricted));
ps.Assert();
and life is good.Anonymous
March 17, 2006
Is there any way to bypass permission check without setting the client code groups?Anonymous
May 15, 2006
FYI, I recently ran into an issue where I create a CAG that fully trusted the strong name key through a Deployment Package, but when I loaded the page with the assembly it would throw SecurityExceptions or tell me in the IE Debug log that "that assembly does not allow partially trusted callers", when it certainly did trust them.
I was developing on Win 2000 with 1.1 (and this worked fine) and then tested on XP Pro SP2 with 1.1 and 2.0
The problem is that I was creating the CAG in the .Net 1.1 framework only and IE was using the .Net 2.0 Framework when it loads inside of its own app domain.
The fix was to create an identical CAG for the .Net 2.0 framework using mscorcfg or caspol.exe. I have to check for the newer framework version even though my app and installer only need 1.1.
This will be a maintenence issue, since IE uses the latest installed version of .Net for some reason, any ".Net Framework 2.1" upgrades will break this in the same way.
This discovery cost me one ms support incident, enjoy!Anonymous
May 24, 2006
Hello,
I have written a windows forms control that we are attempting to host in an
IE browser. The application hosting the control is ASP.NET. The control uses
the following CAS permissions: IsolatedStorageFilePermission,
SqlClientPermission. Using a strong name I have signed both the web
application and the windows forms control. In addition I created a code group
below intranet applications that specifies this strong name and allows full
trust. This has alleviated the IsolatedStorageFilePermission exception.
However, the application still throws the SqlClientPermission exception any
time it attempts to access a SQL Server resource.
Any ideas and/or thoughts would be apperciated.
Thanks,
PhilAnonymous
May 25, 2006
I have a Windows Forms app running in IE which needs to make use of a web service (.ASMX page) hosted at the same site as the DLL is downloaded from. It's all built in .NET and I'm using the proxy class that Visual Studio builds to talk to the ASMX page.
However, even though it only tries to contact the same site, I get web permission exceptions when running in the Local Intranet zone, which according to the documentation ought to allow this by default. If I bump up the zone to full trust, everything works - but clients don't like me asking them to do this!
Signing the assembly is not (yet) an option as it simply doesn't run in that case.
Is there anything I can put in my code to fix this? Any other ideas?Anonymous
June 01, 2006
Hi Julia,
You should be able to get details from the SecurityException about what you were actually granted and what demand failed -- from there you can see the difference between the WebPermission you have and the one that you're trying to use.
-ShawnAnonymous
June 12, 2006
Hi. I am developing an ie based project which needs to have full-trust in internet zone for it to function well. I was just wondering what can i do if i want my specific sight (and only my sight) to have full trust in internet zone of clients viewing it? can i place my web address in their registry or sumthing then it will detect that this site has full trust in internet zone?
help needed badly...Anonymous
June 14, 2006
The comment has been removedAnonymous
June 14, 2006
Ei thanx! But can I imbed it in C# or ASP.NET? I want to automatically set the settings of the viewer when he tries to view my page.Anonymous
June 16, 2006
No you cannot. If code running on the Internet was able to modify policy on anyone's machine to trust themselves, then there's not really much point to the security system :-)
What's going to prevent some malicious code from doing the same thing?
-ShawnAnonymous
June 18, 2006
I created an asp application that creates a word object,fills in the necessary content and sends this mail as an attachment..teh application is working fine from the server which is my machine..but when acessed from a client machine it throws an object required error..Can someone plz help me on this as i am stuck up on this for 1 week..plz help
thx kiranAnonymous
October 09, 2006
I want to display a UserControl on a web page using an tag. The control has dependent assemblies that are quite large. These assemblies are installed on the client (not in GAC), but I don't see a way to use them. The dependent assemblies are always download from the web server resulting in intolerable performance. I have tried using an application configuration file to specify probing privatePath, but the Fusion log reports that it won't probe the specified client location because that is outside the appbase.In the old days of ActiveX, It was possible to download and install whatever was needed and simply activate it on the web page after that. This provided huge value in terms of good performance, ability to do things on the client not allowed/supported by the browser, and simplicity. I'm hoping there is a way to gain those benefits but with the much better security offered by code access control and UserControls.Anonymous
November 16, 2006
The comment has been removedAnonymous
December 17, 2006
No, it is not currently possible to elevate your permissions on the client side for a control. The closest option is ClickOnce which will allow you to prompt and elevate an application -- although this application will not be hosed in the web page. -ShawnAnonymous
January 11, 2007
The comment has been removedAnonymous
January 12, 2007
I need to invoke web service from WinForm Control on aspx page. But I have 401. I need to invoke WS in context of page user (not local user). Is it posible? ThanksAnonymous
January 14, 2007
I have a application, embedded in IE (html assambly). That aplication need to connect back to the server in order to get some data (asmx web service). Web site use intergated auth, but client computer is not in WebServer domain. I have 401 when invoke Wen service. How can I get data from servver. Please help!Anonymous
January 17, 2007
Hi DeniX, I'm not a web service authentication expert, so I'm not sure how to answer your question. I recommend checking out the MSDN forums, where someone will be able to help you with your authentication questions. -ShawnAnonymous
March 07, 2007
Hi. I want to use a .net object in IE. (Directoryservices) Can I give full-trust to it? Without modifying anything on client machine. Maybe with a certificate or a popup at the client, that he gives full trust to this activex. Thanks Laszlo.Anonymous
March 07, 2007
One of my most read blog posts (and one of the reasons I created this blog in the first place -- to answerAnonymous
March 07, 2007
One of my most read blog posts (and one of the reasons I created this blog in the first place -- to answerAnonymous
March 09, 2007
The comment has been removedAnonymous
March 09, 2007
Hi Alvin, I'm not sure I entirely understand your points. ClickOnce aside (it's not really the same thing -- it allows for installing applciations locally, whereas we're talking about hosting a control in a web page here), let me look at your other points. You don't have to elevate a Zone, Site, or URL to get this scenario to work. I totally agree that elevating a zone is almost certainly the wrong way to go. You can use StrongName or Publisher evience to elevate your control, however that means the AppDomain itself will not be trusted. To solve this, you can place Asserts at the entry points of your control so that demands never hit the AppDomain boundary. -ShawnAnonymous
March 09, 2007
Hi Laca, You can't do this without modifying anything on the client machine. (Think of how much malware would love to be able to elevate on client machines!). In Orcas there is a feature that allows controls to carry a manifest which states it needs to be trusted, and if that manifest is signed by a trusted publisher (you'll have to push the trusted publisher down to client machines), then it will run with the requested permissions. -ShawnAnonymous
March 16, 2007
First of all Thank you for maintaing this blog. This is very usefull and informative. There is very little (if any) documentation available on this issue. Here is my situation. I have a user control which I am hosting in IE. This is signed using a strong name. I have created a new CodeGroup and the membership condition is the publik key part of the strong name. Everything works fine in both the Intranet and Internet zone in IE. Except, when a modal form pops up in the Internet Zone, it has a .NET security warning bubble associated with it, warning not to enter password and other stuff on the dialog. ( The form/dialog does not have any textboxes on it). This does not happen in Intranet zone. I am confused as to the behaviour. I will really appreciate your input/suggestions for resolving this issue. Thanks much.Anonymous
March 29, 2007
That behavior is from the Windows Forms classes, which I believe (but am not 100% sure) base it upon the zone of the form rather than the trust level of the form. You could try asking over in the WinForms group on the MSDN forums, where someone who is better versed in WinForms could provide a more authoratitive answer. -ShawnAnonymous
May 10, 2007
I have a .NET control hosted in IE, which uses WSE2 (Microsoft.Web.Services2.dll) to connect back to the server and download files which are later loaded into MS Office applications (Excel, Word, Outlook). WSE2 requires FullTrust and does not trust partially trusted callers. My solution so far is to set a URL/Site based policy entry, which grants FullTrust. The problem is - how to deploy this policy with minimum client involvement?
- Provide the power users with a document, which describes for them how to do the change using .NET Framework Configuration tool. Problem – too much user involvement and .NET 2.0 doesn’t even come with Configuration tool (you have to install the SDK to get it – that’s way too much to ask from the end user)
- The built-in tools - The msi file, generated by the Framework Configuration Tool simply replaces the whole policy instead of only updating it. Problem - while this might be considered somewhat OK for well established enterprise-wide situations - it's completely ridiculous each policy “update” to wipe out everything else at that level. On top of that it seems that the msi toggles between install and uninstall no matter how it’s called. Also with the generated msi, there’s no way to change the URL/Site which is different for every client we have.
- To deal with the above situation, I wrote an ActiveX control, which again is launched from a page to set the required .NET CAS permissions. As long as the user has enough Windows permissions and ActiveX controls are allowed, it doesn’t need anything else to “update” the .NET security policy (for the highest CLR version it finds on the machine). This worked just fine in XP...Then Vista came along…and ActiveX basically lost that ability. It’s signed, marked safe for Scripting and Initialization, but I don’t know of any way for the ActiveX to request elevated Windows permissions to run caspol.exe in order to update the policy. In an exe, I can embed a manifest and require admin rights. Then at runtime Vista will prompt for rights elevation if the user can in fact obtain them. Problem - how can I do the same an ActiveX?
- Anonymous
January 29, 2009
have created a windows library control that accesses a local sql database I tried the following strings for connecting Dim connectionString As String = "Data Source=localhostSQLEXPRESS;Initial Catalog=TimeSheet;Trusted_Connection = true" Dim connectionString As String = "Data Source=localhostSQLEXPRESS;Initial Catalog=TimeSheet;Integrated Security=SSPI" I am not running the webpage in a virtual directory but in C:Inetpubwwwrootusercontrol and I have a simple index.html that tries to read from an sql db but throws the error System.Security.SecurityException: Request for the permission of type 'System.Data.SqlClient.SqlClientPermission, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed. at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet) at System.Security.PermissionSet.Demand() at System.Data.Common.DbConnectionOptions.DemandPermission() at System.Data.SqlClient.SqlConnection.PermissionDemand() at System.Data.SqlClient.SqlConnectionFactory.PermissionDemand(DbConnection outerConnection) at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, etc etc The action that failed was: Demand The type of the first permission that failed was: System.Data.SqlClient.SqlClientPermission The Zone of the assembly that failed was: Trusted I looked into the .net config utility but it says unrestricted and I tried adding it to the trusted internet zones in ie options security I think that a windows form connecting to a sql database running in a webpage should be simple to configure what am I missing?