I have a REST API backed with Symfony 4.3 and NelmioCorsBundle for the CORS. I would like to understand if by definition/best practice, it's correct that my security team requires me to respond OPTIONS requests indicating methods list (Access-Control-Allow-Methods) only with the methods that actually are meant to be used with the particular requested endpoint, instead of a complete list that are used by my entire API.
There's some documentation that clearly clarifies what is correct? So that it is not subject to different interpretations about how.
The vast majority of tutorials and resources like MDN website, gives examples including all the methods (GET, PUT, PATCH...) but never clarifies that. The NelmioCorsBundle doesn't give us any way to take from routes definition. It's for single configuration only.
The Fetch standard, which is the de facto specification for CORS, makes no prescription about this:
Ultimately server developers have a lot of freedom in how they handle HTTP responses and these tactics can differ between the response to the CORS-preflight request and the CORS request that follows it [...]
In practice, different CORS middleware libraries do different things. Some (like rs/cors) only reflect the one method, whereas others (like Express's CORS middleware) always list all the allowed methods.
You could argue that always listing all the methods allowed by your CORS configuration in the Access-Control-Allow-Methods response header is "safer":
On the one hand, you have to pay a small price in terms of bandwidth, because at most one of the methods listed in the Access-Control-Allow-Methods header is necessary for CORS preflight to succeed.
On the other hand, it provides attackers no incentive to send additional probing requests meant to determine which methods your CORS configuration allows.
If you're worried about revealing too much about other endpoints, you should be able to apply different CORS configurations to different endpoints.
Related
I'm in the process of developing a system which is heavily dependent on a web service which is designed according to REST principles. The connection is over HTTPS, and my issue is finding a good way to identify clients. There are several users from several different companies with several different access levels.
The backend/middleware is written in PHP, and up until now, I have used the $_SESSION to identify users.
After reading more about REST services, I learned that REST services should be stateless and every call should provide all information necessary to handle that call. I interpreted this in the direction that the server should not maintain any states related to specific clients.
Questions:
Does this mean that using $_SESSION[some_identifier] to preserve state between calls is not aligning with the REST style?
I'm now considering using a "short-lived token" logic instead. This token is exchanged with the server on each request, and the server provides a new token in the reply of each request. Is this approach more RESTful?
You should be using the Authorization HTTP header, used by various HTTP authentication systems such as Basic, OAuth2, or your own proprietary extensions.
I'm trying to build a new API using Lumen (even though I'm having second thoughts about that), and am trying to use barryvdh's CORS package. I think I have it setup properly, so decided to do a simple request in angular to the default route setup.
With my current, manually setup API, when I make an API request, I always see 2 requests: the first being an OPTIONS request, the second being the POST/GET/DELETE/whatever. When I hit the Lumen api (on a different subdomain), I only see one request, being the POST or GET I'm testing. Both return me the expected results, but I still get the No 'Access-Control-Allow-Origin' header is present on the requested resource., presumably because there was no OPTIONS request?
Do I not understand CORS well enough? Is this expected? Do I not understand Lumen? I have no idea where I've gone wrong with this one.
You will need to intercept the OPTIONS request in Lumen and make sure it returns the cors headers. See https://gist.github.com/danharper/06d2386f0b826b669552 Also you can try and use Postman (a nice app for testing apis) to inspect if the headers were send correctly. https://www.getpostman.com/.The headers you are looking to add are
'Access-Control-Allow-Origin' '*';
'Access-Control-Allow-Headers' 'Content-Type';
Note the headers can also be added to your web server instead of your app but that's not always a good idea.
I'm having troubles to figure out how web services handle requests and send responses, and how my site/module will handle it. So these are my questions and bellow a little about why i am asking this:
What is the right way to send a request to web service?
How a web-service will usually answer a site requesting?
How a PHP site can send a request to a web-service? Is cURL the right way?
I'm a student who are learning PHP and a lot of other things, and my job now is create a Joomla Module to show information from a web service (probably created in java or something, probably created by me, when i learn java...).
I know i will use http requests to talk with the web service, but i worry im using it wrong (making a request to the url, like the browser).
So, i did a little example site and a example API. The api uses Slim microframework to create routes, access my database and return the content in json (what means: if i access 'api.com/api/something' in my browser i see a plain white page with a lot of json). I pretend this is my web service.
The example site send a request to the API with cURL, reads the content and decode the json and do things. It seems forced to me.
I have not much support to understand web services and if i am in the right way (or far from this).
I would appreciate your help.
You are on the right track. A web service is simply a processing or storage facility intended to be accessed by some other program just like a database or fileserver service.
What is the right way to send a request to a web service
It depends. The most common implementations use SOAP or REST which define additional semantics on top of the HTTP protocol. SOAP uses a single URL as a gateway to the service and more specific selection of the functionality and the relevant data is embedded within an XML payload presented via POST. HTTP is merely a bearer for the message exchange. In REST, the HTTP part is integrated into the semantics of the transaction.
The URL identifies the location of the data (or processing function)
The payload contains only data, usually presented as POSTed JSON or XML,
further REST uses the HTTP verb (GET, POST, PUT, DELETE) to indicate the requested action
the HTTP headers are used to convey transaction meta-data.
How a web service will usually answer a request
I'm not sure what you are asking here. It should report back on the state of the request, any relevant error messages and possibly some data.
The speciifics would be unique to the API and documented.
Is cURL the right way?
While it is possible to do a lot with the HTTP wrappers functionality in PHP, libcurl offers an lot more flexibility. So, yes this it would be hard to implement a REST client without using cURL, OTOH a SOAP client is (usually) less complex at the HTTP tier but life is a lot simpler if you use a SOAP library/framework to abstract the more complex protocol.
For future questions please have one question per entry.
What is the right way to send a request to web service?
That really depends on the web service, what they require. It can be as simple as a short text string, to sending a XML formatted or JSON formatted array. You need to research the relevant web service.
How a web-service will usually answer a site requesting?
Again it depends on the web service. They are not the same. A web service will have documentation on what it expects and how it will respond.
How a PHP site can send a request to a web-service? Is cURL the right way?
Curl is a good method and is usually the method used from within PHP.
When it comes to building my web applications, I know HTTP 2 is going to be recommended for all traffic coming to the site. I understand the security concerns and the reason why it is recommended/forced to be used now.
When it comes the web-based languages I code in and understand such as Ruby, PHP, and Perl.
Is there any special functions that I will have to do to produce a secure connection to my server or all do we need to do is redirect all traffic to https:// over http://?
Basically, my autoloading class in PHP would load all classes and functions for my web application to operate. Would I need to create a SSL.class.php for allowing the connection to be secure within my PHP?
The changes in HTTP/2.0 over HTTP/1.1 are mostly relevant if your application streams large amounts of data to many simultaneous users.
Is there any special functions that I will have to do to produce a secure connection to my server or all do we need to do is redirect all traffic to https:// over http://?
No. HTTP/2.0 does not require TLS. If you want TLS (which, personally, I encourage), you still need to send clients to https://.
Basically, my autoloading class in PHP would load all classes and functions for my web application to operate. Would I need to create a SSL.class.php for allowing the connection to be secure within my PHP?
In most cases, the HTTP layer is a webserver problem, not a PHP-land application code problem.
If you are working on a framework that insists on parsing request headers and managing responses in a very HTTP-like fashion, then yes, you probably need to be aware of some of the changes in the new version of the protocol.
Differences Between HTTP/1.1 and HTTP/2.0 for Developers
Servers can push more data over an established connection in HTTP/2.0. This is really neat if you need to push real-time notifications (e.g. what StackOverflow does).
Better multiplexing and streaming; it's now possible to stream multiple resources over the same HTTP connection.
Source
Unless your application is keenly aware of networking protocols, it shouldn't matter much for our day-to-day CRUD interfaces.
EDIT:
I took the route of separating Api and Web Application. However, the issue with cross-site requests remains. The question below this edit is kind of irrelevant now, except for the fact that the cross-site request issue remains. I will leave the question below for reference and maybe to help others decide what to do in this situation.
/EDIT
I recently started work on a web application and with the intent to develop mobile applications as well, I figured I would like to create a public API. Here are some of the challenges I have encountered:
The API is actually served from a subdomain (api.example.com) which is a problem because I cannot make cross site requests. The only solution I came up with is to add routes for both api.example.com and the non-API routes so that I can make calls without cross-site requests which would actually introduce a lot of redundancies and that is not the route I would like to go (no pun intended).
Here is a little snippet that sets up the routes for the API (I use the Laravel framework):
Route::group(['domain' => Config::get('globals.API_URL_RAW'),
'namespace' => 'MySite\Api\v1',
'prefix' => 'v1'], function(){
Route::post('/register', 'RegistrationController#store');
}
So, as you can see, I have routes that respond to requests from api.example.com/v1/register for example. In the web app I use ajax to access this API, but access to the API is restricted due to cross-site requests.
The go-to solution would probably be to separate the web app and the api completely, but how would I then go about solving the cross-site requests issue ?
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://example.com' is therefore not allowed access.
Also, if I were to separate the API from the web application, I would have to handle the JSON in my web application (the API returns JSON objects) whereas now I can just work with the actual objects.
I am very new to developing Web apis, and I feel like I am not getting something here, so any help would be greatly appreciated.
EDIT:
There is actually a very similar question that tackles the same problem, which can be found here:
Consuming my own Laravel API
However I think cross-site requests issue is not an issue for the questioner, because his API is served from the same domain.