-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Signed the assemblies. #3
Conversation
Created a new sn key and signed the assembly
Why this change? |
Ninject.mvc is signed and has webactivator as a dependency. I could of built my own version of activator but thought it might be better to have a signed version in repo instead. Sent from my Windows Phone From: Phil Haack Why this change? Reply to this email directly or view it on GitHub: ]-----------------------------------------------[ |
/cc @davidebbo I thought the official WebActivator package was signed. |
Whoops, I almost merged that on accident. :) |
This came up before, and then triggered the gigantic forum discussion. But in the end, it was never signed. Not sure we really want to re-open this can of worm. Lots of people are using WebActivator, so I wouldn't want to do this lightly. To summarize, signing makes it more difficult to use assemblies A and B in your project if they are built against different versions of WebActivator. NuGet tries to solve that using binding redirects, but that doesn't work in all cases. |
Yeah, i think the real solution is the improved handling of strong naming in NuGet. We've talked about having NuGet have the ability to auto-sign assemblies in a package if that's the only way it can work (aka the target project is signed). |
Indeed we have. Many times! And this WebActivator specific thread is probably not the place to discuss this. :) OTOH, I do wonder how much actual harm would happen is WebActivator was signed, since it is only used in Web projects, and binding redirects tend to work pretty well there. Typical case where binding redirects don't work is unit tests. Since it runs under its own exe (e.g. xunit.exe), the binding redirect doesn't affect it. However, I don't think anyone would ever expect WebActivator logic to execute in the context of unit tests, so that might be a non-issue here. |
I hadn't realised that this was such a heated debate and to be honest i just don't get wht this is such an issue, but that just me. So does this mean that there will or won't be an offical signed WebActivator version? |
One potential approach is to sign it and use a version that never changes, to avoid some of the issues. So basically it'll always have assembly version 1.0 (the Win32 version can move up as it's not used for resolution). Apparently, JSON.net does something similar. Let me get more feedback on this idea first. |
It’s actually a pretty tough situation. If the latest version becomes signed, then it will in fact break the world because of all the existing packages that use the unsigned version. Seems the only way out is:
Then many apps will end up using both packages side by side, which will probably work, but is an ugly situation. Maybe someone will come up with a better plan... |
Why does that break everybody if the latest becomes signed? |
Scenario:
It won't be a super common situation at first, but give it a few months for new packages to start using signed WebActivator, and things will blow up all over the place. Root of the problem is that you can't have binding redirects that redirect from simple name to strongly named assembly. Binding redirect is only to move up version for a given signature. |
Ah, but I assume Package A's reference to WebActivator (since it's not strongly named) will be a simple by name reference and will thus use signed WebActivator just fine. In other words, I didn't think you need binding redirects for a non-sn assembly. I guess I've never tried it with a non-SN -> SN assembly. |
We should double check, but I'm pretty sure it won't bind. |
I just tried it to be sure and confirmed that it does not work:
So unless there is a trick to make it bind (other than AssemblyResolve event which is a non-starter), then we're out of luck here. |
bummer. |
This might be highly contravercial and i do appologise for that but... Has anyone considered maybe enforcing a strongname policy instead? It will obviously involve a quantity of short term pain but, i believe in the long run it will pay divideneds. Phil Haack [email protected] , 17/12/2012 10:32 PM: bummer.
]-----------------------------------------------[ |
Right, you can't "binding redirect" to something which doesn't have the same fundamental identity (and signed vs. non-signed changes the fundamental identity). |
@cedricbrasey Can you clarify what you mean by 'enforcing a strongname policy'? Related to WebActivator, NuGet, or .NET in general? But note that more and more people are trying to move away from strong naming, so it indeed would likely not be a popular proposal :) |
Hi David Personally I would like to see all assemblies deployed with strong names (NuGet, CodePlex, Git, etc) and for binding redirects to be banned. Deep breath... [Pause for initial backlash] I don’t say this lightly and I believe that I have a good case. So please be patient with me as I explain my thinking. My current client and pretty much all my previous clients (I’m a freelance developer in the UK) have an enforced strong name required policy. Now work that I do is 50% GAC deployed and 50% web and for the GAC work we don’t have a choice but to strong name. So out of habit, everything I produce is strong named. My latest project is, thankfully, a greenfield development and I get to play with all sorts of cool things!!! MVC, Ninject, EF, .net4.5 and more importantly some proper design work. So we are now able to leverage some of the excellent work that the communities have done with regards to tools, methodologies, pattern implementations, utility assemblies, etc. Now because of the rules that my client has regards to strong naming I’ve come to an impasse with Ninject (I’m only picking on Ninject as this was the first assembly that highlighted the issue). Ninject uses WebActivator (Not referenced in code, but used in templates). Not an issue if you don’t sign your assembly, but I big issue if you do as Ninject is strong named but WebActivator isn’t. Not really WebActivator’s or Ninject’s problem. What options are available to me?
Isn’t anyone worried here with option 1 or 3, Option 2 BTW is a non goer as I do actually need to deploy this project? Option 3, couple of issues here. Firstly it’s not very ethical as you are basically ‘borrowing’ someone’s hard graft. Secondly what about bug fixes, support etc? Option 1 scares the cr@p out of me. What we are basically doing here is rebuilding someone else’s code and passing it of as their work. There would be nothing to stop someone from deploying a package with a ‘new’ WebActivator 1.5.2 that did something terrible to the server or to client data… With strong named assemblies you can be confident that the referenced assembly used from your project is what you expect and not a rebuild, or worse, a forgery. And binding redirects, well that’s a rant for another day I think. :) Cedric |
This is probably not the right place to discuss the general signing vs not signing issue, but we can certainly discuss it relating to WebActivator. First, I'd like to understand the scenario better. Since that is the root of the issue, why is it a rule that you have to strong name your assembly? Note that even NuGet packages that are signed are often done with non-secret keys. i.e. they're signed for convenience, but that provides no security whatsoever. So it seems like a pretty arbitrary rule which may have been set by people who don't have full understanding of the security implications (I know you don't always control what clients say...). Note that in the OSS world, what you may view as unethical is actually perfectly acceptable, and very much part of how things work. There is absolutely nothing wrong with taking the code and redistributing it as long as it doesn't violate the license (which is very permissive!). Note that you would not be able to put your package on NuGet and call it WebActivator, so it would have to be a different name. As far as getting updates and fixes, git solves that pretty nicely. All you have to do is fork the repo, and later pull changes to get updates. I'm not saying this is a great approach, but it is certainly more feasible than you make it sound. That being said, I could conceivable own a spin off package called WebActivator.Signed, but I am a bit worried about user confusion. |
Ok, I get the subtleties. I recommend introducing StrongWebActivator or SignedWebActivator or WebActivatorEx, whatever. Maybe add some functional improvements to make it more enticing. Packages should be encouraged to use it, but they can still use basic WebActivator. The hope is that over time the use of WebActivator will drop to zero. The thing is, shipping code should be strongly named. Code Analysis will tell you to do so. And I've seen first-hand the downside of not doing so... crashing code on certain users' machines. The diagnosis came when the team signed their assemblies... and then the CLR's loader told them that the images were corrupt (on these certain machines, for whatever reason). There are no doubt other benefits as well. See Microsoft's documentation about why assemblies should be signed. |
Nice to hear the thoughts of a likeminded developer! |
On the subtleties, I wonder why it has be to have a new name. Why not just using a new (major) version? Users still can choose to install legacy (unsigned) versions, if needed. And as a user, I wonder why I would be confused if it made that way. |
Most of the arguments in favor of signing can be refuted, and for the most part have been in this forum thread. But that can be a religious debate, and this is not the place for it (that thread is). The only reason I see to sign to sign WebActivator is to unblock those who are forced to use signing, as long as it can be done with minimal impact to those who are not. So anyway, let's keep this thread focused on how we can achieve this, rather on further arguments about whether strong naming is good/bad, as we'll just have to agree to disagree on that point :) @mahara: I think things would blow up if it was just a new version, per my previews comment. Does that make sense? So unfortunately, I don't think we can avoid renaming the Package, the assembly and the namespace for things to go smoothly. But then the problem is that it will be hard to make anyone use the new package. One thing that might work is to have a new version of WebActivator (say 2.0) that does nothing other than depend on the new package. This way, people who just install WebActivator in a new project would effectively get the new one. But I need to convince myself that this is indeed not a breaking change, as this can be pretty subtle, and it's easy to overlook scenarios. As for the new name, @andrew-webb's ideas are possible options. Any other ideas? Naming is hard :) |
WebActivator2 WebActivatorForEveryone SublimeWebActivator WebActivator2013 |
A couple other things we didn't cover:
|
@davidebbo: I'm not sure I understand correctly the scenario you presented. Are you saying that an app (probably you meant "an unsigned app") can reference both unsigned and signed WebActivator assemblies? That kinda new to me. |
@mahara: the app wouldn't directly reference both, but would end up doing it indirectly by referencing A and B, and that would blow up. That's why the name can't stay the same. And yes, this only applies to unsigned apps, which is most of them out there. |
OK. So now suppose this new WebActivator package, named WebActivatorEx (or whatever), created. Would it be required to have its "WebActivator" namespace changed or not in case when applied to that scenario? |
Namespace needs to change too. |
@cedricbrasey I would venture to say that even though web activator isn't as popular as JSON.NET it is popular enough to where strong naming would cause major issues for many referencing projects when the version changes and they didn't specifically point to a specific version in their references http://coderjournal.com/2012/04/json-net-strong-naming-and-nuget-woes/ The issue isn't so much the strong naming, it is that when the version changes it has a ripple effect that breaks every referencing project, except for the authors that were the most anal about setting an exact reference version. What really disappoints me about these posts asking for strong naming, is that the poster always thinks that causing major disruptions in the NuGet ecosystem is some how easier than them downloading the source and strong naming it them self. I do think that NuGet needs to be a little more smart about strong named assemblies though. And make separate folders in the lib for strong names. "net45s" for example. Also the ability to search for only strong named assemblies on the site would be a nice thing for people like @cedricbrasey. That way everything is still up to the package publisher and people that have to support companies that are strong-name happy can just search for strong-named assemblies. |
@nberardi |
@mahara what happens if you have the following relation in NuGet package A references signed assembly in package B. signed assembly in package B is updated and the version changes, but package A is not updated? Hint: package A no longer works, because package B was signed. So package A has to be recompiled and published before it will work again. |
Am I missing something here but isn't JSON.net signed? The point that I'm trying to make is that if I write an application that uses version 4.5 of JSON.net (only for example here) I expect and demand that my application only work with this versioned dependency. As this is what was tested and signed off by QA. What I don't want is for another application to decided that what I actually want is version 4.6... 9 times out of 10 there is a good reason why I've bound to a specific version (functionality, bug fix, etc). I did a little checking and looking at the top 30 packages (ordered by downloads) in nuget:- out of the 19 packages out of the 18 assemblies Even nuget.core is signed... Why not have nuget enforce a strong name policy and then use the GAC for assembly storage? After all wasn't that the point behind it's creation? My wish is that WebActivator gets bumped to v2.0.0.0 and signed. |
Wasn't the GAC created to resolve this (amongst other issues) scenario? |
@nberardi |
@cedricbrasey JSON.NET is doing that now but they just started last year after they created a horrible mess in JSON.NET that still hasn't been cleaned up. They fixed the mess by using semVer, which basically means that with each release they don't change the version number of the assembly, so that they aren't constantly breaking all referencing projects. See my blog post that I referenced for more information about what was going on then. Secondly the GAC was created in a different world almost 13 years ago. Where most applications were installed on a desktop, and there was no such thing as a global package service for sharing of packages like NuGet. I think you have to take a deep dive on how version numbers effect signed packages and then combine that with the knowledge of how NuGet references packages. Because signing assemblies isn't bad, but when combined with the reference system in NuGet it becomes a whole different beast that you guys are failing to see. |
@mahara lets not play what if games, because you probably store your signing key with your source like most other users and most open source projects as @davidebbo alluded to earlier, so all that somebody would have to do is modify your code set the same version number as you are using in production and the breach would occur anyways. Hell I could do this with JSON.NET, copy it to your LOB app, and suddenly be copying out all your web service calls and proprietary information going back and forth. Strong naming is not a security mechanism, it has never been and never will be, and using it as such just leads to false assumptions like the one you are making about your LOB app. |
@cedricbrasey Another application wouldn't affect which version of a library you get. But you might use two different third party libraries that were compiled against two different versions of (for example) Json.NET. NuGet's versioning policy does as well as you can do I think. See this series of blog posts: http://blog.davidebbo.com/2011/01/nuget-versioning-part-1-taking-on-dll.html |
@nberardi To certain degrees, yes, I agree that strong naming is not a security mechanism. Especially, when the should-not-be-disclosed signing key made available to public for access. What can I say? :) Perhaps, MS should completely remove the following guideline page as it's misleading and/or inaccurate, don't you think so? Rule DescriptionThis rule retrieves and verifies the strong name of an assembly. A violation occurs if any of the following are true: The strong name protects clients from unknowingly loading an assembly that has been tampered with. Assemblies without strong names should not be deployed outside very limited scenarios. If you share or distribute assemblies that are not correctly signed, the assembly can be tampered with, the common language runtime might not load the assembly, or the user might have to disable verification on his or her computer. An assembly without a strong name has from the following drawbacks: Note that to load and analyze a delay-signed assembly, you must disable verification for the assembly. |
@mahara No reason to remove CA2210, because it is not on by default. Choose "Microsoft Managed Recommend Rules" and see if you find CA2210. It isn't there. |
If only there were a way to tell stupid & pointless FxCop rules to fuck off... :-p |
@bradwilson :) |
I put the current proposal on https://github.com/davidebbo/WebActivator/wiki/Signing-WebActivator, so we have a basis of discussion. |
@nberardi |
@davidebbo |
I pushed a signed WebActivatorEx package to NuGet: http://nuget.org/packages/WebActivatorEx/. Can you please give it a try? Let's call it experimental at this point, as I need more feedback about it being what we really want before starting to advertise it for general use. Thanks! |
I can't do anything until Monday. But consider it first on my to do list. Thanks for going this. |
Thank you @davidebbo - it works for me (tested in VS Express 2012 for Web). Will you be naming it "WebActivatorEx" in NuGet (currently it appears as a second "WebActivator")? Will you be changing the NuGet description of the original WebActivator to point people to the new version? Thanks again for: your open-mindedness, your accommodation of us strong-namers, and for your work. |
The package is named WebActivatorEx, but I made the display name be WebActivator. Once we get more confidence that this will all work without breaking people transitioning, the plan is to unlist the old one so only the new one shows up. |
Closing this since assembly is now signed. |
@davidebbo: Thanks for this! |
Created a new sn key and signed the assembly. Please message me and i'll send you the password or regenerate the SN. What ever is easier