Proxy server cache is dangerous for private data? - c#

Suppose I have a asp.net mvc 3 application with an interface named /getdata, different users connect to the server by my PC client software and get private data using this interface. Different users are identified by their own well-encrypted tokens.
Now the problem is ClientA told us he got another user's data. From the log of ClientA we found he got ClientB's (but they don't know each other, they can't share accounts). I looked through the code of my web application but couldn't find any chance to mix their data.
So I wonder can this happen:
(1) ClientB starts a http request to http://mysite.com/getdata, with his token in the http header, via a web proxy.
(2) The web proxy accesses my web server, get ClientB's data.
(3) My web server approves the request and returns ClientB's data, since everything is correct.
(4) ClientB gets his data and correctly displayed
(5) Almost the same time after ClientB get his data, ClientA starts a same request, with ClientA's token in the header.
(6) The web proxy find the url that ClientA requesting is the same as ClientB's, and the result is still in cache, then returns ClientB's data. Then ClientA gets another's data.
In my web app interface, at the very beginning I already set all the response no-cache, max-age=0 and so on to prevent client-side cache. My question is:
Can the scanario in the image happen?
If yes, how can I prevent the web proxy returning cached data? I can't modify the program of the PC client, and web proxy servers are out of my control.
If no, what's the possible reason that A is getting B's data?

Can the scanario in the image happen?
Yes, this is possible if the clients are using the GET verb to access the /getdata endpoint.
If yes, how can I prevent the web proxy returning cached data? I can't modify the program of the PC client, and web proxy servers are out of my control.
Decorate the controller action that is serving the GetData endpoint with a [NoCache] attribute to ensure that no data gets cached downstream.

Related

One Asp.Net Core Api Service for Multi-site

I want to create only one Asp.Net Core API Service for multiple website. they are almost same but have different content.
i want to know which website call API to return that website's contents.
for example :
Web Site One(angular client) : http://Game.medis.land
Web Site Two(angular client) : http://Tech.medis.land
API(/api/getservices) => return All Services (depend on which site call the API, method return different values)
if Site-One call =>{"previews","reviews"}
if Site-Two call =>{"software","hardware"}
how should i manage this? can i get URL from Header of request? or something else?
There are many ways that you can handle it:
1- ClientType: every clients should introduce theirself for example Client B set a header key in all requests (ex: ClientType:client-b) and you can determine your clients.
2- Origin: you can read the Origin from request headers and determine clients by their domains but I think it's not good idea because may be domains changed any times.
3-Api key: you can generate a unique key for every clients( Guid is a good choice) and clients should set their api key in all request header(ex api-key: XXXXXXXX) and in server side determine the clients by key.
Finally I suggest you that handle clients in a middleware and pass it with http features to your controllers.

HttpClient.SendAsync call results in multiple triggers on service side, returns internal server error

I have an ASP.NET Web API deployed on Azure App service.
I am experiencing following error: For one specific business object my Web API's GET method is returning Internal server error, while for other business objects the same GET method is working fine.
When I debugged my Web API it turned out, that valid business object is returned, but… GET method was triggered multiple times (and on client side I see that it is called only once)
This is an excerpt where Web API is called from client code
// Create HTTP transport objects
HttpRequestMessage httpRequest = new HttpRequestMessage();
httpRequest.Method = HttpMethod.Get;
httpRequest.RequestUri = new Uri(url);
// Set Credentials
if (this.Credentials != null)
{
cancellationToken.ThrowIfCancellationRequested();
await this.Credentials.ProcessHttpRequestAsync(httpRequest, cancellationToken).ConfigureAwait(false);
}
HttpResponseMessage httpResponse = await this.HttpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false);
Besides - if I try to open that same url from browser (e.g.: https://myservice.com/api/businessObject/xxx) - request is performed only once (as it should) and correct results (Json) is displayed in browser.
Any suggestions what to try to figure why call from client side (for specific object) results in multiple Web API service executions and how to fix this?
My Web API service is deriving from System.Web.Http.ApiController
I got some information from exception, but it doesn't seem to be very helpful
Exception thrown: 'Microsoft.Rest.TransientFaultHandling.HttpRequestWithStatusException' in Microsoft.Rest.ClientRuntime.dll The thread 0x27fc has exited with code 0 (0x0)
EDIT
I got some information from Azure Log stream, but that information does not seam to make sense… because this problem happens for one specific business object (and only when requested from my application - not failing from web browser), other business objects are working fine so I don't see how this could be related to access / web.config file...
IIS was not able to access the web.config file for the Web site or application. This can occur if the NTFS permissions are set incorrectly.
IIS was not able to process configuration for the Web site or application.
The authenticated user does not have permission to use this DLL.
..
Ensure that the NTFS permissions for the web.config file are correct and allow access to the Web servers machine account.
Check the event logs to see if any additional information was logged.
Verify the permissions for the DLL.
Install the .NET Extensibility feature if the request is mapped to a managed handler.
Create a tracing rule to track failed requests for this HTTP status code

Server side redirect truncating request payloads

I'm on IIS 6 and I have an ASP.Net 4.0 site that's a single page to serve as a SOAP reverse proxy. I have to modify the return content in order to delete a trouble node from the response and add a tracking node.
In order to facilitate its function as a reverse proxy for all addresses, I have the 404 on the server set to a custom "URL" of "/default.aspx" (the page for my app)
For requests without a payload, it works perfectly - such as for ?WSDL Urls. It requests the proper URL from the target system, gets the response and sends it back - it's pretty utterly transparent in this regard.
However, when a SOAP request is being made with an input payload, the Request.InputStream in the code is always empty. Empty - with one exception - using SOAPUI, I can override the end point and send the request directly to /default.aspx and it will receive the input payload. Thus, I have determined that the custom 404 handler is - when server-side transferring the request - stripping the payload. I know the payload is being sent - I have even wiresharked it on the server to be sure. But then when I add code to log the contents of Request.InputStream it's blank - even though Request.ContentLength shows the right content length for the original request.
I've also been looking for a good way to use ASP.Net to intercept the requests directly rather than allowing the normal IIS 404 handler to take care of it but even with a wildcard mapping, I can't seem to get the settings right nor am I fully confident that it would help. (But I'm hoping it would?)
Finally, I don't have corporate permission to install MVC framework.
Thus, I need either some configuration for IIS I am missing to make this work properly or some other method of ensuring that I get the request payload to my web page.
Thanks!
What about using an HTTP Handler mapped to all requests?
You'll need to add a wildcard application mapping as detailed here and correctly configure your HTTP Handler.

Global variables in WCF REST services

My applciation works as follows
[user]----username/password/domain----->[WCF service]
then i access the domain server to see to which actual DB the user is associated,
after getting that, i validate the user in his actual DB(DB is per domain)
the problem is that i need a place to store the domain name for the following requests against the db.
for example,if the users calls a WCF service operation:
Test()
first the validation procedure is called, (WCF UserNamePasswordValidator) which validates the user password(which is sent as part of the header for REST or as part of the SOAP), and the next function to be called is the Test, but by then i cant tell the domain of the user(to actually serve the request agains that domain..)
I dont want to change the signature of each domain to
Test(string domain)
I cant simply access the headers since i expose the same methods both as REST and as SOAP and the authentication is different for each of them..(one is with headers as with Amazon S3 and the later is using the SOAP standard)
so basically i'm looking for a global, per call storage.(i want to avoid the Per-Call initiation method)
thanks.
EDIT:
Maybe i should use the ThreadStaticAttribute? will that work?
This will not work. You can't store anything in UserNamePasswordValidator. It even doesn't have access to OperationContext because it runs on different thread.
The way to do this is create custom message inspector and extract the information from custom message header to custom operation context extension as Frank mentioned.
WCF knows a Current OperationContext. You can write your own extensions for it. Unrelated to this issue, I used the same mechanics in this NHibernate Session management here, which may work in its concept for you as well. It accesses the InstanceContext, but the concepts are similar.

How to simulate a Host file for the time of one request

I need to access simultaniously multiple instances of a web services with the following Url. The web services is hosted in IIS and has SSL enabled.
https://services.mysite.com/data/data.asmx
Usually, when we do this process manually, we go one by one and update the Windows host file (c:\Windows\System32\drivers\etc\hosts) like this :
192.1.1.100 services.mysite.com
I would like to automate the process and do it with some multithreading. So I cannot change the Host file. Is there a way to simulate a host file when we do a HTTP request in C#?
Thanks!
If you know the IP address of the server's SSL endpoint (which isn't necessarily the same as the server's default IP address), then you could just aim you web-service at that? Obviously the SSL check will fail, but you can disable that through code...
ServicePointManager.ServerCertificateValidationCallback += delegate
{
return true; // you might want to check some of the certificate detials...
};
I think you get the same effect by setting the proxy server of that specific request to the IP address of the actual Web server you want to send the request to.
You can change the URL that your request is hitting at runtime, something like this:
svc.Url = "http://firstServer.com";
So if you create a program that loops through each of your desired servers, just update the URL property directly (that example is taken from WSE 3 based web services).

Categories

Resources