I have rest api which is publicly available with REST API key authentication, but I want to allow private network to access api without authentication. Is it safe to add global CORS
Access-Control-Allow-Origin: *
Note that I am doing authentication in haproxy:
acl private_ip src -m reg -i (^127\\.0\\.0\\.1)|(^10.*)|(^172\\.1[6-9].*)|(^172\\.2[0-9].*)|(^172\\.3[0-1].*)|(^192\\.168.*)|(^::1$)|(^[fF][cCdD])|(0:0:0:0:0:0:0:1)
I read that setting CORS "*" could cause some security issues in case when there is IP authentication, but as I am not sure how "src" IP address in haproxy is obtained I can't be sure if this security risk is present in my case?
It is strongly recommended against to use IP authentication and a permissive CORS policy together.
CORS allows for script on a page served from one host to process a response from a call to a resource on another host when normally a well-behaved browser would stop script on the page from reading the response. For example where a page on webserver.com includes an AJAX call to a resource on api-server.com.
CORS is enforced by the browser, so if your attacker can make a call to your API then they are able to ignore your CORS header, and this is transitive to anything they can get another user to do by serving them a malicious page.
API authentication (whether by token or by IP) is a server-side protection that allows you to filter your response to the request. Consider the case where your attacker has access to your network. They can make a request to your API and your IP authentication lets them get the data. CORS is not the solution to that, but you of course secure your network well and only your users have access to it.
However, if the attacker controls a website (say, compromised.example.com) then they can send a user on your network a link to their page. When your user goes to the page, they are served a script that makes a call to your API. Because you permit the request based on IP, you provide the response.
This is where CORS comes in. If you have a header allowing '*' on your API responses, then the browser on your network will happily provide the requesting page (served from the attacker who is not on your network) with the response.
So the attacker has unauthenticated access to your API if they can get one of your network's users to browse to their malicious page and exfiltrate any responses that a user on your network can get.
Related
I am learning about CSRF Tokens and how they help secure your web application. I understand the basics of it, but I am confused as to how it works in practice when the web server and api are separate. In practice how is the token generated, added to the HTML and known by the API?
For example, if I host my web app on something like Nginx or S3 and serve APIs via Spring Boot, how does the HTML with the embedded token get generated and passed to the client? Would the Sprint Boot API need to generate the token and HTML and return that to the client? Is there a different flow that am I missing? If this is the case, what is the point of it being embedded in HTML at all?
All of the documentation I have read assumes you are using something like MVC or skips over this entirely.
CSRF protection is only necessary for requests made by a client (for example, a browser) that silently adds credentials for the current user, by sending a session cookie, resending username and password that were previously typed in ("Basic Authentication") or by including a client certificate. This is because users may be tricked into making unwanted such requests by visiting a malicious web page, and these unwanted requests are then made with their credentials, that is, on their behalf.
For requests made by your web server to an API endpoint, this does not apply, therefore the API endpoint need not offer CSRF protection. A web server cannot be tricked into making unwanted requests.
Or can it? Imagine that the web server offers a "proxy" endpoint that converts incoming requests into requests to the API endpoint, and that sends the API response back to the client:
Client --request--> web server --converted request--> API endpoint
Client <--converted response-- web server <--response-- API endpoint
Further imagine that, as part of the request conversion, credentials from the client are forwarded to the API. For example, a session cookie coming from the browser is converted into an Authorization: Bearer <jwt> header that is sent to the API endpoint. Then an unwanted request to the web server endpoint with credentials effectively becomes a request to the API, and a new CSRF vulnerability has appeared: this time on the web server.
The web server must then protect its own "proxy" endpoint against CSRF by issuing and validating a CSRF token.
This project is on nuxtjs.
I don't think is important but maybe it can be some clue.
I need to get order detail information for using axios and below url.
/users/orders/d/20210806000349
but, very weird because axios doesn't request without cookies that url
of course i do set withCredentials: true already
when i change that url to /20210806000349 everyting is okay
someone help me about this?
I need more detail about domains but maybe api domain and nuxt domain are different. in this case you should care about CORS.
what is CORS
Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any origins (domain, scheme, or port) other than its own from which a browser should permit loading of resources. CORS also relies on a mechanism by which browsers make a "preflight" request to the server hosting the cross-origin resource, in order to check that the server will permit the actual request. In that preflight, the browser sends headers that indicate the HTTP method and headers that will be used in the actual request.
MDN
what happen if you request to foreign domain?
user agent send an option request to foreign host
foreign host send response whit some header
user agent looks to Access-Control-Allow-Origin header and if its value is not equal to your domain block request
if request's withCredentials be true look at Access-Control-Allow-Credentials header and if its value be true send request with cookie. otherwise send request without cookie.
figure out myself
get request also preflight options request if domain is different
but in this case chrome doesn't show up options request
i check this on firefox
I need to build a REST API that will be used by one private SPA web application. The problem is that the REST API must be on a different server than the SPA, so it must allow CORS. For two layers of security, the API can require Basic Authentication over SSL plus check for the correct client IP address.
It will not be possible to have a user login process for the API, since it is a service used by the SPA. The user is already logged into the client that hosts the SPA. I will not have access to anything other than the user's ID, and the REST API will have no way to validate this user ID.
Because the user is logged into the client's server, the API can be restricted to requests from the SPA's IP address, but that still potentially could allow anyone on that server to use the API other than the SPA.
Is this adequate protection?
I am considering adding a third layer of protection in the way of an access token, but this would be also fairly simple to uncover. If you know the basic authentication information (easily obtainable) and your IP address matches the expected client IP, then you are able to call the API to get an access token.
Also, with an access token comes the complexity of dealing with expired tokens.
Is it impossible to completely secure an API that requires a web-based client?
How many layers of security are enough?
Someone to explain please (hopefully with simple words for newbies) why a web application built upon a RESTful API can be CSRF exempt?
I received such assertion after asking: Serializing FormView data in JSON, but honnestly I can't figure out why?
Thanks in advance
CSRF or Cross Site Request Forgery, in layman terms, is meant to allow only selected sources(your own website) to submit data to particular url. It prevents misuse of your functionality by other websites or robots.
Say, I have an url for registration, /registration/, but I don't want to allow external submission of POST data to /registration/. So, I would provide a crsf cookie(depending on host and other stuff) when GET request is issued for /registration/, and ensure that same cookie is provided with POST request. This will ensure that users who have requested the registration form(i.e. genuine web users, not robots), would be able to register. It is not completely full-proof, but ensures some level of security.
Now, We don't use CSRF in API's due to following:-
Technically, CSRF is stored as cookie, since browser is not the intended client of API's, it is of no use.
Secondly, API's are supposed to use specialized client and user authentication, thereby eliminating the need for using any CSRF protection.
Thirdly, Restful api's are supposed to be stateless, therefore the order of API calls should not matter, which is essential for working of CSRF.
Note:-
If you have frontend framework like Angular or intend to use api's on browser too, then it is perfectly ok to use CSRF. In that case you are suppose to write two types of authentication for your apis.
Token Based Authentication - for non-browser clients
Session Authentication - for browser based clients (With csrf)
In this case, any request to api must authenticate with atleast one of the authentication.
According to owasp.org:
Cross-Site Request Forgery (CSRF) is a type of attack that occurs when a malicious Web site, email, blog, instant message, or program causes a user's Web browser to perform an unwanted action on a trusted site for which the user is currently authenticated.
This is not an issue for REST Web services because either:
1) you usually want your service to be accessible from multiple applications (Mobile app, browser, etc.)
2) you have to provide a direct authentication for each request, so this kind of attack is not applicable for REST services. The authentication is done by your application (let's say javascript) and no directly by your browser (sending the session id), so even if a malicious application redirect the user to your webpage, it cannot automatically trigger your javascript function to perform the request (and the authentication).
I know I am missing something, but please help me understand. Consider this situation:
I have a website called goodbank.com. URL http://goodbank.com/transfer/ serves a HTML page on GET with a form to transfer money to another account. The form has a random token to prevent CSRF attack. On the server, token validity is checked on POST and the corresponding controller allows only authenticated sessions.
Let's say that in my browser, I login to goodbank.com/. In another tab, I go to robgoodbank.com. As part of the served page, it has javascript to do AJAX request to goodbank.com/transfer/ to get a valid form. It then fills in other fields in the form and does a POST. My account is cleaned out :(
How does existing protection schemes protect against such an attack?
Thanks in advance.
Unless your server allows Cross Origin Resource Sharing, the browser will reject the XMLHttpRequest. As per the link, the XMLHttpRequest sends the Origin header containing the domain from which the request originates. If the server does not respond with Access-Control-Allow-Origin containing a wildcard of that domain, the browser will reject the request. There are actually a number of Access-Control- headers to control access including allowable methods, etc.
For extra protection, your server should check the Origin if it is present and the Referer HTTP header, which will be "http://robgoodbank.com" in your example, and you can also reject the request.
These are by no means foolproof, but do provide extra layers of protection. There are mechanisms (such as extensions) to spoof the Referer, but those would have been employed by the user unless their browser has been compromised in some way. If their browser has been compromised they are in a lot more trouble...