How to set FiddlerCore up to monitor all system traffic? - proxy

We are evaluating FiddlerCore for a use-case. Basically, for now we just want to catch all of the endpoints/urls being requested on a system. This works fine in Fiddler, no issues. But we only want to catch them while a certain vendor software is open. So we want to write a plugin to that software that will run when it launches, and then exit when it exits. Hence, using FiddlerCore (hopefully).
As proof-of-concept, I just made a simple app, one form with a textbox, that it should just append each url into the textbox. Simple as simple can be. However, it's not doing anything. I run the app, then refresh a page in my browser, and ... nothing.
Here is the entire (non-generated) code of my program...
using Fiddler;
using System;
using System.Windows.Forms;
namespace ScratchCSharp {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
FiddlerApplication.AfterSessionComplete += FiddlerApplication_AfterSessionComplete;
FiddlerApplication.Startup(8888, FiddlerCoreStartupFlags.Default);
}
private void FiddlerApplication_AfterSessionComplete(Session s) {
textBox1.Invoke((Action)delegate () {
AddText(s.fullUrl);
});
}
public void AddText(string text) {
textBox1.Text += $"{text}\n";
}
}
}
After a little more poking around, I see that FiddlerApplication.IsSystemProxy is returning false. Seems to have to do with that the Startup flag to set as system proxy is no longer honored, and it tells you now to use the Telerik.NetworkConnections.NetworkConnectionManager to set it as the system proxy. But I can't find anywhere that actually says how to do that. The closest thing I could find is this thread which seems to be their official answer to this question. However, it only goes into a lot of talk about WHY they deprecated the flag, and what their thinking was in how they designed its replacement, but not actually into HOW TO USE the replacement. The Demo app also does NOT use these libraries (probably why it doesn't catch anything either).
The biggest problem though, is that the NetworkConnectionsManager class has no public constructor, so you can't create an instance. It is not inheritable, so you can't make a subclass instance. All of the methods on it are instance methods, not static/shared. And there seems to be no method in the libraries which will create an instance of NetworkConnectitonsManager for you.
So while the class is clearly designed to be used as an instance (hence the methods not being static/shared, there doesn't actually seem to be any way to create an instance.
Any help on how to set this thing up to catch all the outgoing URLs on the system?

You can use the following code for starting Fiddler Core and registering it as a system proxy:
FiddlerCoreStartupSettings startupSettings =
new FiddlerCoreStartupSettingsBuilder()
.ListenOnPort(fiddlerCoreListenPort)
.RegisterAsSystemProxy()
.ChainToUpstreamGateway()
.DecryptSSL()
.OptimizeThreadPool()
.Build();
FiddlerApplication.Startup(startupSettings);
Some of the methods are obsolete for now, but I would recommend to stick with them until the NetworkConnectionManager API is improved and finalized.
Also, there is a sample application (that FiddlerCore installer installs on the Desktop), which is useful for a starting point with the development.

Related

NET Core Server Side multiple session Blazor

I'm trying to host my Blazor application on my server.
I spent all the summer on it and I just realized every time I open my website on new device it doesn't create a new session restarting from zero, but continues where I left it. The worst part is there is a login system behind it, so I feel super dumb at the moment.
I really need a big hint on how to fix this "not little" issue.
Is there a way to make server create new session every time someone open the website (without making it loose to other users)?
The solution should be use a Client Template instead, but the performance are really to slow.
UPDATE:
Accounts "user password" are:
- user user
- test test
Download project sample (requires Net Core 3.0)
[SOLUTION] itminus found the solution to my issue.
You have also to add in ConfigureServices in Startup.cs this services.AddScoped<Storage>();
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddScoped<Storage>();
}
every time I open my website on new device it doesn't create a new session restarting from zero, but continues where I left it.
I checkout your code and find that you're using Singleton Pattern to initialize the Storage. If I understand it correctly, this Storage singleton instance will be shared across different users (also across different devices). As this instance will be used to render the Main.razor page, there will be concurrency problems that you're experiencing now .
To fix that issue, the Storage instance should be limited within some specific connection. As you're using Blazor Server Side, you could register the Storage as a Scoped Service:
In Blazor Server apps, a scoped service registration is scoped to the connection. For this reason, using scoped services is preferred for services that should be scoped to the current user, even if the current intent is to run client-side in the browser.
Firstly, remove the static singleton instance :
public class Storage
{
private static Storage instance;
private Storage()
{
}
public static Storage GetInstance()
{
if (Storage.instance == null)
Storage.instance = new Storage();
return Storage.instance;
}
public List<Items>list {get;set;} = new List<Items>();
public string password {get;set;}
}
Register this Class as a scoped service:
services.AddScoped<Storage>();
And then inject this service in your Login.razor and Main.razor :
#inject project.Storage Storage
Finally, you need change all the Storage.GetInstance(). to Storage.:
Storage.list = Order;
...
Storage.password = password;
I notice that you're also creating the Importer/Additional instance using the Singleton Pattern. I would suggest you should refactor them to use Service Injection in a similar way.

Is ControllerBase.Execute(RequestContext) obsolete in MVC5?

I am upgrading a web site from MVC3 to MVC5. I simply used NuGet to install Microsoft.AspNet.Mvc version 5.2.3 and everything seemed to be working fine. But upon closer examination I noticed that this code was no longer running:
public abstract class BaseController : System.Web.Mvc.Controller
{
protected override void Execute(RequestContext requestContext)
{
LogRequest();
UpdateUserSession();
base.Execute(requestContext);
}
}
I found this lifecycle documentation (linked from here) which seems to confirm that Execute is no longer called by MVC.
However, this documentation is unclear, saying
This method is an implementation of Execute. You typically do not have to override this method. Override Initialize or ExecuteCore instead.
I would expect it to say "This method is no longer called by the MVC framework as of version 5 (or maybe 4)." Perhaps even mark it [Obsolete], although there may have been good reasons not to do that.
Furthermore, my testing shows that ExecuteCore does not get called either! It looks like OnActionExecuting is the best place to move the code that used to live in Execute, is that correct?
Maybe it helps to anybody:
Old version:
errorManagerController.Execute(requestContext);
New version:
Response.RedirectToRoute(routeData.Values);

MiniProfiler with Web.API 2; is there a global magic request context object?

I'm trying to setup MiniProfiler on my web api site, and having a hard time getting MiniProfiler.Current to work.
I followed the directions at miniprofiler.com, and have the following in global.asax:
protected void Application_Start()
{
MiniProfilerEF6.Initialize();
// other setup
}
protected void Application_BeginRequest() {
// need to start one here in order to render out the UI
MiniProfiler.Start();
}
protected void Application_EndRequest() {
MiniProfiler.Stop();
}
This uses the default WebRequestProfilerProvider, which stores the actual profile object in HttpContext.Current.Items.
When I ask for MiniProfiler.Current, it looks to HttpContext.Current.
When I make a request for one of my web api URLs:
Application_BeginRequest creates the profiler, store it in HttpContext.Current
in a web api MessageHandler, I can see HttpContext.Current
in a web apu IActionFilter, HttpContext.Current is now null, and my attempt to MiniProfiler.Current.Step("controller:action") fails
my EF queries run from various services do not get recorded, as that miniprofiler hook relies MiniProfiler.Current, which relies on HttpContext.Current, which is null right now
Application_EndRequest fires, and HttpContext.Current is magically back, and so it wraps up the profiler and tells me how long it's been since the request began
I dug through the code, and I can create my own IProfileProvider, to store the profiler object somewhere more reliable than HttpContext.Current, but I don't know where that could be.
I spent a few hours trying things out, but couldn't find a workable solution. The problems:
the IProfileProvider is a global variable; all worker threads in either the MVC or Web API pipeline all have to use the same IProfileProvider
I can dig around in web api RequestContext.Properties to pull out the HttpContext for that request, but that doesn't really help because my IProfileProvider is global across the entire app; If I tell it to store the profile in HttpContext A, then any simultaneous requests for other HttpContexts are going to pollute the profile
I can't rely on any kind of threadstorage because of async/await re-using threads dynamically
I can't stick the profiler object in an Ninject binding with InRequestScope because InRequestScope doesn't seem to work with web api 2.1, but even if I could
everyone says HttpRequestMessage.Properties is the new HttpContext.Current.Items, but again, IProfileProvider is a global variable and I don't know of a way to ensure each request is looking at their version HttpRequestMessage. MiniProfiler.Current can be called from anywhere, so I guess a global IProfileProvider would have to somehow inspect the call stack to and find an HttpRequestMessage there? That sounds like madness.
I'm at a loss. What I really want is a special variable.
The process of putting the question together I figured it out. HttpContext.Current can get lost when you async/await things: Why is HttpContext.Current null after await?
I had to make the web.config change listed there, and adjusted my filters to use Miniprofiler.Current before any awaiting.
Also discussed at https://www.trycatchfail.com/2014/04/25/using-httpcontext-safely-after-async-in-asp-net-mvc-applications/

Determine if Glimpse is running during Application_BeginRequest()

I have installed Glimpse (Glimpse MVC4) and MiniProfiler (with EF support).
I also installed the MiniProfiler plugin for Glimpse.
I have that all wired up and working. I want to allow the configuration of Glimpse to determine if MiniProfiler should start profiling. That is, if Glimpse is enabled (through Glimpse.axd not via a config setting) I want to call MiniProfiler.Start() in the Application_BeginRequest() method. So, something like this:
protected void Application_BeginRequest()
{
if (Glimpse.IsRunning)
{
MiniProfiler.Start();
}
}
Is there a way to determine if Glimpse is enabled?
Technically there is a way, but I'd call it hacky at best. I'll let you decide if it is a good fit for your purposes.
var policyString = HttpContext.Current.Items["__GlimpseRequestRuntimePermissions"].ToString();
RuntimePolicy glimpsePolicy;
RuntimePolicy.TryParse(policyString, out glimpsePolicy);
if (!glimpsePolicy.HasFlag(RuntimePolicy.Off))
{
MiniProfiler.Start();
}
The reason I call it a hack is because while Glimpse may be On at the beginning of request, it may be later turned Off.
An example of this behavior is when Glimpse automatically shuts off once ASP.NET begins to report an unsupported media type, like an image. ASP.NET does not have the ability to know the media type until after the HTTP Handler has run. In this case, Glimpse will say that it is on at the beginning of the request, but then will be off at the end of it.

How to debug a plugin in on-line version?

I've created a plugin and registered it using hte registration tool. I've also added a step that is supposed to handle a message of creation of an instance. Sadly, the intended behavior doesn't occur.
My guess is that something inside the plugin crashes but I have no idea on how to debug it. Setting up breakpoints is not going to work agains on-line version, I understand, so I'm not even trying.
For legal and technical reasons, I won't be able to lift over the solution to an on-premise installation, neither. Is guessing my only option?
For server-side (plugins) I'm using ITracingService. For client-side I log everything to console. The downside with the first is that you actually need to crash the execution to get to see anything. The downside with the latter is that plugins sometimes get executed without GUI being invoked at all.
When it comes to heavier projects, I simply set up a WCF web service that I call from the plugin and write to that. That way, on one screen, I'm executing the plugin while on the other, I'm getting a nice log file (or just put the sent information to on the screen).
You could, for instance, start with a very basic update of a field on the instance of your entity that's being created. When you have that working, you can always fall back to the last working version. If you don't even get that to work, it mean, probably, that you're setting up the plugin registration incorrectly.
A very efficient way would be to lift over the solution to an on-premise version where you have full control but I see in your question that it's not en option.
In case you could lift the solution to an on-premise version, here's a link on how to debug plugins.
Don't forget that you also have access to the ITracingService.
You can get a reference to it in your Execute method and then write to it every so often in your code to log variables or courses of action that you are attempting or have succeeded with. You can also use it to surface more valuable information when an exception occurs.
It's basically like writing to a console. Then, if anything causes the plug-in to crash at runtime then you can see everything that you've traced when you click Download Log File on the error shown to the user.
Beware though - unless your plug-in actually throws an exception (deliberate or otherwise) then you have no access to whatever was traced.
Example:
public void Execute(IServiceProvider serviceProvider)
{
// Obtain the execution context from the service provider.
IPluginExecutionContext context =
(IPluginExecutionContext)serviceProvider.GetService(
typeof(IPluginExecutionContext));
// Get a reference to the tracing service.
ITracingService tracingService =
(ITracingService)serviceProvider.GetService(typeof(ITracingService));
try
{
tracingService.Trace("Getting entity from InputParameters...");
// may fail for some messages, since "Target" is not present
var myEntity = (Entity)context.InputParameters["Target"];
tracingService.Trace("Got entity OK");
// some other logic here...
}
catch (FaultException<OrganizationServiceFault> ex)
{
_trace.Trace(ex.ToString());
while (ex.InnerException != null)
{
ex = (FaultException<OrganizationServiceFault>)ex.InnerException;
_trace.Trace(ex.ToString());
}
throw new InvalidPluginExecutionException(
string.Format("An error occurred in your plugin: {0}", ex));
}
catch (Exception ex)
{
_trace.Trace(ex.ToString());
while (ex.InnerException != null)
{
ex = ex.InnerException;
_trace.Trace(ex.ToString());
}
throw;
}
}

Resources