When opening a project you may have recently downloaded, Visual Studio 2013 briefly warns you to only open projects from trustworthy sources. What are some of the risks to opening projects? Can a project do any harm to your system before compilation, and what damage is possible? Are there any indicators you should be aware of before actually opening projects from "untrustworthy" sources? (Not that I can think of any)
Attack Surface within Visual Studio
There are many attack vectors within Visual Studio. All of them are by design. We developers want complete control over our systems within the build process. Unfortunately, when we say "I want to delete the contents of the cache directory on build", that also means malicious project files can delete just about anything from just about anywhere. Or worse. The compromise is the "Hey. We've given you the keys to the kingdom, but we don't recognize this project. Are you sure you want to open this? We're not responsible if it does something stupid" warning message that you mentioned.
Now consider that many developers run Visual Studio as an administrator.
Here are some of those attack vectors:
Pre- and Post-Build Events
In it's simplest form, untrusted projects could execute a Pre-Build event that would delete files. Or worse. Just about anything can be executed within a Build event. This is the 101 stuff that happens on Compile.
Executions on Project Open
Visual Studio project files are nothing more than big MSBuild configurations. There are a few MSBuild targets that Visual Studio executes when you open a project, all to support the tooling. These targets include Compile, ResolveAssemblyReferences, ResolveCOMReferences, GetFrameworkPaths, and CopyRunEnvironmentFiles. If any of these targets exist, the tasks within them are also executed. Delete files, or worse.
See: 'Design-Time Execution' at http://msdn.microsoft.com/en-us/library/ms171468.aspx
IntelliSense
Part of that tooling mentioned above includes IntelliSense, which executes the Compile task within MSBuild; the CSC/VBC must be executed to get all of the IntelliSense functionality. Because of the nature of IntelliSense, this task is repeatedly executed as you work, rather than the opportunities above that are just run once on open.
See: 'Design-Time IntelliSense' at http://msdn.microsoft.com/en-us/library/ms171468.aspx
Hidden Elsewhere in MSBuild
There is a sea of other routine MSBuild targets that you will manually execute throughout your day, including Build, Rebuild, Test, and Clean. Yes, keep in mind that even clean is a build target, so Clean could delete more than just your old \bin directories.
NuGet
Malicious projects may also expose systems via NuGet. Though Package Restore would not be an issue, the packages.config could specify a different Repository Source. Then, when you install a new package, such as install-package jquery, NuGet will retrieve the jQuery package from the untrusted alternate, rather than from nuget.org. This malicious jQuery package could have all sorts of other 'Goodies' within it that would be executed as a part of the package installation.
This is not a security vulnerability from NuGet, because "you" specified an alternate package source; this is by design, such as Corporations that have their own internal package repository.
What you can do?
At the end of the day, what can you do about this? The answer really is to just not open projects from untrusted sources. The project's packages.config file could be analyzed before you open it, but the big exposure is through MSBuild. Unless you are quite adept at reading through MSBuild schema, I would steer clear.
Related
I need to copy standard component DLLs into a standard folder defined in every VS2012 project when the project is opened. We're not allowed to store DLLs in Subversion so I need to reload this folder every time a developer opens the project/solution. I'm looking for an automation solution that will pull DLLs from a centralized location and copy them into the developer's solution. I looked at Visual Studio Extensions but it seems like an awful lot of work just to copy a couple of files. Are there any other hooks in VS2012 (and hopefully VS2010) where I can code simple PowerShell scripts to copy these files?
It turns out AntHillPro has it's own functionality for storing common DLLs and loading them into folders in your Solution before building. It's not as elegant as an MSBuild pre-build task but it fits in with the model followed by our Java builds with some slight tweaking.
Why you just do no use Nuget? Adding nuget reference and enable nuget restore on build will do exactly what you need. You can create nuget repository as shared folder.
Normally "continuous package integration" involves source control, a build server, and participating teams fetching updated packages as often as they like. But I'm looking for a more extreme version of this story - without CM - that happens entirely on a developer's machine, all in one swoop. A more detailed description of what I want goes like this...
Using Visual Studio 2010 or 2012, assume a "foo.csproj" application that implements a plugin system. Each plugin represents a nuget package and has a corresponding Visual Studio project. Each of these projects is part of the same VS solution that contains the base application.
I want the following development story:
Change source code for a plugin.
Build solution, or perform a debug-launch, which causes msbuild to...
rebuild the changed plugin(s)
nuget then packages and uploads each plugin to a local repository (which can be just a subfolder of the VS solution)
rebuild the base application.
refresh the base application's nuget-plugin dependencies, which were just updated in prior steps. Notes:
This assumes MSBuild magically knows not to perform this last step until all plugins are built, packaged, and uploaded.
The "foo" application could itself use nuget.core to refresh the packages, but in this case I'm assuming that the VS build process did this step.
I would like to know if this story is common enough that there are "common" (msbuild?) scripts for this.
My own guess of how this should be handled is as follows:
All plugin projects are placed in a common "Plugins" folder somewhere in the VS solution folder structure.
The base application "project dependencies" are configured with references to all the plugin projects.
Note: I don't like the idea of managing these project dependencies manually.
The base application "foo.csproj" has a build step that scans the "foo.csproj" XML for dependencies it has in the "plugins" folder, and initiates the nuget packaging and deployment for each.
The base application then initiates the nuget "update all". Hopefully this is possible even though msbuild already mid-stride in execution.
In short, the base application is able to instantly consume plugins that have been altered. This is done without check-ins, a build-server, or manual and arbitrary requests to update plugin packages.
If pre-existing scripts do not already exist for this story, then I'll make my own. But I'd still like to know:
Can step 2, immediately above, be converted to something generic? That is, how can I convince msbuild not to build the "base application" until all projects in a particular folder have already been built? Remember, I'd like not to manage the project dependencies manually.
Is there anything flawed with this overall approach?
I would be particularly interested to know if there is an already existing nuget-visual-studio integration that assists with this story that I may have overlooked.
That's quite a long question to answer, so not sure I'm covering everything in this one; I'll do my best. First, your scenario is not uncommon. The first 2 steps of your planned approach seem OK to me (you're free to choose the location of the plug-in projects).
One thing's for sure: you'll have to manually define the build order, because your solution has no idea of knowing whether the projects consuming (NuGet) plug-ins have a dependency to the projects containing the source code for those plug-ins. Instead of using the built-in Build Order dialog in Visual Studio, take a look at this post on the MSDN blog for a correct way of doing this (or you might end up with something that works locally but not on the build server).
The key MSBuild elements in the referred post are the following:
<ProjectReference Include="... foo.csproj">
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
Now, as for the packaging, deployment and consumption of those plug-ins:
Each plug-in project should trigger package creation and publication in a post-build step. This post on my blog contains ZIP-download with quite lot of MSBuild stuff you can use to get started. E.g. I version, package and publish the NuGet package for a class library in Release builds. I'm using the NuGet command line tool to pack (command reference) and push (command reference) the package.
The consuming application project(s) should run NuGet.exe update <packages.config> (command reference) in a pre-build step.
Also pay attention you're NOT running builds in parallel.
How can I make a solution in visual studio so that the .dll dependencies that reside in some other directory totally different from where the solution itself is affected by "get latest".
What I've tried is creating a Dependencies solution folder within the solution itself and added the dlls to it, that way they belong to the solution even though they don't belong to the directory structure of the solution.
So for example the .sln file is in:
D:\tfs\repository\main\SolutionA\solution.sln
and the dlls are in:
d:\tfs\repository\main\SolutionX\Dependencies\Binaries
What I really want to achieve is to have a foolproof way to build the solution, including the following scenario:
1- Have a brand new installation of windows, visual studio, etc.
2- open visual studio
3- find solution.sln on TFS, double click on it so that visual studio gets every project and files in the solution, and opens the solution
4- successfully build
What happens when I try the Dependencies solution folder approach and repeat the scenario above, it will get all the projects within the solution, opens it, but the dependencies solution contents won't be pulled from TFS (although Visual Studio shows them on Solution explorer), which I think is flawed.
Some suggestions that don't involve creating pre/post build scripts are appreciated.
When you attempt to open a solution for the first time using the TFS Source Control Explorer, you may find that not all of your dependencies will be retrieved - the squiggly line may be highlighting some of your missing References.
One work around is to...
SOLUTION SETUP
Checkout all of your source code from TFS (i.e. Main and all of the sub-directories)
Open your solution in Visual Studio (i.e. MyApplication.sln)
In the solution explorer, create a New Solution Folder called ThirdPartyDll, and then add the appropriate assembly references (i.e. Assembly1.dll, Assembly2.dll,...)
Check-in your solution to TFS
SAMPLE FILE STRUCTURE
Main
MyApplication.sln
Source
MyProjectA
MyProjectA.csproj
MyProjectB
MyProjectB.csproj
Dependencies
Assembly1.dll
Assembly2.dll
You've run into a limitation of the "Open from Source Control" functionality. If you added the solution to source control from Visual Studio you should have seen the following message:
"The project that you are attempting to add to source control may cause other source control users to have difficulty opening this solution or getting newer versions of it. To avoid this problem, add the project from a location below the binding root of the other source controlled projects in the solution."
Open from Source Control will create a workspace mapping for the solutions root directory (D:\tfs\repository\main\SolutionA) but not a separate one for the SolutionX folder which is a peer to SolutionA. On the "new" machine you will need to manually create a workspace mapping to d:\tfs\repository\main in order to get both the SolutionA and SolutionX folder.
Create a solution folder and add the dependencies to it, that way when VS gets latest for the solution it will download these files. A bit brittle as people will need to maintain that folder but it works.
Alternatively create a nuget package and use restore packages on build. It will require a couple of extra steps when you create a new developer box (your nuget package repo will need to be added) but it will work for all projects going forward and is less brittle than the solution folder method.
Please hear me out as this question has been modified extensively.
I have an msbuild target that I want to execute after each project in my solution is built from the IDE. I can easily do this by creating an msbuild replica of my solution, but you can't use it within visual studio. You can go through the projects properies as specify an after build process, but this is quite tedious, especially if you have more than 2 projects.
Is there a better way to execute a target for all projects in a solution within the IDE? I just can't believe that VS2010 doesn't give you an easier option.
BTW, does VS 2012 Beta support a full MsBuild file instead of the brain dead solution file?
What I get from your question is that you've extended the build process and then created a 'shadow' msbuild file that does what the solution file normally ends up doing during build. As you are aware, solution files are a rather unfortunate visual studio only concept. That issue is nearly impossible to work around.
The idiomatic approach to this problem is leave the solution file alone and modify the individual .csproj files to include the custom build steps that each project would need to be completed according to your process. NuGet does this when you use it, so does NotifyPropertyWeaver. (NuGet works around the solution issue by introducing a '$(SolutionDir)' property)
As an aside, I'm not sure how valuable 'building an installer' is to the individual developer on your team and including in the build seems like it adds friction rather than removes it.
If this is for a custom build server, there's no need to use the solution file at all if you don't mind keeping the two in sync and I'd wholeheartedly recommend that approach.
You can debug msbuild using the visual studio IDE.
There is an undocumented registry switch to enable. See this thorough msdn article:http://blogs.msdn.com/b/visualstudio/archive/2010/07/06/debugging-msbuild-script-with-visual-studio.aspx
Will Visual Studio choke on customized .csproj files?
For example, I wanted to add a Target to update the version number in all AssemblyInfo.cs files. I plan to invoke this from the command line with MSbuild.
As another example, I would like to include the build timestamp into the compile, like so. This would be a pre-compile step (I guess), and unlike the example above, this one would run from within a build inside Visual Studio.
Will VS be ok with this?
As long as the code is a valid MSBuild extension, Visual Studio should be able to handle it. Under the hood the project files are really just MSBuild files and MSBuild does the dirty work of the VS build system. So as long as the file remains a valid MSBuild file it should be just fine.
Yes it does allow customizations. We integrated FxCop with our release-mode builds this way.
It will complain when you first load the project file after it's been edited, saying "it's been tampered with, do you wish to continue loading?" Just hit yes and continue on your merry way. It also lets you check a box to ignore the rest of the projects in the solution for the same warning.