I am testing CSRF on one website. The website prevents CSRF by checking the referrer field. Now I have created an HTML page which sends the request. How can I add the referrer field to that request using JavaScript or any other method?
A web page shouldn’t be able to add a Referer header to a request using JavaScript. However, according to Wikipedia, there are still some problems with relying on the Referer header:
Some proxies automatically strip out the Referer header. So it’s not always there.
A web page “can suppress the Referer header by issuing requests from FTP or HTTPS URLs.”
“[O]ld versions of Flash (before 9.0.18) allow malicious Flash to generate GET or POST requests with arbitrary HTTP request headers using CRLF Injection.”
Related
I am working on an app and would like to use http post requests to send data from client to server, on which the server uses the origin url from the client to allow to use our services, so my question is, can the http url from the client side be faked as a security threat to access my services, and if so, what other alternatives should i take?
An example is, if a client-side script running on a page from foo.com wants to request data from bar.com, in the request it must specify the header Origin: http://foo.com, and bar must respond with Access-Control-Allow-Origin: http://foo.com.
What is there to stop malicious code from the site roh.com from simply spoofing the header Origin: http://foo.com to request pages from bar?
What is there to stop malicious code from the site roh.com from simply
spoofing the header Origin
The browser is. CORS restrictions and headers only work in the browser and the browser is very strict about controlling them. This is specifically to prevent drive-by attacks from random scripts on random sites a user may unknowingly visit. It’s to protect the user of the browser.
However, absolutely nothing prevents a rogue server from sending an arbitrary HTTP request with any arbitrary headers to your server. I could do so from my command line using curl or such right now. These headers do not pose any sort of guarantee or protection for your server.
'on which the server uses the origin url from the client to allow to use our services'
The origin url can be faked very easily.
Add a login with a token to prevent that.
I want to accept only limit domain requests such as i want to accept all request which comes from www.abc.com and www.xyz.com all other request should be denied . I can't be use token process from server side because multiple domain using my javascript code so here we can't think about server side token and HTTP_ADDR can be manipulate from javascript. Please suggest how to validate it which is reliable?
XMLHttpRequest will insert an Origin header into the request which tells you the site that the request came from.
Use that to populate the Access-Control-Allow-Origin header.
(This, obviously, provides no protection against non-Ajax requests).
It appears that you are trying to prevent Cross Site Request Forgery (CSRF) rather than preventing actors from creating arbitrary cURL requests to your site in order to retrieve data. For this purpose, I recommend the following approach.
For "safe" methods you could check that the Origin header matches your whitelist, and if so you output the Access-Control-Allow-Origin header to match. This is an implementation of CORS.
For "unsafe" methods you could set and check a header such as X-Requested-With is present. It is harder to secure unsafe methods using Origin because old browsers do not send the header, and some new browsers do not send the header for same origin requests.
The above approach only works for AJAX, and not for normal form GET or POSTs or cross domain resource requests.
I'd like to generate a file on a website using JavaScript and provide it for download by the user. I learned that this is not possible using plain JavaScript and HTML5.
I'm thinking of posting the generated file contents to a CGI function on my server that just echoes the data. By setting the right headers I could provide the data for download this way.
I'm wondering if such an echo CGI function could be misused and result in security problems. The website (also the CGI function) is password protected using basic authentication.
Any comments?
It is indeed possible to do this using data: URLs:
text file
However, if you still wish to use the CGI method, there are security risks of allowing a page to echo POSTed data. This is known as reflected Cross Site Scripting (XSS).
Say you have a CGI listening on https://example.com/cgi-bin/downloader.
Assume the user is already authenticated with your basic authentication and then receives an email containing a link. The user visits the website in the email (say evil.com) which creates a POST request submitted by JavaScript to https://example.com/cgi-bin/downloader containing a HTML document which also contains some JavaScript to send the cookies from your domain to the attacker. Even if you are setting the correct content-type header to identify the HTTP response as XML, some browsers (IE) will try to sniff the content and present the Content Type that the browser thinks it is to the user (HTML in this case). To avoid this, make sure that the following header is set in the response:
X-Content-Type-Options: nosniff
So using this header in combination with a Content Type of text/xml in the response should mitigate the risk of XSS. I also recommend the Content-Disposition header being set so the file will be downloaded rather than displayed:
Content-Disposition: attachment; filename="bar.xml"
To prevent other sites making requests to your CGI service in the first place, you could use a CSRF prevention method. The recommended method is the "Synchronizer Token Pattern" and this involves creating a server side token that is tied to user session that must be submitted with the POST request. Whether this is possible with your system using basic authentication is for you to decide. The Referer header can be used, although this is less secure:
checking the referer is considered to be a weaker form of CSRF protection. For example, open redirect vulnerabilities can be used to exploit GET-based requests that are protected with a referer check and some organizations or browser tools remove referrer headers as a form of data protection. There are also common implementation mistakes with referer checks. For example if the CSRF attack originates from an HTTPS domain then the referer will be omitted. In this case the lack of a referer should be considered to be an attack when the request is performing a state change. Also note that the attacker has limited influence over the referer. For example, if the victim's domain is "site.com" then an attacker have the CSRF exploit originate from "site.com.attacker.com" which may fool a broken referer check implementation. XSS can be used to bypass a referer check.
In short, referer checking is a reasonable form of CSRF intrusion detection and prevention even though it is not a complete protection. Referer checking can detect some attacks but not stop all attacks. For example, if you HTTP referrer is from a different domain and you are expecting requests from your domain only, you can safely block that request.
You should also test this to make sure that script will not be executed when an XML is downloaded using Internet Explorer.
If all it does is echo data coming from the client, I don't see any security issues. That data was already known to the client. You are just changing headers so the browser will allow you to save the contents as a file.
You are not disclosing any information to parties that don't already have access.
Cookie is a special type of HTTP header.
Javascript can retrieve all cookies for the current page (e.g.
https://stackoverflow.com/a/3400787/418439).
However, it is not possible to retrieve the header of the current
page
(Accessing the web page's HTTP Headers in JavaScript)
unless making another request.
Why it is designed in this way? Due to security concern?
I've read that setting document.domain = "example.com" lets me access the parent domain from a subdomain.
Will the same work the other way around?
Let's say my main site is running under http://example.com. All API functions that I want to access via AJAX (GET & POST) are hosted on http://api.example.com.
Will I be able to access api.example.com from example.com?
EDIT: Looking at document.domain again, I don't think that this will solve the problem. The result from calls to api.example.com are not necessary HTML, but output from a PHP script running on the API server. It can be JSON, plain text, etc. so there's no way to set document.domain for that (since it's not an iframe).
You need to set document.domain on BOTH pages
Alternatively set CORS headers on your server:
http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/
A Quick Overview of CORS
Firefox 3.5 and Safari 4 implement the
CORS specification, using
XMLHttpRequest as an “API container”
that sends and receives the
appropriate headers on behalf of the
web developer, thus allowing
cross-site requests. IE8 implements
part of the CORS specification, using
XDomainRequest as a similar “API
container” for CORS, enabling simple
cross-site GET and POST requests.
Notably, these browsers send the
ORIGIN header, which provides the
scheme (http:// or https://) and the
domain of the page that is making the
cross-site request. Server developers
have to ensure that they send the
right headers back, notably the
Access-Control-Allow-Origin header for
the ORIGIN in question (or ” * ” for
all domains, if the resource is
public) .
The CORS standard works by adding new
HTTP headers that allow servers to
serve resources to permitted origin
domains. Browsers support these
headers and enforce the restrictions
they establish. Additionally, for HTTP
request methods that can cause
side-effects on user data (in
particular, for HTTP methods other
than GET, or for POST usage with
certain MIME types), the specification
mandates that browsers “preflight” the
request, soliciting supported methods
from the server with an HTTP OPTIONS
request header, and then, upon
“approval” from the server, sending
the actual request with the actual
HTTP request method. Servers can also
notify clients whether “credentials”
(including Cookies and HTTP
Authentication data) should be sent
with requests.