How do I pass secret key to URL via a QR-code? - security

I am looking for a secure way to pass a secret key when the user scans a QR-code and goes to my url. This secret key is the key that is connected to one of my products(a smart speaker). If the secret key is valid, the user will be asked to login or register to couple their account to the product on my webpage.
However after my research, QR-codes only pass data that is visible in the url. This brings along security issues even if the key is encrypted: the problem of users typing in adjacent values, the keys get saved in browser history (this means malicious code could sweep through a user’s browsing history and extract passwords, tokens, etc). They’re probably saved in my server’s logs and memory, ... .
Is there a more secure way to pass secret information via a QR-code to a url?

Long story short - there is not. One usually would pass secrets as headers or in the body or the request, but you don't have this kind of flexibility when using QR codes.
Without understanding your business requirements fully, I would try to tackle the problem in the following way.
Embed the secret in the url. Encode it to a QR code. Hide the code in the products package for the customer to find after buying and opening the product.
After using the url redirect the user to a page to create some credentials or use some federation protocols to create an account.
After the account has been created, mark the urls secret as invalid.

You can put the secret data in the fragment part of the URL (after #) then it won't get sent to the server, but can be read by JavaScript in the web page.

Related

GCP Cloud Storage Signed Urls - Bound to an object or just calculated?

GCS Signed Urls enable you to simply make objects available temporarily public by a signed url.
https://cloud.google.com/storage/docs/access-control/signed-urls
As I understand it, you need to calculate a signature based on several parameters, and then you get
access to the object without any other security layer.
Unfortunately the documentation is not completely clear if an object gets explicitly activated by the GCS service for that and gets a flag "signature XYZ valid for XX minutes on object ABC" or if GCS serves all files all time, as long as the signature is correct.
If any object can be made available with a proper signature, then all files in GCS are de facto accessible public, if the signature gets guessed right (brute force).
Is this right?
Is there any information on the level of security, that protect url-signing?
Is there a way to disable the url-signing?
Do the VPC Service Perimeters apply to signed urls?
These are some points that I need find out due to compliance evaulations and they are more theoretical questions, than some concrete security doubts I have with this service.
Thanks for your comments.
Unfortunately the documentation is not completely clear if an object gets explicitly activated by the GCS service for that and gets a flag "signature XYZ valid for XX minutes on object ABC" or if GCS serves all files all time, as long as the signature is correct.
The signed URL contains a timestamp after which the signed URL is no longer valid. The timestamp is part of what the signature signs, which means it can't be changed without invalidating the signature. The signatures themselves are generated entirely on the client with no change in server state.
If any object can be made available with a proper signature, then all files in GCS are de facto accessible public, if the signature gets guessed right (brute force). Is this right?
Yes, this is true. Anyone who knows the name of a service account permitted to read the file, the bucket name, and the object name, and who correctly guesses which of the 2256 possible hashes is correct could indeed view your file. Mind you, 2256 is a fairly large number. If an attacker could make one trillion guesses per nanosecond, we would expect that on average they would discover the correct hash in about 3.6x1044 years, which is about 2.7x1034 times the age of the universe.
Is there any information on the level of security, that protect url-signing?
Certainly. GCS uses GCS uses a common signed URL pattern identical to S3's "AWS Signature Version 4." The exact signing process is described on both service's websites. The signature itself is an HMAC SHA-256, which is a type of SHA-2 hash, a well-studied algorithm whose strengths and weaknesses are widely discussed. https://en.wikipedia.org/wiki/SHA-2.
Is there a way to disable the url-signing?
VPC service controls are the simplest way. They can prevent any user outside of your project from accessing the data regardless of credentials.
Do the VPC Service Perimeters apply to signed urls?
Yes, signed URLs would only work from within the configured security perimeter.
Looking at the library code, the signed URLs are created using your service account private key without cooperation from GCP.
Regarding the brute-force, each Signed URL has a credential attached, which is linked to the signer. This signer account needs to have permissions you want the user to have on the object. In case the URL is stolen, it can then be revoked by revoking permissions of the signer (you'll revoke all Signed URLs for that signer tho). To minimize risks, you could create a SA that would have access only to specific objects in the bucket.
To decrease the possibility of brute-force attacks, you can also rotate the Service Account key by creating a new one and deleting the previous.
Regarding the question: Can Signed URLs be fully disabled? You could "disable" this feature by not granting project-wide storage permissions to any Service Account for which you have generated a Private Key.

Obtaining Instagram Access Token

We have a client who has a simple Instagram feature on the site to pull photos by a certain tag. They just noticed it isn't working. Getting an error - invalid access token. I guess since the 1st because of the updates. We didn't used to need an access token since we're not doing anything with users - just tags.
Now it looks like we need one and the documentation makes zero sense on how to obtain one. And it seems like they're not accepting most apps. The app is in sandbox mode too. So I'm assuming it's because it got switched to that? Got no notification of this happening.
The first step in documentation to get an access token is "Direct the user to our authorization url." What does that even mean? There's not a link provided or anything. It also says "Company Name, Contact Email and Privacy Policy URL are required to start a submission." Our app doesn't have a privacy policy... it's just a simple tag feed. I don't understand why everything is so complex to have a simple tag feed.
Is there a wait time to get the app approved..if it gets approved... Do I have to have it approved before getting an access token? This isn't outlined anywhere.
You got it right. As of June 2016 any Instagram API calls require an access token.
Getting an access token is described in the documentation. App approval is not required.
There are two ways to get one: server-side or client-side. The second option (called implicit authentication) can only be used when implicit OAuth is enabled in the client settings (Manage Clients > Edit Client > Security > Disable implicit OAuth). It is disabled by default.
In either case you need to redirect the user to the authorization URL to obtain an access token.
The URL for explicit mode (server side) is:
https://api.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=code
The URL for implicit mode (client side) is:
https://api.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=token
After this you will be redirected to the REDIRECT-URI, which will be passed an argument. For explicit mode this will be a query string with a code, while for implicit mode you will get the access token directly as a hash:
http://your-redirect-uri?code=CODE
http://your-redirect-uri#access_token=ACCESS-TOKEN
For implicit mode you can then get the access token from the window.location.hash in Javascript.
For explicit mode, however, you need to further process the code to obtain the access token. You can read how this can be done in the API Documentation. I'm not going to take this any further here.
The problem is that every user who wants to see your feed needs to login to Instagram (and have an account) in order to view it. In your case this might not be desired. However, there are a few options to get around this (rather annoying) problem:
You can reuse your own (already obtained) access token(s) to display the Instagram feed for every user. You will need to be aware of rate limits for each token. For sandboxed apps this is 500 API calls / hour, while live mode allows 5000 API calls / hour. [source] You could store tokens in a table and use them in a round-robin manner, to allow more API calls. This involves manually obtaining a bunch of tokens which your application can use (the more the better). This might not be the ideal solution considering Instagram doesn't warrant access tokens to have an unlimited lifetime.
You can retreive JSON data without authentication by appending /media/ to a user page URL, as described in this post. No tokens or client IDs are required for this to work. However, this only works for users, not for tags. Besides, Instagram doesn't document this feature so it is not garanteed to work in the future.
You can use an aggregator like Juicer or Dialogfeed instead which will handle access tokens for you. This is usually not free of charge.
I'm also in the process of making an Instagram feed for my website, and this is what I concluded from my research. Please bare with any errors I made.
Edit: Here are some more limitations for sandbox apps.
In sandbox mode you can only access data from sandbox users (thus users who received a sandbox invite). This means that:
Media retreived by user, e.g. /users/{user-id}/media/recent, will return an empty response if the user is not any of the sandbox users.
Media retreived by tag, e.g. /tags/{tag-name}/media/recent, will only contain tagged media belonging to sandbox users.
Thus, for a tag feed to work, it needs to be live (reviewed and approved). If you don't want to do this, the only alternative is to use an aggregator as I mentioned above.

How can I authenticate a user from an email link?

Our web app. sends reports out to users which contain links that point to various items within our web app. (specific records). Users ordinarily have to login to our system to access it, so I am wondering what the best methods are of allowing one of these links to direct the user to the area of the system, without them having to repeatedly login.
When you create a link, you can note which user this link is for. When user clicks on the link, fetch information for the user. Guid in your url would guarantee that no other person can guess path for that users data. This will not technically authenticate a user. But will allow them to see data you need.
First of all it's bad idea to distribute user credentials even to a known email address.
You can generate a unique key for each customer and insert it in query string of included URL in the email. once user clicks on the sent URL, system discovers which user is dealing with and authenticates user. After successful authentication process it really makes sense if you disable the sent unique key.

AWS S3 The security of a signed URL as a hyperlink

Is this safe? Maintaining security using a pre-signed url with AWS S3 Bucket object?
my link
Another words - part 1...
say I'm storing a bunch of separate individual's files in a bucket. I want to provide a link to a file for a user. Obviously, each file is uniquely but consecutively named, I don't want people to be able to change the link from 40.pdf to 30.pdf and get a different file. This URL seems to do that.
part 2, and more importantly....
Is this safe or is a it dangerous method of displaying a URL in terms of the security of my bucket? Clearly, i will be giving away my "access key" here, but of course, not my "secret".
Already answered 3 years ago... sorry.
How secure are Amazon AWS Access keys?
AWS Security Credentials are used when making API calls to AWS. They consist of two components:
Access Key (eg AKIAISEMTXNOG4ABPC6Q): This is similar to a username. It is okay for people to see it.
Secret Key: This is a long string of random characters that is a shared secret between you and AWS. When making API calls, the SDK uses the shared secret to 'sign' your API calls. This is a one-way hash, so people cannot reverse-engineer your secret key. The secret key should be kept private.
A Signed URL is a method of granting time-limited access to an S3 object. The URL contains the Access Key and a Signature, which is a one-way hash calculated from the object, expiry time and the Secret Key.
A Signed URL is safe because:
It is valid for only a limited time period that you specify
It is valid only for the Amazon S3 object that you specify
It cannot be used to retrieve a different object nor can the time period be modified (because it would invalidate the signature)
However, anyone can use the URL during the valid time period. So, if somebody Tweets the URL, many people could potentially access the object until the expiry time. This potential security threat should be weighed against the benefit of serving traffic directly from Amazon S3 rather than having to run your own web servers.

Auto authentication through email link

I have written an agent which takes the username and authenticate user, if authentication is successful then it redirects to the actual URL of the database.
For taking name of the user, I am using #Formulas. Hence, I can use my method of authentication in any link or hotspot or button in Notes Client. But, I face problem to send this method through reminder email links.
When I create a URL through backend agent, this URL/hotspot should have my code with #formula. In simple words, I want to pass #Dblookup inside URL/hotspot through my email link. How to accomplish this task ?
Or is there any alternative to get user name if any person clicks a link in his email ?
Only Notes client has to be used.
Edit#1: Adding scenario for better explanation:
Our users are not happy to re-authenticate themselves for web applications. So, we have been trying something like if they want to open a webdoclink, which they got through their email in notes client, so they shouldn't be asked to authenticate again (since they have already logged into notes client).
We could achieve this for static application links, where application name is not changed. Now, the challenge we are facing is how to do it for reminder emails, which have links to particular web document (links here are not static. They are differed by unique document ids).
For this to work, we need shortname of person who clicked that link from his email.
You probably need to be sending an Action hotspot instead of a URL hotspot; but it is very difficult to guess without seeing what your code is really doing. Also, I believe that creating an Action hotspot probably will require copying it from a previously saved rich text field, perhaps in a profile document and appending it to the rich text body field of the message you are sending. (That's a technique I've used in the past to create action hotspots, anyhow. I'm not sure if there are better alternatives.)
And since this is for Notes client recipients, the other technique that I would probably explore is the use of a store-form-in-document message instead of an ordinary email message. That way you just need to have a button containing the #DbLookup on the form that you send in the message.
I agree with leyer. The ACL (Access Control List) is the main tool to use to decide functionality. For instance a user can have access to the db. Then you can define who can create databases, create emails. It is best to use the ACL so you can also use Roles and other tools. Basic LotusScript can access the ACL on open events or do a test in buttons.
Regarding the scenario you are describing, if the issue is that users have to re-authenticate for every web application on the server, you would be better of implementing SSO/Session based authentication on the server then coding this workaround. With Session based authentication, users only have to authenticate once.
From the admin help:
Session-based name-and-password authentication sends the client's name and unencrypted password, and is sent with each request to the server. Session-based authentication differs in that the user's name and password information is sent over the network only the first time the user logs in to a server, not each time a request is posted. After login, the user's name and logon information is stored in a cookie in the user's browswer, and the browser sends the cookie to the server with each request. Before honoring a request, the server verifies the information in the cookie and uses the cookie contents to identify the logged-in user. The session is only valid within the browser in which the login was performed. If the user shuts down the browser in which the session login took place, the user's session will be ended and the cookie will be destroyed.
Using session-based name-and-password authentication provides greater control over user interaction than basic name-and-password authentication. For example, you can customize the form in which users enter their name and password information. It also allows users to log out of the session without closing the browser.
If you are using windows based servers, you could even implement SPNEGO, automatically signing the users in using der Windows account, therefore eliminating login prompts completely.
With Domino 9, you also have the option of using Security Assertion Markup Language (SAML) to configure federated-identity authentication.
In your case, I would start with Session-based name-and-password authentication to solve the multiple-login issue.

Resources