Restrict exposing certain request headers for REST API in browser - rest

I am fetching a GET API using the fetch command in react. When I run the production build, I can see the x-api-key in request header when I inspect in either Google/Firefox (network). This is the API key that my web app uses to make the request and I don't want it to get exposed in the browser's devtools. Any ideas on how to achieve this?

Fundamentally, you rewrite some stuff and proxy the request server side.
There is no way to hide the x-api-key header if you are directly making the request from the client. The only way is to make it from the server, then provide the results to the client.

Related

Including a body in a GET, PUT, or POST request results in response of "You need to enable JavaScript to run this app"?

The short story: If I hit my endpoint /api/something with a PUT and no body, it goes through to my Lambda (via CF -> API GW -> Lambda). If I add a body to the request, it doesn't work and seems to die before hitting the API Gateway. I'm not sure why it would do this.
The long story:
I've set up a CloudFront distribution that sends requests to /api to our API gateway and all other requests just vend static website resources.
It has been working great so far for our simple use cases. We previously only hit the API Gateway with GET requests, but now we're going to start needing to send PUT or POST requests to the API Gateway. I had to update the CloudFront distribution "behaviors" for the /api path pattern (the one going to the API gateway) to allow all HTTP methods after that, I was able to start getting responses from the API Gateway for PUT and POST responses (previously only worked for GET).
However, I noticed that if I try to send a payload or body with the request (regardless of the request type), I don't think it actually hits the API Gateway or the Lambda that the API Gateway is routing to because I get a response of "You need to enable JavaScript to run this app". I tried looking at the logs but couldn't find anything. The heads shows "Error from cloudfront" but I'm not sure why or where to find what the error was.
Any tips on how to troubleshoot this or what the issue might be?
Update (10/8): I figured out the "enable javascript" thing was coming up because of my custom error pages for 403&404 errors. I deleted them in my development environment and now get a clearer error.
"This distribution is not configured to allow the HTTP request method
that was used for this request. The distribution supports only
cachable requests. We can't connect to the server for this app or
website at this time. There might be too much traffic or a
configuration error. Try again later, or contact the app or website
owner."
However, I still don't know what to do, as the request type (PUT) is enabled and the request works as long as I don't provide a body. Not sure how to get it to be ok with a body at the moment.

Confusion about REST API calls

I have an api gateway installed that I'm trying to program against. Requests work when using apps like Postman but when I try to connect through code in the form of XMLHTTPRequests I get 401... No 'Access-Control-Allow-Origin' header is present on the requested resource. saying that the server doesn't allow cross site calls.
Maybe I'm not fully understanding how this works but it seems that apps like Postman circumvent this somehow. Whereas when I'm trying to access the api from a local file in my browser I bump into this problem.
Do I need to host the webpage I'm calling from to get this to work? Or am I missing something else here?
When the browser issues a XMLHTTPRequest, it checks if the origin (i.e. the domain) of that request is allowed by the endpoint to send requests. The check is done by a preflight request, i.e. a HTTP OPTIONS request which should provide a response containing a Access-Control-Allow-Origin header with the domain originating the request (or * to allow all domains).
Since this is a security measure of the browser, mainly based on the fact that browsing web pages the user may not know which requests are sent to which endpoints, Postman simply does not need to apply it because its requests are explicitly sent by the user himself.
https://developer.mozilla.org/en-US/docs/Glossary/CORS
https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request

What's the REST way to verify an email?

When a user register to my web application I send an email to verify his inbox.
In the email there are a link to a resource like this:
GET /verify/{token}
Since the resource is being updated behind the scenes, doesn't it break the RESTful approach?
How can I do it in a RESTful manner?
What you are talking about is not REST. REST is for machine to machine communication and not for human to machine communication. You can develop a 1st party REST client, which sends the activation to the REST service.
You can use your verification URI in the browser to access the REST client:
# user follows a hyperlink in the browser manually
GET example.com/client/v1/verify/{token}
# asking the client to verify the token
and after that the REST client will get the hyperlink for verification from the REST service and send the POST to the service in the background.
# the REST client follows the hyperlinks given by the service automatically
# the REST client can run either on the HTTP client or server side
GET example.com/api/v1
# getting the starting page of the REST service
# getting the hyperlink for verification
POST example.com/api/v1/verification {token}
# following the verification hyperlink
If you have a server side 1st party REST client, then the HTTP requests to the REST service will run completely on the server and you won't see anything about it in the browser. If you have a client side REST client, then you can send the POST in the browser with AJAX CORS or you can try to POST directly with a HTML form (not recommended). Anyways the activation should be a POST or a PUT.
It depends on what are you trying to do.
Does it fire an email after validating the user for example? If so, it is not an idempotent method and you should use POST.
Example:
POST /users/{id}/verify/{token}
If the method doesn't have any consequence besides the update, I think you should use PUT.
Aren't you overthinking REST? With e-mail verification you want the user to be able to simply click the link from whatever mail user agent he is using, so you'll end up with a simple GET on the server (presented as a hyperlink to the user) with the token either in the path or as part of the query string:
GET http://example.com/verify-email/TOKEN
GET http://example.com/verify-email?token=TOKEN
Either is fine for this use case. It is not really a resource you are getting or creating; just a trigger for some process on the backend.
Why do you think this would run afoul of good design?

Tuleap - REST API with Cross-Origin Resource Sharing

I have a question regarding the Tuleap REST API when used with CORS.
Basically, I'm trying to make a REST call to see the backlog of my project.
Referring to the API Explorer, to do so I need to do a GET call like this: /api/projects/{id}/backlog I also need to add the custom headers X-Auth-Token and X-Auth-UserId to ensure the authentication.
When I do this request with a HTTP Request tool (Poster for Firefox) everything works fine and I get status 200.
The problem now is that I'm trying to develop an application (in angularJS) that would do the same request.
I noticed that when the page is doing the request, it starts by doing a preflight OPTIONS request which is due to the Cross-Origin-Ressource-Sharing.
It seems like the X-Auth-Token and X-Auth-UserId header are being put in the Access-Control-Request-Headers. Because of that I get an unauthorized 401 response code from the server and I can't complete the request.
I've been looking online and couldn't find my answer as how to make this call work.
There was a recent contribution that should remove the need for authentication on all OPTIONS routes in order to enable the preflight: http://gerrit.tuleap.net/#/c/2642/ It was
Integrated in Tuleap 7.2.99.36
Either your version of Tuleap is too old or there is a bug.
Note all calls still require some headers such as "Content-Type: application/json"; the integration tests should provide good examples of how to make calls:
https://tuleap.net/plugins/git/tuleap/tuleap/stable?p=tuleap%2Fstable.git&a=tree&h=9a513f2b7e765f7b9a4f7f72e9d43f40f623fec5&hb=293d47e4006531d3c0d04edfc6e7058e53c7c9c8&f=tests/rest
and
https://tuleap.net/plugins/git/tuleap/tuleap/stable?p=tuleap%2Fstable.git&a=tree&h=4d9071865a42cbd0d40f5f933b4b0b1047c54a8c&hb=293d47e4006531d3c0d04edfc6e7058e53c7c9c8&f=tests/lib/rest

Request builder call not returning when using ssl(https)

I am using GWT. Currently using gwt-rpc to for login authentication. For only login purpose i want to use ssl(https) and so instead of using gwt-rpc i am trying Request Builder and calling a servlet with https.
When in Servlet URL i use protocol as http the request builder works perfectly and response returns to client side(onResponseReceived ). but when i use https in the servlet url then the servlet is gettting called but the response is not returning to the onResponseReceived method of request builder.
my url with http looks like : http://localhost:8888/myproject/myservlet
and with https it looks like :https://localhost/myproject/myservlet
Please give any suggestion or is there any other way to do it.and also is it possible to use ssl over gwt-rpc.
Browser Same origin policy is blocking your requests.
Your page was requested over http, but you are now making an ajax call over https. This is a violation of same origin policy.
To get around, you should serve your original html/servlet over https. This does have a performance cost, but it is the only way to build a secure website.
I'm not familliar with GWT and Request Builder, but whenever I have had problems with HTTPS connections from my code it has come down to certificates and having the right certificate installed in the client or telling the client code where to find the certificate in order to encode the call.
That would be the first avenue I would want to explore in your situation.