-
Notifications
You must be signed in to change notification settings - Fork 89
/
UserProjectSecurityChecker.cs
181 lines (156 loc) · 5.85 KB
/
UserProjectSecurityChecker.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/// Copyright (c) Microsoft Corporation. All rights reserved.
using System;
using System.Globalization;
using System.IO;
using Microsoft.VisualStudio.Build.ComInteropWrapper;
namespace Microsoft.VisualStudio.Project
{
/// <summary>
/// Does security validation of a user project before loading the project.
/// </summary>
public class UserProjectSecurityChecker : ProjectSecurityChecker
{
#region fields
/// <summary>
/// The project shim for the main project file.
/// We need this otherwise the msbuild API cannot check the user file.
/// </summary>
private ProjectShim mainProjectShim;
#endregion
#region ctors
/// <summary>
/// Overloaded Constructor
/// </summary>
/// <param name="projectFilePath">path to the project file</param>
/// <param name="serviceProvider">A service provider.</param>
public UserProjectSecurityChecker(IServiceProvider serviceProvider, string projectFilePath) :
base(serviceProvider, projectFilePath)
{
}
#endregion
#region properties
/// <summary>
/// The main projects' shim.
/// </summary>
internal protected ProjectShim MainProjectShim
{
get
{
return this.mainProjectShim;
}
internal set
{
this.mainProjectShim = value;
}
}
#endregion
#region overridden method
/// <summary>
/// Checks if the user file is safe with imports. If it has then the user file is considered unsafe.
/// </summary>
/// <param name="securityErrorMessage">At return describes the reason why the projects is not considered safe.</param>
/// <returns>true if the user project is safe regarding imports.</returns>
protected override bool IsProjectSafeWithImports(out string securityErrorMessage)
{
securityErrorMessage = String.Empty;
string[] directImports = this.SecurityCheckHelper.GetDirectlyImportedProjects(this.ProjectShim);
if(directImports != null && directImports.Length > 0)
{
securityErrorMessage = String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.DetailsUserImport, CultureInfo.CurrentUICulture), Path.GetFileName(this.ProjectShim.FullFileName), directImports[0]);
return false;
}
return true;
}
/// <summary>
/// Checks if the project is safe regarding properties.
/// </summary>
/// <param name="securityErrorMessage">At return describes the reason why the projects is not considered safe.</param>
/// <returns>true if the project has only safe properties.</returns>
protected override bool IsProjectSafeWithProperties(out string securityErrorMessage)
{
securityErrorMessage = String.Empty;
// Now ask the security check heper for the safe properties.
string reasonForFailure;
bool isUserFile;
bool isProjectSafe = this.SecurityCheckHelper.IsProjectSafe(ProjectSecurityChecker.DangerousPropertyProperty,
ProjectSecurityChecker.DefaultDangerousProperties,
this.mainProjectShim,
this.ProjectShim,
SecurityCheckPass.Properties,
out reasonForFailure,
out isUserFile);
// Main project gets precedence over the user project.
// Do not report that since this is only for the user file.
if(!isUserFile)
{
return true;
}
if(!isProjectSafe)
{
securityErrorMessage = this.GetMessageString(reasonForFailure, SR.DetailsProperty);
}
return isProjectSafe;
}
/// <summary>
/// Checks if the project is safe regarding targets.
/// </summary>
/// <param name="securityErrorMessage">At return describes the reason why the projects is not considered safe.</param>
/// <returns>true if the project has only safe targets.</returns>
protected override bool IsProjectSafeWithTargets(out string securityErrorMessage)
{
securityErrorMessage = String.Empty;
// Now ask the security check heper for the safe targets.
string reasonForFailure;
bool isUserFile;
bool isProjectSafe = this.SecurityCheckHelper.IsProjectSafe(ProjectSecurityChecker.DangerousTargetProperty,
ProjectSecurityChecker.DefaultDangerousTargets,
this.mainProjectShim,
this.ProjectShim,
SecurityCheckPass.Targets,
out reasonForFailure,
out isUserFile);
// Main project gets precedence over the user project.
// Do not report that since this is only for the user file.
if(!isUserFile)
{
return true;
}
if(!isProjectSafe)
{
securityErrorMessage = this.GetMessageString(reasonForFailure, SR.DetailsTarget);
}
return isProjectSafe;
}
/// <summary>
/// Checks if the project is safe regarding items.
/// </summary>
/// <param name="securityErrorMessage">At return describes the reason why the projects is not considered safe.</param>
/// <returns>true if the project has only safe items.</returns>
protected override bool IsProjectSafeWithItems(out string securityErrorMessage)
{
securityErrorMessage = String.Empty;
// Now ask the security check heper for the safe items.
string reasonForFailure;
bool isUserFile;
bool isProjectSafe = this.SecurityCheckHelper.IsProjectSafe(ProjectSecurityChecker.DangerousItemsProperty,
ProjectSecurityChecker.DefaultDangerousItems,
this.mainProjectShim,
this.ProjectShim,
SecurityCheckPass.Items,
out reasonForFailure,
out isUserFile);
// Main project gets precedence over the user project.
// Do not report that since this is only for the user file.
if(!isUserFile)
{
return true;
}
if(!isProjectSafe)
{
securityErrorMessage = this.GetMessageString(reasonForFailure, SR.DetailsItem);
}
return isProjectSafe;
}
#endregion
}
}