AWS Lambda#Edge/Cloudfront execution flow - amazon-web-services

I am refactoring a project from a third-party company where they add two different Lambda#Edge functions which are triggered by CloudFront.
Basically, the flow is following:
When users call S3 file from web app -> CloutFront fire event which will call Lambda#Edge.
There are two Lambdas: one for counting downloads per user and another one to restrict access.
The problem is that solution is not working and missing a download count check.
What is the execution workflow for Lambda#Edge attached to the same event? I am thinking of placing all the logic inside of one Lambda as I am afraid that counting can happen earlier than access denied. However taking in consideration that lambda#edge have execution time limitation

The documentation is available here.
When a user requests a file there is a viewer request. If the file is in the cache, then a viewer response follows. There is no origin request. For this reason you should authenticate your users on a viewer request.
When the file isn't in the cache, there is an origin request. This is when the file is downloaded from S3.
You could have the logic in a single Lamda#Edge, but you could also:
Authenticate users on Viewer Request.
Count downloads on Viewer Response. A Viewer Response event will be triggered regardless, if there is cache hit or not, but not when the origin returns an HTTP status code of 400 or higher.

Related

fast access management for CDN

I am looking for a quick/cheap way to implement the access management of a CDN containing images.
Please check the diagram
context
A user usually requests a high number of small images (latency should be below 200ms), and a user requests images one by one.
access management
A user updates the permission of an image in the DB
A permission hook is triggered and updates the permission file of the image (add user id in the file)
Upload/update the S3 bucket with the new permission file
invalidate CLOUDFRONT cache for this specific file
image request
A user sends an HTTP request to collect an image
METHOD: GET
URL: URL/image-id.png
HEADER: Authorisation (containing user id)
The edge lambda intercepts the request, validates the token, uses the image id to retrieve the permission file of the image, and finally verifies if the file contains the user id.
If any steps in point 2 fail, then the lambda returns an error message; otherwise forward the request to CDN.
What do you guys think? Is it a terrible idea?

How can I handle a POST from a third party authentication when I need a GET in AWS CloudFront?

I am using AWS Cloudfront to serve static html and images from a private s3 bucket. I need an authentication layer and have a requirement to use Microsoft SSO. To trigger the authentication check, I have a Lambda function connected to a Cloudfront Viewer Request.
From what I understand, I need to return the Request in a callback method when I want to get past the viewer request (after authentication). My issue is that the Microsoft SSO redirect's to the Cloudfront URL using an HTTP POST. If I return the request, Cloudfront attempts to POST to an S3 (or sends a MethodNotAllowed when I disable POST). I need this to be a GET request, but do not know how I can change it. According to the docs, the HTTP of the request object is read only.
I have tried redirecting to the Cloudfront URL when posting or serving a simple HTML that links to the html I want, but these both result in the Viewer Request being called again.
Has anyone handled a similar situation?
You should be able to return a redirect, but set the status code to 303 instead of one of the other 3xx codes. This is See Other which results in the browser following the redirect but using GET on the second request. There is no way to trick CloudFront into believing the method changed -- a redirect is required.

Can I send an HTTP request to an Alexa's Skill Endpoint in order to trigger a reprompt in Alexa?

The scenario would be this.
I would start the skill with the corresponding command ("Alexa, do whatever.."), handle the subsequent LaunchRequest in the Skill Endpoint, and later (minutes later), Alexa would prompt the user with some question.
I'd like to know if I can trigger that late prompt (reprompt actually) in Alexa by sending a request to the corresponding Endpoint from a third Web Service. I guess I can handle HTTP request in the Endpoint (AWS Lambda function or whatever), but I don't know if I can trigger reactions in Alexa withouth it starting them first.
I don't think this would be allowed as it would break a fundamental privacy issue whereby interactions need to be initiated by the user and so be against the Alexa TOS.
If your "reprompt" doesn't actually require some 3rd party trigger e.g if you don't what to run something in response to a code event, then you could look at the reminders API.
You do need to request their permission initially to do this, so it would potentially change your flow somewhat, but then you could prompt them to re-engage with your skill this way.

Distinguish API keys used in Google Cloud Translation API requests

I have an application that uses Google Cloud Translation API for translating contents from a source language to the languages used by the different users.
Since there are several clients for the API, I would like to distinguish the request numbers for different clients, like making a distinction between Android and iOS clients.
There's a dashboard in Google Cloud Translation API Overview page that contains the Traffic chart with a By credential option, which should be able to distinguish the request numbers by their credentials (in our case, API keys.) Unfortunately, it doesn't, the only option available there being Unspecified.
Moreover, even if I change the filter of credentials to No selection, the Traffic map is still the same!
I have also attached the project's credential list, where only API keys are used.
Please help me how to know the request numbers by different API keys, thanks.
Update:
Here are how I send requests to Google Cloud Translation API.
I tried with Postman and Swift code in iOS (what I actually do in my project.) Sent GET/POST requests to the API with API keys and POST requests with service account token, but neither API keys nor service account shown in request logs as the first picture.
Postman
Request with API key in GET
Request with API key in POST
Request with service account token in POST
Swift code
Code
Response
I have also done some requests to Translation API using different credentials. After doing the requests, I have checked my dashboard and I encountered the same situation as you, with all requests marked as Unspecified when choosing the By credential option.
As it turns out, there is an issue related to this situation, as this is not the expected behavior. This has been notified and it will be sorted out by the Google team. You can keep track on any updates related to this issue here. If you click the star button on this site, you will get email notifications whenever any progress has been made. Please bear in mind that it may take some time for this issue to be resolved.
In the meantime, you may consider tracking the client information through the statistics of the applications that make requests to the API, if possible. Thanks for your help on finding this issue.

Security concern in direct browser uploads to S3

The main security concern in direct js browser uploads to S3 is that users will store their S3 credentials on the client side.
To mitigate this risk, the S3 documentation recommends using a short lived keys generated by an intermediate server:
A file is selected for upload by the user in their web browser.
The user’s browser makes a request to your server, which produces a temporary signature with which to sign the upload request.
The temporary signed request is returned to the browser in JSON format.
The browser then uploads the file directly to Amazon S3 using the signed request supplied by your server.
The problem with this flow is that I don't see how it helps in the case of public uploads.
Suppose my upload page is publicly available. That means the server API endpoint that generates the short lived key needs to be public as well. A malicious user could then just find the address of the api endpoint and hit it everytime they want to upload something. The server has no way of knowing if the request came from a real user on the upload page or from any other place.
Yeah, I could check the domain on the request coming in to the api, and validate it, but domain can be easily spoofed (when the request is not coming from a browser client).
Is this whole thing even a concern ? The main risk is someone abusing my S3 account and uploading stuff to it. Are there other concerns that I need to know about ? Can this be mitigated somehow?
Suppose my upload page is publicly available. That means the server
API endpoint that generates the short lived key needs to be public as
well. A malicious user could then just find the address of the api
endpoint and hit it everytime they want to upload something. The
server has no way of knowing if the request came from a real user on
the upload page or from any other place.
If that concerns you, you would require your users to login to your website somehow, and serve the API endpoint behind the same server-side authentication service that handles your login process. Then only authenticated users would be able to upload files.
You might also want to look into S3 pre-signed URLs.