How can I debug my SNS subscription? - amazon-web-services

I have created a basic SNS topic. It's a HTTP (and HTTPS) request a an endpoint on my web server. The web server is not on AWS.
The endpoint the SNS subscription points to sends me an email containing all of the headers of the request. Even if the headers are empty and email will be sent. A request of any kind will result in an email.
The endpoint will process the request regardless of the HTTP verb used (GET, POST, etc).
If I visit the endpoint in my browser, I receive an email. When I try to request a confirmation within the AWS control panel, I get nothing.
I thought this could be down to me using a Let's Encrypt SSL, but I have also tried using a HTTP endpoint, rather than HTTPS, but get the same issue.
How can I debug this? Is there any way of seeing why the request is failing?

When I need to debug http web hooks and such like this, I use this tool:
https://ngrok.com/
to setup a public endpoint that points to my local web server, that I am running in my development environment, so I can see the request come in, and depending on the language (usually .net for me), I can step thru the code as the request is received in my debugger. You'll need to temporarily point your sns topic to this endpoint.
This won't help if you are not getting the request at all, but if there is any question that the request is coming in, but its not being processed correctly, this may help.

Related

How to send email with Amazon SES using a pure HTTP request?

I want to send email using the Amazon SES without using aws-sdk. I need to send it using just a pure HTTP request. In other words, how can I send email with Amazon SES using cURL?
SES has email service and it is possible to quite easily check what is being sent with some external tool to sniff the requests that are being sent from your computer. On the other hand, keep in mind that if you want to do it purely using cURL, you have to also handle authentication and signing your requests before, which will create a lot of additional work.
Here you have example request syntax:
https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.html
Link for the signature (I believe that was the things that oyu were looking for) etc:
https://docs.aws.amazon.com/ses/latest/APIReference/CommonParameters.html
Here you have the link for the endpoints:
https://docs.aws.amazon.com/general/latest/gr/ses.html

Authentication and websockets

I'm doing this -
Load single page application - an apollo client is initialised with a websocket and http link. This happens when the user is logged out, let's say.
The user then logs in without a page reload. The graphql response now contains the session cookie.
Problem - whilst subsequent http requests include the session cookie the websocket connection does not.
How do people solve this problem?
I'm guessing either make all communication with the server via websockets, or, create a new apollo client upon successful sign in and use this for subscriptions.
This is for a chat app. I'm using http and websockets at the moment.

Can I rely on ConnectionId for security with API Gateway Websockets?

I'm working on a project where the backend is built with the serverless framework. Recently, I added a feature using API Gateway's websockets. However, I have my doubts about my particular implementation's security, and wanted to ask how valid they were.
I struggled to build authentication into my websocket routes. There was an authorizer feature, but unfortunately native Javascript APIs provide no way to edit headers in a Websocket message - this means I would have to submit authorization tokens in the url params, which I would prefer not to do.
I came up with a workaround. I have existing HTTP microservices set up on API Gateway with serverless, authenticated through AWS Cognito Identity Federation. My solution was to "piggyback" my websocket authentication onto my HTTP services, as follows.
My client opens a websocket connection, and receives back the connectionId assigned to it by API Gateway.
My client calls an HTTP route with the connectionId, which is authenticated with Cognito. This serves to let my backend know that this particular connectionId is authenticated. I push the connectionId and the Cognito identity to a database, along with other information. This way, later I can find what connectionIds are associated with a particular Cognito identity.
When a client wants to call a "secured" websocket method, the websocket method checks the lookup table to see if that connectionId is associated with the correct Cognito identity. If it is, then the method goes through. Otherwise, the connection is closed.
I found this resource at Heroku on websocket safety which recommends a similar, but not quite identical process: https://devcenter.heroku.com/articles/websocket-security
It recommends the following:
"So, one pattern we’ve seen that seems to solve the WebSocket authentication problem well is a “ticket”-based authentication system. Broadly speaking, it works like this:
When the client-side code decides to open a WebSocket, it contacts the HTTP server to obtain an authorization “ticket”.
The server generates this ticket. It typically contains some sort of user/account ID, the IP of the client requesting the ticket, a timestamp, and any other sort of internal record
keeping you might need.
The server stores this ticket (i.e. in a database or cache), and also returns it to the client.
The client opens the WebSocket connection, and sends along this “ticket” as part of an initial handshake.
The server can then compare this ticket, check source IPs, verify that the ticket hasn’t been re-used and hasn’t expired, and do any other sort of permission checking. If all goes well, the WebSocket connection is now verified."
As far as I can tell, my method are heroku's are similar in that they both use an HTTP method to authenticate, but differ because
1) Heroku's method checks for authentication upon opening, while mine checks afterwards
2) Heroku's method requires generating and storing secure tokens
I don't want to send authorization over the websocket, because I'd have to store it in url params, and I also do not want to generate and store tokens, so I went with my method.
However, I have a couple of doubts about my method as well.
1) Because I don't check authorization on websocket open, in theory this approach is vulnerable to a dDos attack, where an attacker simply opens as many sockets as they can. My assumption here is that the responsibility falls on API Gateway to prevent, with its Leaky Bucket algorithm.
2) My strategy hinges on the connectionId being secure. If an attacker were able to spoof this connectionId, then my strategy would no longer work. I assume this connectionId is issued internally within API Gateway to mark specific connections, and should not be vulnerable as a result. However, I wanted to double check if this was the case.
I would suggest looking into JWT's. It was kind of created for this purpose where you need to have some way to authenticate client-side requests without exposing credentials. It is fully self contained and allows you to not make a request to a database everytime you make a request to validate the user making the request: https://jwt.io/
JWT's are very easy to implement in Serverless and attach to a web socket connection request. You can then do something like add the user IP address to the payload of the JWT and validate that at request time to ensure that the user is 100% validated.

Why am I getting "uri:/carbon/admin/login.jsp, error:required token is missing from the request" when trying to log into WSO2 APIM?

I configured my cluster in AWS for WSO2 API Manager, with load balancers for each section: The store, the publisher, the gateway managers and the gateway workers.
However, when I try to log into the Store, the Publisher or Carbon, with the correct username and password, I get the following error in the logs:
ARN - JavaLogger potential cross-site request forgery (CSRF) attack thwarted
(user:<anonymous>, ip:10.0.1.125, method:HEAD, uri:/carbon/admin/login.jsp,
error:required token is missing from the request)
That's all the information the log gives me, and I know for sure the user/pass is correct. Why can't I log in?
I only posted this question for share the answer, because I couldn't find anything about it on Google.
My problem was that the load balancer was configure to distribute the requests evenly among it's instances. So, when I tried to log in, the request always was sent to a different node, which by definition is a CSRF attack.
As soon as I allowed those requests to be sticky, so a login request from a node goes to itself, the log in works.

Facebook graph real-time updates, verify callback_url on local

In my development enviroment (localhost of course).
Based on this documentation I've sucessfully created a apps token with this:
https://graph.facebook.com/oauth/access_token?client_id=<app-id>&client_secret=<app-secret>&grant_type=client_credentials
then make post request to verify my callback_url to FB graph, like this
https://graph.facebook.com/<app-id>/subscriptions?access_token=my_apps_access_token=user&fields=first_name&callback_url=http://localhost:3000&verify_token=mystringtoken
but it's always return :
{"error":{"message":"(#2200) callback verification failed: ","type":"OAuthException"}}
(I've try using lvh.me:3000)
Is there possible to verify the callback_url using localhost?
From the API documentation:
Your callback server must handle two types of requests.
Facebook servers will make a single HTTP GET to your callback URL when you try to add or modify a subscription. After a successful subscription, Facebook servers will notify your server of changes by issuing HTTP POST requests to the same URL.
From this statement, I would presume that you must provide a publicly accessible URL.
Here is How to . I've explained the proccess.