Request.Headers["Referer"] does not exist - c#

I have a solution with two ASP.NET Core MVC projects. One project (Client) is making a request to the other (Server) using HttpClient. When the action in Server receives the request, I want to get the URL of the thing that sent it. Every article I have read purports Request.Headers["Referer"] as the solution, but in my case Headers does not contain a "referer" key (or "referrer").
When receiving the request in Server, how should I find the URL of the Client that sent it?

That is how you you get the referring url for a request. But the referer isn't the thing that sent the request. The referer gets set in the headers by the browser when a person clicks on a link from one website to go to another website. When that request is made by the browser to the new website the request will typically have the Referer header which will contain the url of the prior website.
The receiving server can't get the url of the "client" making the request, remember a typical web browser client isn't at any url. All the receiving server can get is the IP address of the client typically.
Since you have control of the client software, if you wanted you could have the client put whatever info you want in the header of the request before it's sent to the server and the server could then get that info out of the header.

If you're using HttpClient, then it is up to the site making the request to add that header. It isn't added automatically in this case. So: change the code - or request that the code is changed - so as to add the header and value that you expect. If you are proxying through a request, you might get the value from the current request's Referer header, and add that.
Even in the general case of a browser making the request as part of a normal page cycle, you can't rely on it: the Referer header is often deliberately not sent; depending on the browser version, configuration, whether you're going between different domains, whether it is HTTPS or not, and rel markers on a <a href=... such as "noreferrer".

Related

What is the purpose of th HTTP GET method in forms?

As far as I understand, the GET method asks the server to send something to the client's browser. I set up a HTTPListener in C# and when I access http://localhost:1330/form.html the request I get from the client is: GET /form.html which means that the client is saying "Hey server, I need the HTML code to display that page in the browser", which makes sense.
If I set a <form> with method=POST in form.html, the input fields values are located in the request body which is in context.Request.InputStream in C# which looks similar to this: input_name1=value&input_name2=value2&input_name3=value3... and the URL remains /form.html.
This also makes sense. The client says: "Hey server, take this data that was written in the HTML <input> elements" and the server uses it, maybe storing it in a database or computing something and send it back to the client.
Now if I set the form method to GET, the URL is modified to: /form.html?input_name1=value&input_name2=value2&input_name3=value3 and the context.Request.InputStream remains blank which is the opposite of the POST, in which the InputStream contained the data and the URL had no queries. For me, the GET method in forms doesn't make any sense. Why do we need to get the data from the form client side, send it to the server and then getting it back to client unmodified? Why do I send the data from the browser to C# and then sending it back to browser, if I can just get it client side using simple JavaScript?
In the moment the browser makes the GET request with the queries to the server, the client browser already has that data, so why does it ask the server to give it if it is already at the client's browser?
Generally speaking, an HTTP GET method is used to receive data from the server, while an HTTP POST is used to modify data or add data to a resource.
For example, think about a search form. There may be some fields on the form used to filter the results, such as SearchTerm, Start/EndDate, Category, Location, IsActive, etc, etc. You're requesting the results from the server, but not modifying any of the data. Those fields will be added to the GET request by the client so the server can filter and return the results you requested.
From the MDN article Sending form data:
Each time you want to reach a resource on the Web, the browser sends a
request to a URL. An HTTP request consists of two parts: a header that
contains a set of global metadata about the browser's capabilities,
and a body that can contain information necessary for the server to
process the specific request.
GET requests do not have a request body, so the parameters are added to the URL (this is defined in the HTTP spec, if you're interested).
The GET method is the method used by the browser to ask the server to
send back a given resource: "Hey server, I want to get this resource."
In this case, the browser sends an empty body. Because the body is
empty, if a form is sent using this method the data sent to the server
is appended to the URL.
An HTTP POST method uses the request body to add the parameters. Typically in a POST you will be adding a resource, or modifying an existing resource.
The POST method is a little different. It's the method the browser
uses to talk to the server when asking for a response that takes into
account the data provided in the body of the HTTP request: "Hey
server, take a look at this data and send me back an appropriate
result." If a form is sent using this method, the data is appended to
the body of the HTTP request.
There are plenty of resources online to learn about the HTTP protocol and HTTP verbs/methods. The MDN articles An overview of HTTP, Sending form data, and HTTP request methods should provide some good introductory reading material.

Response.Redirect() or A HREF ?

I see a lot of articles talking about how to use it. But what is the advantage of using Response.redirect in your c#, versus just using ahref in the .aspx file?
Response.Redirect runs on the ASP.NET Server. It can only be using when the server is processing an existing HTTP request. It sends a redirect status code and location to redirect back to the client as part of an HTTP response. Then client can then take that location and send an HTTP request to it. So you end up with:
Client -> Server: Initial request for resource at location X
Server -> Client: Redirect to get resource from location Y
Client -> Server: Request for resource at location Y
A hyperlink (a href) is before any HTTP request is even generated. When you click on a hyperlink, the browser just sends an HTTP request to the location specified by the href. The browser could then response with a redirect.
They're really apples and oranges, because they operate at different times.

MVC HttpGet and HttpPost

Recently I have attended a training in mvc. The trainer said that - As per the security concerns we have to use HttpPost instead of HttpGet. Always use HttpPost.
Can anyone explain - what is the security issue when we use HttpGet?
When transmitting data over secure connection (https) body of the post request is encrypted and practically undreadable, you can only see address where data is going but not the data itself. Get on the other hand has no body and data has to be transmitted in either query string or as a path parameter. While it is true that query string does get encrypted as well, due to request logging on the server and browser it is possible to get hold of that data.
Anyone can insert image on public forum or stackoverflow with link to your web-site. Then happens next:
Browser looks at url in image tag
Browser find cookies corresponding to domain in url
Browser sends request to url with cookies of user
Your server performs action
Browser tries to parse response as image and fails
Browser renders error instead of image
But if you mark your action as Http Post only then this scenario isn't applicable for 90% of sites. But you should also consider that if hacker can create a form on other web-site then he still can make browser to perform request. So you need CSRF. Well, browsers made a lot to prevent cross-site requests, but it's still possible in some scenarios.

Why my REST API clients need JSONP request?

I created REST base webAPI in MVC 4 and hosted on server when I call this from HTML on other domain and on my local pc I need to call it as JSONP request like put callback=? in url so it can be jsonp. My question is that why this is so? if its due to cross domain then how google and facbook and other companies host their api we also call it from our own domain but we dont keep callback=? in their url.
so why my API need callback=? in url if i call it from other domain or on my local pc with simple jquery html.
Its because of the Same Origin Policy imposed by the browsers.
See
http://www.w3.org/Security/wiki/Same_Origin_Policy
http://en.wikipedia.org/wiki/Same_origin_policy
.
Also note that CORS might be a better option than JSONP in the future
http://en.wikipedia.org/wiki/Cross-origin_resource_sharing
EDIT: ------------
If you have gone through above links you would see that JSONP allows users to work-around this Same Origin Policy security measure imposed by the browsers.
Trick is browsers allow tags to refer files in other domains than the origin.
Basically what happens is with JSONP, you send a callback function name to the server appended to the query string. Then the server will pad or prefix it's otherwise JSON request with a call to this function, hence the P in the name to denote response is padded or prefixed.
For example you can create a script tag like
then the target server, should send a response such that
mymethod({normal: 'json response'})
when this repsone is evaluated on the client side (as for any other javascript file) it will effectively call your method with the JSON response from that server.
However, this can only do GET requests.
If you want to make POST (PUT/DELETE) requests you need to use CORS in which server needs to set a specific header beforehand.
Access-Control-Allow-Origin: www.ext.site.com
Hope this helps.
Because of the same-origin policy limitations. The same-origin policy prevents a script loaded from one domain from getting or manipulating properties of a document from another domain. That is, the domain of the requested URL must be the same as the domain of the current Web page. This basically means that the browser isolates content from different origins to guard them against manipulation.

Access YouTube with ASP.NET and YoutubeFisher but gets HTTP Error 403

I'm trying to use YoutubeFisher library with ASP.NET. I make an HttpWebRequest to grab html content, process the contest to extract the video links and display links on the web page. I managed to make it work on localhost. I can retrieve video links and download the video on the locahost. But when I push it to the Server, it works only if I send the request from the same Server. If that page is accessed by a client browser, the client can see the links properly, but when link is clicked the client gets the HTTP Error 403, everytime the client clicks on the link even though the link is correct.
My analysis is that when the Server makes HttpWebRequest to grab HTML contet, it sends HTTP header as well. The HTML content (links to the video file) that is sent back from YouTube server, I think, will reponse to only the request that matches that HTTP header, that is sent from the Server. So, when client clicks on the link it sends request to YouTube server with different HTTP header.
So, I'm thinking of getting the HTTP header from the client, then modify the Server HTTP header to include HTTP header info of the client before making HttpWebRequest. I'm not quite sure if this will work. As far as I know, HTTP heaer cannot be modified.
Below is the code that makes HttpWebRequest from YouTubeFisher library,
public static YouTubeService Create(string youTubeVideoUrl)
{
YouTubeService service = new YouTubeService();
service.videoUrl = youTubeVideoUrl;
service.GetVideoPageHtmlSource();
service.GetVideoTitle();
service.GetDownloadUrl();
return service;
}
private void GetVideoPageHtmlSource()
{
HttpWebRequest req = HttpWebRequest.Create(videoUrl) as HttpWebRequest;
HttpWebResponse resp = req.GetResponse() as HttpWebResponse;
videoPageHtmlSource = new StreamReader(resp.GetResponseStream(), Encoding.UTF8).ReadToEnd();
resp.Close();
}
Client browses the page but the links are there but give HTTP 403:
Browse the page the from the Server itself, everything works as expected:
How do I make HttpWebRequest on the behalf of the client then? Is my analysis of this problem correct?
Thank you for your input.
Use an http monitor such as Charles, Fiddler or even Firebug to find out what additional headers are being sent from the brower in the success case. I suspect you'll need to duplicate one or more of accept, user-agent or referer.
In the past I've just assumed that youtube has those links encoded so that they only work for the original request IP. If that were the case it would be far more difficult. I have no clue if this is the case or not, try forwarding all the header elements you can before going down this route...
The only possibility that comes to mind is that you'd have to use a javascript request to download the page to the client's browser, then upload that to your server for processing, or do the processing in javascript.
Or you could have the client download the video stream via your server, so your server would pass through the data. This would obviously use a ton of your bandwidth.

Categories