How to securely sign requests with aws credentials? - php

I am not entirely sure if this is the question I should be asking so feel free to submit edits.
I am developing a desktop app I plan to distribute and use amazon Polly to read text the user enters. I am having trouble understanding how to securely allow users to access the service under our program without exposing the access key.
I saw in a previous example that I should create a request to use the resource, have the access and secret access key in a server and it sign the request. Then send it back to the user on the desktop application.
If this is correct could someone explain and give me a simple example of how to accomplish this in python? Thank you. :)
Here is what I have so far that I would like to be on the code clients download:
from boto3 import client
import boto3
import StringIO
from contextlib import closing
polly = boto3.client(
'polly',
region_name='us-east-1',
aws_access_key_id='I_want_to_protect_this',
aws_secret_access_key='I_also_want_to_protect_this'
)
response = polly.synthesize_speech(
Text="Good Morning. My Name is Rajesh. I am Testing Polly AWS Service For Voice Application.",
OutputFormat="mp3",
VoiceId="Raveena")
print(response)
if "AudioStream" in response:
with closing(response["AudioStream"]) as stream:
data = stream.read()
fo = open("pollytest.mp3", "w+")
fo.write( data )
fo.close()

The correct approach for providing people with access to AWS services and resources stored on AWS is to take a client/server approach.
The client in your case is a Desktop application, but it could equally be a mobile app or a web app. The client is basically untrusted and should not be given any credentials for accessing AWS.
The server is an application running somewhere (typically on Amazon EC2 or AWS Lambda) that receives requests from the client, applies business logic (eg verifying the user's identity and determining what actions they are permitted to take) and calls AWS services.
Then there are two approaches to making calls to AWS:
The server can make all the calls to AWS (using credentials that are available only to the server) and pass back results to the client. This isolates the client from AWS and allows you to insert custom business logic within the server. (eg When you use Netflix, your TV doesn't call AWS directly.) Or...
The server can verify the identity of the client (eg the user logs into the client app, which sends the login details to server) by consulting a database of authorized application users, generate temporary AWS credentials, pass them back to the client and then the client can call AWS directly. (eg Many mobile apps do this to talk with Amazon S3.)
The temporary AWS credentials can be generated by the server by calling the AWS Security Token Service and specifying the permissions and duration sought. STS will then return a set of time-limited credentials that have the desired permissions. The client application can use these credentials to call AWS services (eg Amazon Polly as per your code sample).
This way, no credentials are stored in the client code and the server controls whether the client is permitted to access AWS, which API calls can be used and how long the access should be granted.

Related

Firebase Cloud Functions on Client (vue.js) to access Back-End API data hosted on GAE PHP

I have a web app hosted in Firebase in vue.js. The app access to the organization's main database via API to a back-end server developed in PHP (laravel) hosted in GAE.
I'd like to know if using Firebase Cloud Function on the client (js) to make calls to a back end API (PHP) would help me to protect data and be more efficient authenticating calls from the client to back end.
Currently:
Users login into the client using Firebase Auth and the client sends the resulting token to my back-end server on each API call. Then the back-end verifies the token received via HTTPS using FB Auth API and then if verified, the backend would return the request data via JSON back to the client-side via HTTPS response.
My 2 biggest concerns are:
1) would this approach scale well with more users.
2) for large extractions of data, i.e. 1000+ rows. I'd like to avoid to have JSON objects being "downloaded" on the client.
New Scenario:
The users would still log in on the client (vue.js) using FB Auth, but the Client would use FB Cloud Functions to make the calls to the Back-End API data hosted on GAE and then return the data as an array.
The advantages I hope to utilize are:
- The client will not have https traffic with data as this would be handled by FBCF and send to the client via socket (?).
- Save verification auth calls from the server, IF there is a way for FBCF to make calls to GAE without the need to pass the token (maybe using endpoints?)
Does this make sense or am I introducing a middle man unnecessarily?

401 while creating customer in quickbooks using php api

I keep getting 401 in spite of using the test keys from the playground app, can someone help on how to resolve this, code works fine on a dev server, as soon as code moved to qa server i created a new QuickBooks account and a new app and now i keep getting a 401
Just moving code from one server to another is a guaranteed way to break anything OAuth related.
You would need to at least:
Move the code
Change the OAuth URLs in Intuit's control panel to point to the new server
Change the OAuth URLs in your code
Clear any stored OAuth access tokens from your database (if you moved the data in the database to the new server as well)
Reconnect to QuickBooks, via the [Connect to QuickBooks] button
Additional notes:
Why are you using test keys from Intuit's playground app? Create your own app, and use your own keys.
If you created a new app, you'll also need to swap our your OAuth consumer key, OAuth consumer secret, and App token in your code.
Be aware that if your app is in DEVELOPMENT mode, then you can only connect to DEVELOPMENT QuickBooks accounts. If you created a LIVE QuickBooks account, you can only connect to it with PRODUCTION/LIVE app credentials (e.g. you need to PUBLISH your app).
Since you didn't post:
Your code
Screenshots of the credentials from Intuit's control panel (assuming they are dev/sandbox and thus safe to post)
Any of the HTTP requests/responses you're sending/receiving
We won't be able to really help you much further.

Malicious URI handling for connection with external websites

My application allows the user to connect to my backend from which it will redirect the request to an external api of another website.
This other website allows access to a REST API through the usage of an application and private key. The keys are stored in my backend server for security purposes. The other website allows other developers/administrators to make their own instance of that website with the same REST API keys but with different content.
So the flow is as follows:
Client application connects to backend server.
(When successfully authenticated) The client sends request for information to backend server.
Backend server forwards the request to a REST API instance of an external website.
REST API instance of the external website returns requested information to backend server.
Backend server returns requested information to client.
In the process of requesting the information, the client needs to specify to which external API the backend server should connect via a URI.
With security in mind I've noticed a big issue with my system: the user could send a URI of a "REST API" in his possession that actually captures all the data between the backend server and the bad "REST API". This way the bad URI could capture the secret REST API keys for malicious purposes.
How can I be sure that the URI the client provides to the backend server is a legitimate URI for an external REST API and not just a random, bad or malicious URI?
The only solution I've came up with is a database check for the legitimacy of a URI to cope with this issue.

GDrive token gets invalidated after some time

Current Working Flow
I have a web app (developed in wordpress)
I am using google-drive-sdk to upload dynamically generated pdf file to a GMail account.
The GMail account has been configured in the web app giving the
secret key ....
The web app first makes the authentication ===>i.e The GDrive Account is authenticated for the first time by the GMail owner (In Google Permission window the button Allow Access is clicked)
It works fine thereafter when called from the web app - the pdf file dynamically generated gets into the configured GDrive
The Problem
PDF files gets uploaded to the GDrive only for some time.
After sometime it doesn't upload the files to GDrive.
I then tried creating a new token - It again starts uploading files but stops after some time.
This happens only in Staging server.
In my local development system it keeps working fine - uploading the file to GDrive whenever the app is executed.
The difference between both the environment is the GMail Account is different.
If you have any idea on the cause of issue or any pointers would really be helpful for me.
Your application must use OAuth 2.0 to authorize requests. All requests to the Drive API must be authorized by an authenticated user.
The details of the authorization process, or "flow," for OAuth 2.0 vary somewhat depending on what kind of application you're writing. The following general process applies to all application types:
When you create your application, you register it using the Google API Console. Google then provides information you'll need later, such as a client ID and a client secret.
Activate the Drive API in the Google API Console. (If the API isn't listed in the API Console, then skip this step.)
When your application needs access to user data, it asks Google for a particular scope of access.
Google displays a consent screen to the user, asking them to authorize your application to request some of their data.
If the user approves, then Google gives your application a short-lived access token.
Your application requests user data, attaching the access token to the request.
If Google determines that your request and the token are valid, it returns the requested data.
Some flows include additional steps, such as using refresh tokens to acquire new access tokens. For detailed information about flows for various types of applications, see Google's OAuth 2.0 documentation.

Temporary Credentials using AWS IAM

I have a server, which should provide temporary AWS credentials to the client. The credentials will be transmitted using HTTPS.
The client should be able to upload S3 files, as well as download them. The concern I have is the following:
I have multiple users accessing ONLY their own directory: /Users/someUser/myfile.png
You can set policies to allow or deny S3 in general, but you can't grant only the access to a specific path.
What should I do about this? Will the HTTPS transmission be enough?
Then my second question.
If I hear "temporary credentials", I have a key in mind, that is valid for a couple of hours and then expires. But I'm not sure if IAM is really built for that.
Should I provide the same credentials for all users?
Or do I generate a key-pair for each client?
The server runs with PHP, the client with Objective-C.
You can specify permissions on a path in Amazon S3. For more details see the following:
Using IAM Policies
Also, if you want to create "temporary credentials" you can use the AWS Security Token Service. This service allows you to create credentials that last from 1 - 36 hours and you can put a policy on those credentials to limit their access. For more details about the service see:
Security Token Service API Reference
Finally, there is an article written for the AWS Mobile SDKs that does something similar. It has a server to issue temporary credentials to users that use an Amazon S3 bucket. It limits the users to a "sub-folder" of the bucket and also limits their actions. You can read and this sample here:
Credential Management for Mobile Applications
Hope this helps you get to the information you need.

Categories