From ce38f36540f68614b76f58cdc1e3782254351592 Mon Sep 17 00:00:00 2001 From: Lucy Gramley Date: Fri, 8 May 2026 11:04:24 -0700 Subject: [PATCH] Remove legacy WebRole debug proxy component Delete the entire WebRole directory and all references to it. The WebRole component implements a WebSocket-to-V8-debug-port proxy that has multiple security issues (NTVS-003/004/005): - No authentication beyond a source-controlled GUID (CWE-306) - HtmlDecode/HtmlEncode inversion enabling stored XSS (CWE-79) - Unbounded static log buffer enabling memory exhaustion DoS (CWE-400) The legacy V8 --debug protocol (port 5858) was removed in Node.js 8 (2017), making this component non-functional with any modern Node.js. Changes: - Delete Nodejs/Product/WebRole/ directory - Remove WebRole project from NodejsTools.sln - Remove ProjectReference from Nodejs.csproj and TargetsVsix.csproj - Remove PostBuildEvent that copied WebRole DLL - Remove NtvsDebugProxy handler and rewrite rules from all Web.Debug.config templates (product + test) - Remove legacy node --debug flag from iisnode config transforms Fixes ADO#2982592 (NTVS-003), also resolves ADO#2982593 (NTVS-004) and ADO#2982594 (NTVS-005) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- Nodejs/NodejsTools.sln | 15 -- Nodejs/Product/Nodejs/Nodejs.csproj | 6 - .../AzureExpress4App/Web.Debug.config | 16 -- .../AzureNodejsApp/Web.Debug.config | 16 -- .../Web.Debug.config | 16 -- .../TypeScriptAzureWebApp/Web.Debug.config | 16 -- .../TypeScriptAzureWebRole/Web.Debug.config | 16 -- Nodejs/Product/TargetsVsix/TargetsVsix.csproj | 11 - Nodejs/Product/WebRole/Global.asax | 1 - Nodejs/Product/WebRole/Global.asax.cs | 42 --- .../WebRole/Properties/AssemblyInfo.cs | 18 -- Nodejs/Product/WebRole/WebRole.csproj | 75 ------ Nodejs/Product/WebRole/WebSocketProxy.cs | 33 --- Nodejs/Product/WebRole/WebSocketProxy.html | 19 -- Nodejs/Product/WebRole/WebSocketProxyBase.cs | 254 ------------------ .../CloudProject/WebRole1/Web.Debug.config | 16 -- 16 files changed, 570 deletions(-) delete mode 100644 Nodejs/Product/WebRole/Global.asax delete mode 100644 Nodejs/Product/WebRole/Global.asax.cs delete mode 100644 Nodejs/Product/WebRole/Properties/AssemblyInfo.cs delete mode 100644 Nodejs/Product/WebRole/WebRole.csproj delete mode 100644 Nodejs/Product/WebRole/WebSocketProxy.cs delete mode 100644 Nodejs/Product/WebRole/WebSocketProxy.html delete mode 100644 Nodejs/Product/WebRole/WebSocketProxyBase.cs diff --git a/Nodejs/NodejsTools.sln b/Nodejs/NodejsTools.sln index 906c844bc..8a5f4e6f2 100644 --- a/Nodejs/NodejsTools.sln +++ b/Nodejs/NodejsTools.sln @@ -12,8 +12,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Product", "Product", "{F971 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjectWizard", "Product\ProjectWizard\ProjectWizard.csproj", "{DBC73DF7-1B4C-48BE-8B48-715297487E7A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebRole", "Product\WebRole\WebRole.csproj", "{712D84EC-B2A6-46D1-B030-BA697AE5E554}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Npm", "Product\Npm\Npm.csproj", "{E5EF4B0A-AB41-4B98-8FA8-98D6348003A8}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestAdapterImpl", "Product\TestAdapterImpl\TestAdapterImpl.csproj", "{5085DF35-3A32-4894-835E-E5A3956D4F57}" @@ -72,18 +70,6 @@ Global {DBC73DF7-1B4C-48BE-8B48-715297487E7A}.Release|arm64.Build.0 = Release|Any CPU {DBC73DF7-1B4C-48BE-8B48-715297487E7A}.Release|x86.ActiveCfg = Release|Any CPU {DBC73DF7-1B4C-48BE-8B48-715297487E7A}.Release|x86.Build.0 = Release|Any CPU - {712D84EC-B2A6-46D1-B030-BA697AE5E554}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {712D84EC-B2A6-46D1-B030-BA697AE5E554}.Debug|Any CPU.Build.0 = Debug|Any CPU - {712D84EC-B2A6-46D1-B030-BA697AE5E554}.Debug|arm64.ActiveCfg = Debug|Any CPU - {712D84EC-B2A6-46D1-B030-BA697AE5E554}.Debug|arm64.Build.0 = Debug|Any CPU - {712D84EC-B2A6-46D1-B030-BA697AE5E554}.Debug|x86.ActiveCfg = Debug|Any CPU - {712D84EC-B2A6-46D1-B030-BA697AE5E554}.Debug|x86.Build.0 = Debug|Any CPU - {712D84EC-B2A6-46D1-B030-BA697AE5E554}.Release|Any CPU.ActiveCfg = Release|Any CPU - {712D84EC-B2A6-46D1-B030-BA697AE5E554}.Release|Any CPU.Build.0 = Release|Any CPU - {712D84EC-B2A6-46D1-B030-BA697AE5E554}.Release|arm64.ActiveCfg = Release|Any CPU - {712D84EC-B2A6-46D1-B030-BA697AE5E554}.Release|arm64.Build.0 = Release|Any CPU - {712D84EC-B2A6-46D1-B030-BA697AE5E554}.Release|x86.ActiveCfg = Release|Any CPU - {712D84EC-B2A6-46D1-B030-BA697AE5E554}.Release|x86.Build.0 = Release|Any CPU {E5EF4B0A-AB41-4B98-8FA8-98D6348003A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E5EF4B0A-AB41-4B98-8FA8-98D6348003A8}.Debug|Any CPU.Build.0 = Debug|Any CPU {E5EF4B0A-AB41-4B98-8FA8-98D6348003A8}.Debug|arm64.ActiveCfg = Debug|Any CPU @@ -209,7 +195,6 @@ Global GlobalSection(NestedProjects) = preSolution {32EC5259-98DA-40CA-9E2D-1B1B2E966F88} = {F9719B35-F359-47A7-A2F8-34F42E53C809} {DBC73DF7-1B4C-48BE-8B48-715297487E7A} = {F9719B35-F359-47A7-A2F8-34F42E53C809} - {712D84EC-B2A6-46D1-B030-BA697AE5E554} = {F9719B35-F359-47A7-A2F8-34F42E53C809} {E5EF4B0A-AB41-4B98-8FA8-98D6348003A8} = {F9719B35-F359-47A7-A2F8-34F42E53C809} {5085DF35-3A32-4894-835E-E5A3956D4F57} = {F9719B35-F359-47A7-A2F8-34F42E53C809} {CB61D8BD-48DC-40F4-A4BA-5B68A10A7481} = {F9719B35-F359-47A7-A2F8-34F42E53C809} diff --git a/Nodejs/Product/Nodejs/Nodejs.csproj b/Nodejs/Product/Nodejs/Nodejs.csproj index bdbbbf21d..fa6a4f7e2 100644 --- a/Nodejs/Product/Nodejs/Nodejs.csproj +++ b/Nodejs/Product/Nodejs/Nodejs.csproj @@ -723,10 +723,6 @@ {cb61d8bd-48dc-40f4-a4ba-5b68a10a7481} PressAnyKey - - {712d84ec-b2a6-46d1-b030-ba697ae5e554} - WebRole - {dbc73df7-1b4c-48be-8b48-715297487e7a} ProjectWizard @@ -1043,8 +1039,6 @@ - mkdir $(OutDir)RemoteDebug\ - copy /y $(OutDir)..\WebRole\Microsoft.NodejsTools.WebRole.dll $(OutDir)RemoteDebug\ - - - - - - - - - - - \ No newline at end of file diff --git a/Nodejs/Product/Nodejs/ProjectTemplates/AzureNodejsApp/Web.Debug.config b/Nodejs/Product/Nodejs/ProjectTemplates/AzureNodejsApp/Web.Debug.config index 9bfddf4b9..1997e30f3 100644 --- a/Nodejs/Product/Nodejs/ProjectTemplates/AzureNodejsApp/Web.Debug.config +++ b/Nodejs/Product/Nodejs/ProjectTemplates/AzureNodejsApp/Web.Debug.config @@ -16,24 +16,8 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/Nodejs/Product/Nodejs/ProjectTemplates/TypeScriptAzureExpressApp/Web.Debug.config b/Nodejs/Product/Nodejs/ProjectTemplates/TypeScriptAzureExpressApp/Web.Debug.config index 9bfddf4b9..1997e30f3 100644 --- a/Nodejs/Product/Nodejs/ProjectTemplates/TypeScriptAzureExpressApp/Web.Debug.config +++ b/Nodejs/Product/Nodejs/ProjectTemplates/TypeScriptAzureExpressApp/Web.Debug.config @@ -16,24 +16,8 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/Nodejs/Product/Nodejs/ProjectTemplates/TypeScriptAzureWebApp/Web.Debug.config b/Nodejs/Product/Nodejs/ProjectTemplates/TypeScriptAzureWebApp/Web.Debug.config index 9bfddf4b9..1997e30f3 100644 --- a/Nodejs/Product/Nodejs/ProjectTemplates/TypeScriptAzureWebApp/Web.Debug.config +++ b/Nodejs/Product/Nodejs/ProjectTemplates/TypeScriptAzureWebApp/Web.Debug.config @@ -16,24 +16,8 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/Nodejs/Product/Nodejs/ProjectTemplates/TypeScriptAzureWebRole/Web.Debug.config b/Nodejs/Product/Nodejs/ProjectTemplates/TypeScriptAzureWebRole/Web.Debug.config index 9bfddf4b9..1997e30f3 100644 --- a/Nodejs/Product/Nodejs/ProjectTemplates/TypeScriptAzureWebRole/Web.Debug.config +++ b/Nodejs/Product/Nodejs/ProjectTemplates/TypeScriptAzureWebRole/Web.Debug.config @@ -16,24 +16,8 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/Nodejs/Product/TargetsVsix/TargetsVsix.csproj b/Nodejs/Product/TargetsVsix/TargetsVsix.csproj index d3e2ac7a3..f6fbe4066 100644 --- a/Nodejs/Product/TargetsVsix/TargetsVsix.csproj +++ b/Nodejs/Product/TargetsVsix/TargetsVsix.csproj @@ -67,17 +67,6 @@ Always - - - {712d84ec-b2a6-46d1-b030-ba697ae5e554} - WebRole - BuiltProjectOutputGroup%3bBuiltProjectOutputGroupDependencies%3bGetCopyToOutputDirectoryItems%3bSatelliteDllsProjectOutputGroup%3b - DebugSymbolsProjectOutputGroup%3b - MSBuild - Microsoft\VisualStudio\v$(VsVersion)\Node.js Tools - True - - VsixSHA2 diff --git a/Nodejs/Product/WebRole/Global.asax b/Nodejs/Product/WebRole/Global.asax deleted file mode 100644 index b9b106458..000000000 --- a/Nodejs/Product/WebRole/Global.asax +++ /dev/null @@ -1 +0,0 @@ -<%@ Application Codebehind="Global.asax.cs" Inherits="Microsoft.NodejsTools.WebRole.Global" Language="C#" %> diff --git a/Nodejs/Product/WebRole/Global.asax.cs b/Nodejs/Product/WebRole/Global.asax.cs deleted file mode 100644 index 962c98fc4..000000000 --- a/Nodejs/Product/WebRole/Global.asax.cs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; - -namespace Microsoft.PythonTools.WebRole -{ - public class Global : System.Web.HttpApplication - { - private void Application_Start(object sender, EventArgs e) - { - // Code that runs on application startup - - } - - private void Application_End(object sender, EventArgs e) - { - // Code that runs on application shutdown - - } - - private void Application_Error(object sender, EventArgs e) - { - // Code that runs when an unhandled error occurs - - } - - private void Session_Start(object sender, EventArgs e) - { - // Code that runs when a new session is started - - } - - private void Session_End(object sender, EventArgs e) - { - // Code that runs when a session ends. - // Note: The Session_End event is raised only when the sessionstate mode - // is set to InProc in the Web.config file. If session mode is set to StateServer - // or SQLServer, the event is not raised. - - } - } -} diff --git a/Nodejs/Product/WebRole/Properties/AssemblyInfo.cs b/Nodejs/Product/WebRole/Properties/AssemblyInfo.cs deleted file mode 100644 index 10f6332a1..000000000 --- a/Nodejs/Product/WebRole/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("A87D74DE-BD73-4FDF-9D76-06D2C76F2460")] diff --git a/Nodejs/Product/WebRole/WebRole.csproj b/Nodejs/Product/WebRole/WebRole.csproj deleted file mode 100644 index ecb09177f..000000000 --- a/Nodejs/Product/WebRole/WebRole.csproj +++ /dev/null @@ -1,75 +0,0 @@ - - - - 16.0 - 4.0 - - - - - false - Debug - AnyCPU - 8.0.30703 - 2.0 - {712D84EC-B2A6-46D1-B030-BA697AE5E554} - {fae04ec0-301f-11d3-bf4b-00c04f79efbc} - Library - Properties - Microsoft.NodejsTools.WebRole - Microsoft.NodejsTools.WebRole - false - SAK - SAK - SAK - SAK - - - AnyCPU - - - - - - - - - - - Global.asax - - - - - - Microsoft400 - StrongName - false - - - - - 1.0.0 - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - 1.0.0 - all - - - - - - - - - - - \ No newline at end of file diff --git a/Nodejs/Product/WebRole/WebSocketProxy.cs b/Nodejs/Product/WebRole/WebSocketProxy.cs deleted file mode 100644 index 0099b6ed2..000000000 --- a/Nodejs/Product/WebRole/WebSocketProxy.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using System.Web; -using Microsoft.VisualStudioTools; - -namespace Microsoft.NodejsTools.Debugger -{ - public class WebSocketProxy : WebSocketProxyBase - { - public override int DebuggerPort - { - get { return 5858; } - } - - public override bool AllowConcurrentConnections - { - get { return false; } - } - - public override void ProcessHelpPageRequest(HttpContext context) - { - using (var stream = GetType().Assembly.GetManifestResourceStream("Microsoft.NodejsTools.WebRole.WebSocketProxy.html")) - using (var reader = new StreamReader(stream)) - { - string html = reader.ReadToEnd(); - context.Response.Write(html); - context.Response.End(); - } - } - } -} diff --git a/Nodejs/Product/WebRole/WebSocketProxy.html b/Nodejs/Product/WebRole/WebSocketProxy.html deleted file mode 100644 index 1610951cd..000000000 --- a/Nodejs/Product/WebRole/WebSocketProxy.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - NTVS remote debugging proxy for Microsoft Azure Web Sites - - - -

NTVS remote debugging proxy for Microsoft Azure Web Sites

- Node.js remote debugging is enabled for this Microsoft Azure web site, and it can be attached to using - Node.js Tools for Visual Studio. To attach, go to - Debug → Attach to Process, switch Transport to "Node.js remote debugging", and enter the appropiate - URL in the Qualifier textbox. -

- - diff --git a/Nodejs/Product/WebRole/WebSocketProxyBase.cs b/Nodejs/Product/WebRole/WebSocketProxyBase.cs deleted file mode 100644 index cb5f6b04a..000000000 --- a/Nodejs/Product/WebRole/WebSocketProxyBase.cs +++ /dev/null @@ -1,254 +0,0 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using System.Net.Sockets; -using System.Net.WebSockets; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using System.Web; -using System.Web.WebSockets; - -namespace Microsoft.VisualStudioTools -{ - public abstract class WebSocketProxyBase : IHttpHandler - { - private static long _lastId; - private static Task _currentSession; // represents the current active debugging session, and completes when it is over - private static volatile StringWriter _log; - - private readonly long _id; - - public WebSocketProxyBase() - { - _id = Interlocked.Increment(ref _lastId); - } - - public abstract int DebuggerPort { get; } - - public abstract bool AllowConcurrentConnections { get; } - - public abstract void ProcessHelpPageRequest(HttpContext context); - - public bool IsReusable - { - get { return false; } - } - - public void ProcessRequest(HttpContext context) - { - if (context.IsWebSocketRequest) - { - context.AcceptWebSocketRequest(WebSocketRequestHandler); - } - else - { - context.Response.ContentType = "text/html"; - context.Response.ContentEncoding = Encoding.UTF8; - - switch (context.Request.QueryString["debug"]) - { - case "startlog": - _log = new StringWriter(); - context.Response.Write("Logging is now enabled. View. Disable."); - return; - - case "stoplog": - _log = null; - context.Response.Write("Logging is now disabled. Enable."); - return; - - case "clearlog": - { - var log = _log; - if (log != null) - { - log.GetStringBuilder().Clear(); - } - context.Response.Write("Log is cleared. View."); - return; - } - - case "viewlog": - { - var log = _log; - if (log == null) - { - context.Response.Write("Logging is disabled. Enable."); - } - else - { - context.Response.Write("Logging is enabled. Clear. Disable.

");
-                                context.Response.Write(HttpUtility.HtmlDecode(log.ToString()));
-                                context.Response.Write("
"); - } - context.Response.End(); - return; - } - } - - ProcessHelpPageRequest(context); - } - } - - private async Task WebSocketRequestHandler(AspNetWebSocketContext context) - { - Log("Accepted web socket request from {0}.", context.UserHostAddress); - - TaskCompletionSource tcs = null; - if (!AllowConcurrentConnections) - { - tcs = new TaskCompletionSource(); - while (true) - { - var currentSession = Interlocked.CompareExchange(ref _currentSession, tcs.Task, null); - if (currentSession == null) - { - break; - } - Log("Another session is active, waiting for completion."); - await currentSession; - Log("The other session completed, proceeding."); - } - } - - try - { - var webSocket = context.WebSocket; - using (var tcpClient = new TcpClient("localhost", DebuggerPort)) - { - try - { - var stream = tcpClient.GetStream(); - var cts = new CancellationTokenSource(); - - // Start the workers that copy data from one socket to the other in both directions, and wait until either - // completes. The workers are fully async, and so their loops are transparently interleaved when running. - // Usually end of session is caused by VS dropping its connection on detach, and so it will be - // CopyFromWebSocketToStream that returns first; but it can be the other one if debuggee process crashes. - Log("Starting copy workers."); - var copyFromStreamToWebSocketTask = CopyFromStreamToWebSocketWorker(stream, webSocket, cts.Token); - var copyFromWebSocketToStreamTask = CopyFromWebSocketToStreamWorker(webSocket, stream, cts.Token); - Task completedTask = null; - try - { - completedTask = await Task.WhenAny(copyFromStreamToWebSocketTask, copyFromWebSocketToStreamTask); - } - catch (IOException ex) - { - Log(ex); - } - catch (WebSocketException ex) - { - Log(ex); - } - - // Now that one worker is done, try to gracefully terminate the other one by issuing a cancellation request. - // it is normally blocked on a read, and this will cancel it if possible, and throw OperationCanceledException. - Log("One of the workers completed, shutting down the remaining one."); - cts.Cancel(); - try - { - await Task.WhenAny(Task.WhenAll(copyFromStreamToWebSocketTask, copyFromWebSocketToStreamTask), Task.Delay(1000)); - } - catch (OperationCanceledException ex) - { - Log(ex); - } - - // Try to gracefully close the websocket if it's still open - this is not necessary, but nice to have. - Log("Both workers shut down, trying to close websocket."); - try - { - await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, null, CancellationToken.None); - } - catch (WebSocketException ex) - { - Log(ex); - } - } - finally - { - // Gracefully close the TCP socket. This is crucial to avoid "Remote debugger already attached" problems. - Log("Shutting down TCP socket."); - try - { - tcpClient.Client.Shutdown(SocketShutdown.Both); - tcpClient.Client.Disconnect(false); - } - catch (SocketException ex) - { - Log(ex); - } - Log("All done!"); - } - } - } - finally - { - if (tcs != null) - { - Volatile.Write(ref _currentSession, null); - tcs.SetResult(true); - } - } - } - - private async Task CopyFromStreamToWebSocketWorker(Stream stream, WebSocket webSocket, CancellationToken ct) - { - var buffer = new byte[0x10000]; - while (webSocket.State == WebSocketState.Open) - { - ct.ThrowIfCancellationRequested(); - - Log("TCP -> WS: waiting for packet."); - int count = await stream.ReadAsync(buffer, 0, buffer.Length, ct); - Log("TCP -> WS: received packet:\n{0}", Encoding.UTF8.GetString(buffer, 0, count)); - - if (count == 0) - { - Log("TCP -> WS: zero-length TCP packet received, connection closed."); - break; - } - - await webSocket.SendAsync(new ArraySegment(buffer, 0, count), WebSocketMessageType.Binary, true, ct); - Log("TCP -> WS: packet relayed."); - } - } - - private async Task CopyFromWebSocketToStreamWorker(WebSocket webSocket, Stream stream, CancellationToken ct) - { - var buffer = new ArraySegment(new byte[0x10000]); - while (webSocket.State == WebSocketState.Open) - { - ct.ThrowIfCancellationRequested(); - - Log("WS -> TCP: waiting for packet."); - var recv = await webSocket.ReceiveAsync(buffer, ct); - Log("WS -> TCP: received packet:\n{0}", Encoding.UTF8.GetString(buffer.Array, 0, recv.Count)); - - await stream.WriteAsync(buffer.Array, 0, recv.Count, ct); - Log("WS -> TCP: packet relayed."); - } - } - - private void Log(object o) - { - var log = _log; - if (log != null) - { - log.WriteLine(_id + " :: " + o); - } - } - - private void Log(string format, object arg1) - { - var log = _log; - if (log != null) - { - log.WriteLine(_id + " :: " + format, arg1); - } - } - } -} diff --git a/Nodejs/Tests/TestData/CloudProject/WebRole1/Web.Debug.config b/Nodejs/Tests/TestData/CloudProject/WebRole1/Web.Debug.config index bb11a37e8..e2df86eec 100644 --- a/Nodejs/Tests/TestData/CloudProject/WebRole1/Web.Debug.config +++ b/Nodejs/Tests/TestData/CloudProject/WebRole1/Web.Debug.config @@ -16,24 +16,8 @@ - - - - - - - - - - - - - \ No newline at end of file