I'm building a custom command line tool using node. The user will need to be able to sign in and persist their session. I have done this using node and passport before for a web app using localStorage, but how should I go about storing the users JWT with a cli tool.
If it's an OAuth2 or OIDC access_token then even though it's a JWT you should treat it as an opaque blob because OAuth2 and OIDC clients are not the intended audience for access_token (they're meant to pass it as-is verbatim to the remote Protected Resource).
I note that OAuth2 and ODIC allow access_token to be anything - including non-JWT tokens, such as a short opaque "reference token" value.
This means that you can write the JWT (in its Base64-encoded format) directly to a file on-disk and read it back as you like. Because it's Base64 you don't need to worry about file encoding too much (e.g. both 7-bit ASCII vs UTF-8 are fine).
If it's an ODIC id_token then you could Base64-decode it and store the decoded raw JSON in a file if you intend to use each individual Claim stored within in your client. Note that if you do store the raw JSON to a file you must use UTF-8 unless you want difficulties down the line.
Each platform has a preferred location for per-user temporary data:
On Windows, you should store this in a subdirectory of %LOCALAPPDATA% (C:\Users\me\AppData\Local), e.g. %LOCALAPPDATA%\YourCompany\YourProduct\Jwt.json.
If security is important you should encrypt this file at-rest using DPAPI: DPAPI encrypts files using a secret key that's part of the user's profile - you just pass the cleartext into the Win32 function and it returns the encrypted ciphertext which you then write to disk. Make sure you're careful about the binary encoding of any text you read and write, of course. DPAPI can be used on a per-user (roaming between machines) or per-machine (multiple users, but only on the same machine) basis.
Windows also has the Credential Manager API, but it's not well-suited to storing large blobs: https://learn.microsoft.com/en-us/windows/desktop/secauthn/kinds-of-credentials
On macOS you'll want to use the Keychain API: https://developer.apple.com/documentation/security/keychain_services
On Linux, there is no system-provided secret-storage mechanism ( https://dzone.com/articles/storing-secrets-in-linux ), but most approaches seem to write secrets to disk and then set chmod on the file to prevent access by other users. You could also encrypt the file with a custom password that the user must enter whenever your program runs.
As with Windows, you should still save this data under the user's home directory (~/) and not the shared /tmp directory. The convention on Linux for application-specific data is to use a hidden (dot-prefixed) home subdirectory, e.g. ~/.yourCompany/yourProduct or just ~/.yourProduct.
Related
I have a web app that uses known username and password combinations to login to external servers. There are multiple username/password combinations used for different services. Right now, they are essentially "hard-coded" into the website code, but, I would like to move this information off the code base for better security.
My initial thought is to store this data in the database which is used to support the website. I want to store it in a way that it is not easily "hackable" (i.e. I'm not going to store it as plain text or as a MD5 hash). Should I follow the same format that I use to store the website user's passwords, where I use a random number generator to create SALT for each password and then store the password as hashed combination of the password and SALT, or would this be overkill?
Generally, storing passwords in the application code is always a bad idea. Moving it outside the code has many advantages including security.
Now storing it either in DB or Configuration Files is a choice you have to take depending on your application.
For full security you should never store passwords in retrievable form. But to login to a external server as in your case, you need to get the actual plain text password, so one way hash will not work for you.
In our product we deal with such situation by using 2 Way SSL Certificates. It is very secure and there is no need to store the passwords.
But if you really need to store the passwords, then I will suggest to use configuration file and let your application read it. You can encrypt the passwords stored in the configuration files (Encrypting the passwords stored in the configuration file will again bring you back to the same question of how to protect the key). The access to the configuration file should be restricted (in Unix, 600 File Permission).
Alternatively, if your web application is Java, then you can consider using JNDI.
After more research, I've decided at this point to follow the ideas here:
Encrypt a Column of Data - SQL Server | Microsoft Docs
...and encrypt/decrypt on the DB inside a Stored Procedure.
I'm storing options data in a chrome extension using chrome.storage.local.set
How secure is that data?
Can it be read easily by anyone who has access to the file it is stored in?
It is not secure, and per the official chrome.storage docs is stored unencrypted in the user's profile folder under their Chrome data directory. You will need to use some additional encryption if you are storing more sensitive data using these APIs.
They are stored in a LevelDB database in the following location:
C:\Users\<User>\AppData\Local\Google\Chrome\User Data\Default\Local Extension Settings\<Extension id>
It's saved in the following path (For other OS, the path is similar), can be easily accessed.
C:\Users\<User>\AppData\Local\Google\Chrome\User Data\Default\Local Extension Settings\<Extension id>
Basically, since the data is saved in local machine, you can't trust it as secure, since there're tons of ways to get the data. For example, other extension/scripts may overrite chrome.storage.local.set and they may get the data first, like what Storage Area Explorer does.
I can streami '~/test/test.mp4' file while set secure token is 'Do NOT use SecureToken'.
But I can't stream '~/test/test.mp4' file while secure token is 'Protect all protocols using hash (SecureToken version 2)'.
Also, I can stream '~/test.mp4' file while secure token is 'Protect all protocols using hash (SecureToken version 2)'.
Example:
Do NOT use SecureToken
success
rtmp://example.com:1935/vod/_definst_/mp4:test/test.mp4
success
rtmp://example.com:1935/vod/mp4:test.mp4
Protect all protocols using hash (SecureToken version 2)
fail
rtmp://jungslab.com:1935/vod/_definst_/mp4:test/test.mp4?wowzatokenendtime=1461729940&wowzatokenstarttime=1461719140&wowzatokenhash=nB0hdUG-U60WAQ-wV5lIRD0e3tbCCXk3tBWrLXxb90M=
success
rtmp://example.com:1935/vod/mp4:test.mp4?wowzatokenendtime=1461729868&wowzatokenstarttime=1461719068&wowzatokenhash=KpioKfCCQQoeVT4lwLUnwC2xhDG-HOS2kRtAx5PEHhY=
How access a subdirectory file in wowza that uses secure token.
The problem with Wowza here seems to be with parsing query string. If you can't change the content directory in you vod/Application.xml (or you don't want to do so) to the test subdirectory (or any other mount) you may try moving the query string right after the instance specification app/(definst?qs=/file) or use plugin to obey the directory structure completely.
Address to try for your file could be:
rtmp://jungslab.com:1935/vod/_definst_?wowzatokenendtime=1461729940&wowzatokenstarttime=1461719140&wowzatokenhash=nB0hdUG-U60WAQ-wV5lIRD0e3tbCCXk3tBWrLXxb90M=/mp4:test/test.mp4
(adjust your token info for valid)
Depending on the version/build that you have, there was a previous bug found (on 4.3.0.01 and earlier) where subdirectories were not parsed correctly with Secure Token enabled. You should try:
rtmp://jungslab.com:1935/vod/mp4:_definst_/test/test.mp4?wowzatokenendtime=1461729940&wowzatokenstarttime=1461719140&wowzatokenhash=nB0hdUG-U60WAQ-wV5lIRD0e3tbCCXk3tBWrLXxb90M=
You will need to re-generate your hash since your stream path has changed.
Alternatively, you can install the latest build from Wowza, since the fix should be in the latest available patch.
As a troubleshooting tool, you can add the Boolean properties securityDebugLogRejections and securityDebugLogDetails to your conf/appName/Application.xml file to output additional debug information to your logs/wowzastreamingengine_access.log file. In particular, you can see what string the server is using to generate the hash, and why the received hash was rejected.
We have a web application which consists of two parts (among others): a 'shell' written in Java running in Jetty using Windows authentication through Waffle, which shows a 'component' written in ASP.NET running in IIS using Windows authentication. Both parts are served from the same host, but (of course) from different ports.
As it stands, a user first must sign in to the shell, and then when the component is loaded the user must sign in again. We want to get rid of that second sign-in step.
From what I've seen and read, e.g. about claims-based authentication and OAuth, the standard pattern for that is the following:
After signing in to the shell, the shell constructs a 'token' with the user's Windows account name, which it sends back to the browser.
The component does not use Windows authentication, but instead the browser sends it the token.
The component verifies that it trusts the token, and uses the identity from that token.
(In our case the simplest technique is to put the token in a cookie, since both shell and component run on the same server, and HTTP cookies are not port-specific, so the browser will automatically send the shell's token to the component.)
Now I see several ways to construct and verify the token, like:
(a) The token contains the Windows account name, encrypted with a symmetric key that is hardcoded into both shell and component, or generated and agreed at installation time or start-up time.
(b) The token contains the Windows account name, signed using a private key, and verified using the corresponding public key. This key pair is generated at installation time.
(c) The token contains a GUID, and the component's server side makes a call to the shell's server side to verify its validity and get the Windows account name.
I think I prefer (b), since (a) seems too 'hardcoded', and (c) is more likely to give scaling issues. Also, we already have a private/public key pair in place in the form of an SSL server certificate in the shell which is trusted by the component.
My main concern with (b) is that the token will contain an (X.509?) signature, which means the token could become fairly large. (Would it?) Also I'm not (yet) familiar with techniques to create a signature in Java, and verify it in .NET.
My question: What is the standard/recommended pattern to use here? What alternatives have I overlooked? Is there a standard protocol that we could use here?
You are on the right track.
Yes, the idea is to have the shell generate a token that cannot be forged (generated by anything/anyone but the shell) that can be verified by the component.
You are right that the token can become quite large. It will not become so large as to be unworkable (i.e. larger than a browser can handle), but it can become a performance issue.
In general, any component that accepts HTTP traffic with any kind of cached authentication is going to have a preferred format for that cached authentication. In your current implementation, after the user signs into the component (the second sign in step) the component will issue some kind of cookie containing identification credentials it will accept for subsequent requests. So the best thing would be for the shell to create exactly those credentials.
Failing that, it's quite reasonable for you to use your option (b) of creating a signed certification form the shell that the component can verify and then replace with its preferred form of authentication credential.
I've found numerous posts on stackoverflow on how to store user passwords. However, I need to know what is the best way to store a password that my application needs to communicate with another application via the web? Currently, our web app needs to transmit data to a remote website. To upload the data, our web app reads the password from a text file and creates the header with payloads and submits via https.
This password in plain text on the file system is the issue. Is there any way to store the password more securely?
This is a linux os and the application is written in python and is not compiled.
Further clarification:
There are no users involved in this process at all. The password stored in the file system is used by the other web app to authenticate the web app that is making the request. To put it in the words of a commenter below:
"In this case, the application is the client to another remote application."
From the question it seems you need to store password in such a way, that it can be read and used in an automated transaction with another site. You could encrypt the password and store it encrypted in the file, then decrypt it using a key stored elsewhere in your system before using it. This makes difficulties to someone that gets access to the file from using the password, as they now have to find the key and encryption algorithm used, so they can decrypt it.
As defense, more lesser defense is always better than one strong defense that fails when breached. Moreover, I would also secure the file containing the password, rather than the password itself. Configure your webserver to disable possibility to serve the file containing the password, and try to set the process needing the file to run under a separate account, so you can restrict the access to the file to account running the process and admin accounts only.
I don't think you will find a foolproof way to do this. I would suggest a combination of things to achieve 'security by obscurity':
store the password file on a different computer than the one which will use it
store the file path in a separate config file on the app nachine
use permissions to limit access to the config and password files to your process only
audit file access if your system allows it (keep a log of who touched the files)
give the folders and files innocuous names (/usr/joe/kittens.txt?)
block physical access to the computer(s) (offsite hosting, or locked closet, or something)
You can use a two-way key encryption algorithms like RSA,
The password is stored encrypted (by a key, which is stored in the user's brain) on the filesystem, but to decode the password, the user must enter the key.
At the very least you should use permissions (if you are on a filesystem which supports them) to ensure that you are the only one able to read the file.
In addition, if your app is compiled, it would not be too difficult to encrypt the password with a hard-coded passphrase. If the code is not compiled this method wouldn't really be helpful, as a would-be attacker could just read the source and determine the encryption.
You can store it as a result of hash algorithm, this is one way algorithm (eg. MD5 or SHA). On authentication you calc MD5 of password typed by user and checking equality with your stored MD5 password hash for this user. If is equal password is ok.
For more information about hasing algorithms you can visit:
http://en.wikipedia.org/wiki/Secure_Hash_Algorithm
http://en.wikipedia.org/wiki/MD5
Is your web application hosted on a farm? If not then a technology such as DPAPI will allow you to encrypt the password so that it can only be decrypted on the machine it was encrypted on.
From memory there can be problems with using it on a web farm though, as you need to go and re-encrypt the value for each server.
If it is a web farm then you probably want to use some form of RSA encryption as has been suggested in other answers.
EDIT: DPAPI is only good if you are hosting on windows of course...
Protecting the Automatic Logon Password
The LsaStorePrivateData function can be used by server applications to store client and machine passwords.
Windows only
I don't think you are understanding the answers provided. You don't ever store a plain-text password anywhere, nor do you transmit it to another device.
You wrote: Sorry, but the issue is storing a
password on the file system... This
password is needed to authenticate by
the other web app.
You can't count on file system protections to keep plain-text safe which is why others have responded that you need SHA or similar. If you think that a hashed password can't be sufficient for authentication, you don't understand the relevant algorithm:
get password P from user
store encrypted (e.g. salted hash)
password Q someplace relatively
secure
forget P (even clear the buffer you
used to read it)
send Q to remote host H
H gets password P' from user when
needed
H computes Q' from P', compares Q'
to Q for equality