How to secure event grid subscription webhook - azure-eventgrid

What is the best practice to validate that webhook has been sent to my subscription endpoint by azure event grid rather than by other, possibly malicious, service or person.

When you configure webhook URL, you can put a secret token into a query parameter. Then, in your code you can validate this parameter.
For example, for Azure Function webhook, you would use code parameter:
https://myfunctionapp.azurewebsites.net/api/EventGridWebHook1?code=your_functionapp_code

Related

Twilio Studio Flow with AWS Lambda and API Gateway

I have a redirect widget that calls the AWS Lambda using AWS API Gateway. it returns a twiml-gather then will call an external API base on the output I receive on the twiml-gather
for security reasons, I would like to make my AWS API Gateway have an OAuth or API key
right now, I'm not sure how can i achieve this given that using the redirect widget doesnt have an option to input a http-headers (can't use the Twilio function because of 10 seconds time limit)
You can make use of the X-Twilio-Signature here.
You also find some Twilio blog posts on this topic.
Validating Requests are coming from Twilio
https://www.twilio.com/docs/usage/security
If your application exposes sensitive data, or is possibly mutative to your data, then you may want to be sure that the HTTP requests to your web application are indeed coming from Twilio, and not a malicious third party. To allow you this level of security, Twilio cryptographically signs its requests.

AWS Cognito Pre-Token Generation not adding custom claims to ID Token (with ALB setup + Auth Code flow)

I'm adding custom claims to Cognito's ID token using the "Pre Token Generation" trigger.
Problem
The lambda is triggered, but the issued ID Token doesn't include the claims I added. Am I missing something?
My setup
Using OAuth 2.0 with authorization code flow
My client app sits behind a load balancer (alb). The alb interacts with Cognito to get the Access + ID Tokens in the form of a ALBSessionCookie. Very similar to [0]
To get the ID Token, the client calls a custom endpoint to my backend with the ALBSessionCookie. The backend uses that cookie to return a decoded ID Token to the user. This is the ID Token that I expect should have the custom claims included.
[0] https://www.exampleloadbalancer.com/auth_detail.html
Lambda function (pre-token generation trigger)
Format taken from https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-pre-token-generation.html#aws-lambda-triggers-pre-token-generation-example-1
exports.handler = (event, context, callback) => {
event.response = {
"claimsOverrideDetails": {
"claimsToAddOrOverride": {
"my-custom-claims-namespace": JSON.stringify({
"custom-claim-1": "hello",
"custom-claim-2": "hello",
})
}
}
}
callback(null, event)
}
If I can't make this work with ALB, what are some workarounds? Some ideas:
Call Cognito directly for an ID Token (somehow), hoping that will trigger the lambda to issue a JWT with the custom claims
Call Cognito via AmplifyJS
I have a feeling this is expected behavior, though seems like a limitation. Looking here:
https://www.exampleloadbalancer.com/auth_detail.html
We can see that the following steps occur:
ALB receives JWT (ID token, Access Token)
ALB to send access token
ALB receives user info(claims)
I believe the ALB is then not sending the contents of the Decoded ID token (That were manipulated by the Lambda trigger) back to the backend but instead sends the 'user info(claims)' (returned from the UserInfo endpoint) which are not effected by the Cognito trigger.
Yeah the ALB doesn't work that way, the ID Token that Lambda trigger customizes is the one you get when a user Authenticates. There are a couple of options.
Custom User Attributes
The least invasive IMO if instead of adding these attributes in the Lambda trigger, you could have them as custom attributes in Cognito, these I do believe will be in this token. You can sync these attributes at each successful Authorization. That may meet your requirements.
API GW
You could put an API GW either between your LB and your APP or infront of your LB. The API GW does give you a layer in which you can do all this stuff and more with customizing headers, tokens etc. For example you could have a Lambda Authorizer which reads this access token, and returns a context which you can reference in your integration requests back to your backend. It's a bit more involved and will add at least some latency to your app, although you can safely have a large TTL on your auth response because your LB is already doing Auth and you only want some extra attributes. You could also do a re-design and put this all in API GW and get all the bells and whistles it has but you might not need them.
But yeah probably easiest to use the first option if possible as that won't require you to do a redesign and you will just need to change your attribute names to custom:....

Google Drive watch API: How to set request headers/body of notification

https://developers.google.com/drive/api/v3/reference/files/watch
Seeing this documentation, I couldn't find any option to set up additional request headers and body to be sent to my webhook endpoint. So I can't set anything like auth tokens to these notifications, right?
You have multiple options:
Add the token in the URL
Validate with the headers X-Goog-Channel-Token (parameter token) and/or X-Goog-Channel-ID (parameter id)
The first one you simply make Google call a URL with the token backed in. The second one you use data that you know to make sure it's Google who's sending the message.
References
Push Notifications (Google Drive v3 reference)

How to store session in AWS lambda

I have a AWS Lambda function which need to talk to an external API to validate the user using bearer token pass in API request header.
Now I want to store that token in session, so I don't want to call external API every time when user send request again with that token.
So which is a best way to do it with AWS lambda.
Thanks
If this request is coming through API Gateway you should look at using a Customer Authorizer. Rather than storing the token in a session, since Lambda APIs are meant to be stateless, you should validate the token in a Custom Authorizer using the necessary keys. The key(s) would typically be set in an environment variable so you can easily access it and validate the token.
https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html

Custom Authorizer using QueryString

I am trying to restrict user to just view its own data and not anyone else's. So, if a user (bob) tries to hit
/api/v1/get-device-info?username=jon
, I want API gateway to send 403, only allowing username=bob. On the Lambda side, I am getting data from RDS. To solve this, I was looking at Custom Authorizers and got blocked thinking how to establish the identity of the user making the query.
What do you mean "establish the identity of the user"? If you are using Custom Authorizers then the user should be sending a token in the request header that identifies them as your API's user.

Resources