HttpWebRequest to different IP than the domain resolves to - c#

Long story short an API I'm calling's different environments (dev/staging/uat/live) is set up by putting a host-record on the server so the live domain resolves to their other server in for the HTTP request.
The problem is that they've done this with so many different environments that we don't have enough servers to use the server-wide host files for it anymore (We've got some environments running off the same servers - luckily not dev and live though :P).
I'm wondering if there's a way to make WebRequest request to a domain but explicitly specify the IP of the server it should connect to? Or is there any way of doing this short of going all the way down to socket connections (Which I'd really prefer not to waste time/create bugs by trying to re-implementing the HTTP protocol).
PS: I've tried and we can't just get a new sub-domain for each environment.

One way to spoof a HTTP host header is to set a proxy to the actual server you'd like the request sent to. Something like
request.Proxy = new WebProxy(string.Format("http://{0}/", hostAddress));
may well work.

There are ways to control configuration values.
You have conditional compilation enabled in .NET, in which you can create your configuration sets and create directives that can use specific domain instead of changing its resolution strategy. For example, in debug, you can use x.com and in release mode you can use y.com, wherever you need to reference your url.
Web.config and app.config now supports changes as per the configuration selected, you can have web.debug.config and web.release.config and you can specify different url references here.

Related

How to get IIS to serve HTTP connection from custom source with ASP.Net

Here's the scenario: I want IIS to be able to serve URLs from custom sources provided by my code. One example of this would be to serve files from an SQL database instead of the file system (this is an example however, I know about SQL server file tables and those are not the appropriate solution).
I know about HTTP handlers (*.ashx), but somehow, those never play nice with anything. I never got IE's resume download feature to work with them, not to mention streaming video files from mobile devices. There has to be a ton of code in IIS somewhere which decides how to handle all these cases, and I wouldn't want to rewrite it all from scratch and risk missing something critical.
What I'm looking for (and I think it's simple enough) is some callback which asks for some part of the data and lets IIS handle the HTTP response details. If that's not possible, is there any other solution which does not include HTTP handlers?
You can add resumable feature to ASHX files, but needs your implementation as well. because for supporting resume, you need to support accept-ranges and implement it as well in your code. for more info you can check here.
So, it isn't possible to assign your duties to the IIS, because IIS just can handle your requests according to the handle list that you've provided. IIS can't understand database and you must write your own code.

Is there any port specific cookie in asp .net [duplicate]

I have two HTTP services running on one machine. I just want to know if they share their cookies or whether the browser distinguishes between the two server sockets.
The current cookie specification is RFC 6265, which replaces RFC 2109 and RFC 2965 (both RFCs are now marked as "Historic") and formalizes the syntax for real-world usages of cookies. It clearly states:
Introduction
...
For historical reasons, cookies contain a number of security and privacy infelicities. For example, a server can indicate that a given cookie is intended for "secure" connections, but the Secure attribute does not provide integrity in the presence of an active network attacker. Similarly, cookies for a given host are shared across all the ports on that host, even though the usual "same-origin policy" used by web browsers isolates content retrieved via different ports.
And also:
8.5. Weak Confidentiality
Cookies do not provide isolation by port. If a cookie is readable by a service running on one port, the cookie is also readable by a service running on another port of the same server. If a cookie is writable by a service on one port, the cookie is also writable by a service running on another port of the same server. For this reason, servers SHOULD NOT both run mutually distrusting services on different ports of the same host and use cookies to store security sensitive information.
According to RFC2965 3.3.1 (which might or might not be followed by browsers), unless the port is explicitly specified via the port parameter of the Set-Cookie header, cookies might or might not be sent to any port.
Google's Browser Security Handbook says: by default, cookie scope is limited to all URLs on the current host name - and not bound to port or protocol information. and some lines later There is no way to limit cookies to a single DNS name only [...] likewise, there is no way to limit them to a specific port. (Also, keep in mind, that IE does not factor port numbers into its same-origin policy at all.)
So it does not seem to be safe to rely on any well-defined behavior here.
This is a really old question but I thought I would add a workaround I used.
I have two services running on my laptop (one on port 3000 and the other on 4000).
When I would jump between (http://localhost:3000 and http://localhost:4000), Chrome would pass in the same cookie, each service would not understand the cookie and generate a new one.
I found that if I accessed http://localhost:3000 and http://127.0.0.1:4000, the problem went away since Chrome kept a cookie for localhost and one for 127.0.0.1.
Again, noone may care at this point but it was easy and helpful to my situation.
This is a big gray area in cookie SOP (Same Origin Policy).
Theoretically, you can specify port number in the domain and the cookie will not be shared. In practice, this doesn't work with several browsers and you will run into other issues. So this is only feasible if your sites are not for general public and you can control what browsers to use.
The better approach is to get 2 domain names for the same IP and not relying on port numbers for cookies.
An alternative way to go around the problem, is to make the name of the session cookie be port related. For example:
mysession8080 for the server running on port 8080
mysession8000 for the server running on port 8000
Your code could access the webserver configuration to find out which port your server uses, and name the cookie accordingly.
Keep in mind that your application will receive both cookies, and you need to request the one that corresponds to your port.
There is no need to have the exact port number in the cookie name, but this is more convenient.
In general, the cookie name could encode any other parameter specific to the server instance you use, so it can be decoded by the right context.
In IE 8, cookies (verified only against localhost) are shared between ports. In FF 10, they are not.
I've posted this answer so that readers will have at least one concrete option for testing each scenario.
I was experiencing a similar problem running (and trying to debug) two different Django applications on the same machine.
I was running them with these commands:
./manage.py runserver 8000
./manage.py runserver 8001
When I did login in the first one and then in the second one I always got logged out the first one and viceversa.
I added this on my /etc/hosts
127.0.0.1 app1
127.0.0.1 app2
Then I started the two apps with these commands:
./manage.py runserver app1:8000
./manage.py runserver app2:8001
Problem solved :)
It's optional.
The port may be specified so cookies can be port specific. It's not necessary, the web server / application must care of this.
Source: German Wikipedia article, RFC2109, Chapter 4.3.1

C# - How to detect whether a website has a Shared or Dedicated IP Address?

Is it possible to detect whether a website has a dedicated or shared ip address from it's url using C# (Windows Forms application) ? I want to implement a functionality in my application to let write a web address in a TextBox than i click on the Test button. and then show ( Success ) MessageBox if the site has a Dedicated ip address or show a ( Failure ) MessageBox otherwise.
How can i detect whether a website has a Shared or Dedicated IP Address using C#.NET?
You can try, but you'll never have a good result. The best I think you could do is to check the PTR records of the IP, and then check if there are associated A records from different websites. This would still suck however, since a website could have two seemingly different domains that pertain to the same organization (googlemail.com/gmail.com for example).
Also, this assumes the existence of PTR records, multiple ones. I don't think I've seen such a setup supported by most VPS/sharing hosting.
Well, the way I would do it is:
Send HTTP GET to the URL and save the result.
Resolve the URL to an IP.
Send HTTP GET to the IP and save the result.
Compare the two results. (You can do sample checks between the two result)
If the results are the same, then this is dedicated hosting, if the result is different then this is a shared hosting.
Limitations for this method that I can think of now:
Will take you time to figure our a proper comparing method for the
two results.
If shared hosting is configured to default route to the site which you are checking.
Functions to resolve URLs, and do web requests for different programming languages are scattered across the Internet.
From a technical standpoint, there's no such thing as a "shared" or "dedicated" IP address; the protocol makes no distinction. Those are terms used to describe how an IP is used.
As such, there's no programmatic method to answer "is this shared or dedicated?" Some of the other answers to this question suggest some ways to guess whether a particular domain is on a shared IP, but those methods are at best guesses.
If you really want to go down this road, you could crawl the web and store resolved IPs for every domain. (Simple, right?) Then you could query your massive database for all the domains hosted on a given IP. (There are tools that seem to do this already, although only the first one was able to identify the multiple domains I have hosted on my server.)
Of course, this is all for naught with VPS (or things like Amazon EC2) where the server hardware itself is shared, but every customer (domain) gets one or more dedicated IPs. From the outside, there's no way to know how such servers are set up.
TL;DR: This can't be done in a reliable manner.

prevent cross domain requests to my wcf services

I use wcf ui services communicate between my javacsript (jquery) and server side code. I find this work effectively.
However I want to make it more secure. I can I set up wcf so that the requests to the services can only be made from within the same domain, to prevent external clients from making such requests to my services.
So for example, my service opertion url is http://www.website.com/Service.svc/GetProducts. I want to set up wcf so that only requests from pages in the http://www.website.com are allowed. I presume this is in the realm of cross domain wcf requests but need some assistance in setting this up. Help would be great.
This simply isn't possible if your services are exposed to the web.
If something about your services isn't secure enough for that, you should look into fixing that problem - not trying to prevent people from making requests.
Anyone can always use a debugging proxy like Fiddler, Charles, etc. or a tool like WireShark to send any data they want to your services - including a complete replay of a request made via the browser. (Including referrer http headers, etc).
If your situation allows for it, perhaps you might consider using a VPN appliance or something similar, and restrict access to users inside your network (or coming in through the VPN). That way there is less concern about your security of the services.... however it's a known fact that "internal attackers" are just as prevalent, if not more so, than external ones... so don't get too comfy.
Let me head this argument off at the pass too, while I'm at it; someone might suggest that browsers already prevent cross site scripting like that. Yes, that's true. But usually it would be the developer of the other application adding the client side script to call those services - and he/she could just as easily make that request on the server side and proxy the results along to the client.

Connecting to a remote queue via the hosts file

I have different environments for my application (Dev -> Test -> Prod), and I'm using MSMQ.
I also have the name of the queues (they are remote queues) I use via config files, in the following format:
FormatName:Direct=SERVER_NAME\Private$\MY_QUEUE
My problem is that SERVER_NAME is different in the different environments, and I'd like to delegate that problem to the server (ie: for databases I have aliases with the same name in all 3 servers, and they each point to the actual db server)
I tried adding the queue server to the hosts file, but it failed with the following error:
The queue does not exist or you do not have sufficient permissions to perform the operation.
I tried FormatName:Direct, FormatName:OS, and FormatName:TCP
Any help (workaround, new ideas, how to make that work) would be highly appreciated.
The objective is to have a single config file that would work in all environments.
We are also using a hosts file in our environment and found out (the hard way) that MSMQ does not support it.
Our solution is to use an abstraction layer (ITransport) over MSMQ, and let this layer replace host names (that might be found in a hosts file) with ip addresses. It is easily done using the Dns class.
This is just a guess, and I can't verify this at this moment, but:
The reason for the failure is that msmq uses kerberos authentication. Which authenticate both side of the exchange. Your side is accessing the server with the "wrong" name. So when the server tries to authenticate with you(the client). Windows can "tell" that this is not the server you are looking for. So it fails the authentication.
There are probably ways to circumvent that. But it will compromise security. What I would suggest is to put the three names of the destination servers (dev, qa and production) in the config file. And choose between them with some parameter like domain name, user name, computer name or something other like that that is also different in you different environment.
The formatnames that you have specified are not valid. It should be:
FormatName:Direct=OS:SERVER_NAME\Private$\MY_QUEUE
or if you want to use the IP adress instead:
FormatName:Direct=TCP:XXX.XXX.XXX.XXX\Private$\MY_QUEUE

Categories