Password Input Type Not Stored Securely

I was going to try to deal with support directly on this issue, but their initial response was to post this to the community. Pretty poor response to a security issue. Wish they would treat potential security flaws with a bit more discretion. However, I guess it was already fairly publicly reported here without much response.

and

But ultimately the real issue is that any input box in a smartapp is stored and persists after install.

So, here’s the issue:

input "Password", "password", title: "Password"        

this is stored in the settings Array as setting.password in plain text.

In the IDE SmartApps settings it does mask out the password, but anyone logging the settings array would see settings.password including the default action of

log.debug "Installed with settings: ${settings}"

you will see in the settings array password=“password”

Trying to overcome this issue I tried to issue this command after install:

settings.remove("Password") 

which does appear to remove the password from settings but it survives that function call scope and comes back in other function calls.

the appSettings array supposedly exists for this use case but their is no way to get a user input password and have it not stored for the life of the SmartApp.

What does this mean? Any SmartApp that asks for private information is NOT stored privately and is cached even when it is attempted to be cleared. Any SmartApp needs to do is find the app with the security information and pull out the settings array.

There should be some way to salt/hash passwords and store them securely within the SmartApp and restrict their logging display or access outside the SmartApp.

More over, there should be a way to clear a settings option and not have it survive a “remove” call.

Right now, there is simply no way to remove the password once it is inputted within a SmartApp other than to have the user enter the “wrong” password again after a successful login.

Just a heads up that if you use any SmartApp or DeviceType that requires a password, that it is stored in plain text and is easily accessible in the IDE / Logs.

2 Likes

Agreed, normally I do wait. In this case, I was able to find several posts talking about the issue.

On top of it, the scope of the issue is limited to the logging and the app’s settings and not being able to remove the password once it’s set.

Since I’m still waiting on over a dozen other fixes to the IDE since July, it probably makes more sense to put this out to the community to find some sort of workaround and not wait till someone inside ST can actually store a password securely.

I’m thinking of some method to route a password input request to a ssl server I manage, ask for the password to be entered, then return back a hash / key for that password.

But then I still have to send an ssl request to that service for the actual password or API key and that would make it just as vulnerable.

Fundamentally, passwords and other sensitive data needs to be stored securely and not in plain text in SmartApps and in the IDE.

Essentially, all passwords or any sensitive data, API Keys, etc. that are used in ST in SmartApps or DeviceTypes are stored in plain text and are ripe for the taking.

I’m hoping ST has already figured out a way around this with some sort of private API call and just hasn’t documented it @Jim but I’m guessing its an underlying architectural flaw / risk in using this platform.

2 Likes

I noticed this too! I actually run a small Ruby on Rails program to collect my energy usage data from SmartThings post request. Instead of a password authentication system I use a token system instead (API keyish).

Not suuuper great in the way of security, but at least if someone saw the https requests all they could potentially do is send me fake usage data.

I wonder how ripe for the taking they really are though. The developer IDE is behind https requests. The only real threat I see is if someone gets your ST password and logs into your IDE to check out the passwords. Another oops is the fact that passwords are in plain text on ST servers and a ST server breach means that others get your passwords. OK - but if they salted your password, they’d never be able to use it for other server’s authentication that way, since there’s no way to extract the password from a true encrypted password system.

In short… I think what they’re doing isn’t all that bad. Use only API keys and not real passwords, and keep your ST password safe. I’d love to see a solution to the overall problem though. Unsalted passwords aren’t great. Maybe some kind of overlord authentication system like oAuth Twitter or Facebook, just thinking about that makes me sick though.

1 Like

Yeah, but you should be able to clear input from settings once the app has been installed. This would solve the problem.

What’s scary is my attempts to remove the input values from settings returns outside of that functional call.

This would indicate that app Settings are being stored in more than one place, there is the functional access to it, but then on each function call, it must be pulling the Settings from that other place again.

This second location could be the ideal place to store them securely, or at least give us a way to clear the password or any input after install.

If the user wants to update or re-install, they would have to enter the password again.

OR

Allow an input box not be saved to settings and just used locally. Something like this:

input "Password", type "password, title: "Password", Global:false

This would then mean that the password would only survive the install phase and not save on installation of the smartapp.

1 Like

Not completely sure how clearing the password after app install would work. There would have to be a user session then stored in the app to save the authentication state. The way it works now is that each request that the app uses, the password would have to be used each time, so the password has to be accessible to the application, just hidden from IDE(?). What you’re talking about seems to be more in line with how browsers work with cookies, which would be awesome if that could be executed!

I think that the variable settings are stored in one location right now, in the SmartThings ‘cloud.’ Hub V2 may allow us to keep settings variables stored locally, which I could see would create a parity of these settings values.

SmartThings variable definitions are lazily initiated and evaluated, so once the value is created, it isn’t destroyed until it’s overwritten. If I create a variable Password=‘ABCD’ but then rename the variable to userPassword=‘ABCD’, variable Password will remain on the SmartThings IDE, set to ABCD.

Maybe tech involved in HubV2 will allow these issues to be solved. Perhaps not.

Maybe my use case is fairly unique, but ultimately I only need the password on SmartApp pre-install and not for the entire lifecycle of the SmartApp to function. Because I am having the SmartApp do a login to get an API key and then the SmartApp during its function will just use the API key not the user / password.

Therefore, it is not needed to retain the password after install. However, the issue is there is no way to remove that input value from the settings array.

The other “issue” that has come up is trying to get a count of subscribed devices. I need to exclude all input types from the settings array and only look at the devices that are selected, which isn’t terribly hard, but just have to subtract out any input boxes from that count. You would think there would be a # of devices selected, or at least something that exists inside the settings array that identifies the “type” to be device vs input, etc.

Anyway, I can’t really do much about it other than to wait for supports response or try to hack some sort of workaround to mask or hide the password.

Thanks for raising this, @pstuart. We do take security seriously, but I don’t think our support team understood that you were talking about an issue related to security.

First and foremost, input fields of type password are encrypted in the database, so they are secure in storage. They are encrypted, rather than being one-way-hashed because we assume a password will need to be used for interaction with an external service, as in your case.

I don’t believe we’ve had a request for clearing input fields in the past, but I’ll look into it. I can definitely see the usefulness of that functionality, especially for your use case. More generally, we don’t typically allow a SmartApp to modify any settings that have been entered by the user, which limits some avenues of privilege escalation. This is why your attempts to clear the value resulted in the value coming back in subsequent SmartApp executions. That said, clearing passwords seems like an obvious exception to that rule. In addition, those fields should be excluded from log messages.

To summarize, 1. We will investigate adding a mechanism for to clear passwords if, as a SmartApp developer, you no longer need access to them and 2. We’ll look to exclude password input types from log messages.

3 Likes

@scottvlaminck Thanks for the information and assurance input fields of type password are encrypted in the database and limited in scope to plain text within the SmartApp / DeviceType usage.

I did use the email header: IDE SmartApp Password Input Type Security Issue

What else could I have possibly done to indicate to support that this was a Security Issue?

The person who responded to my request (out of respect I will not name publicly) has since apologized for his response to bring this to the community.

However, I think SmartThings should have an alternative channel beyond support@smartthings.com to report potential security issues or concerns from end users and/or developers.

Thanks again for the public response and I hope we can get something in place quickly to insure that password input types aren’t being displayed in any attempt to log the values.

4 Likes

Hey @pstuart,

I completely agree. I’m personally overviewing forum structure at this time, and finding a way to integrate this. In addition, from what feedback/bugs/concerns and issues, we’re internally solidifying a stronger process of communication for that.

We will update this thread with the best path for these types of reports shortly.

Thanks!