Connection String in .config file - Security Concerns

G

Guest

Hello,

I have developed a web application that connects to 2 different database
servers. The connection strings with db username + password are stored in
web.config file.
After a code review, one developer suggested that it's a security flaw;
therefore connection strings should be kept somewhere else or encrypted.
My argument is that web.config file is protected by IIS and Windows security
which is the case. And another argument is that encryption would probably
require a key or cipher which also would have to be stored somewhere. Hard
coding it in the code would mean that someone could easily disassemble web
app .dll file and get that key, if someone already was smart enough to breach
IIS and Windows security.

My questions to you:
1. Any real life concerns keeping connection strings in .config files
2. Other locations where connection strings can be kept securely
3. If you do recommend encryption, what encryption methods, Where should key
be kept.

Thank you
 
M

Marina

It really depends on how ultra secure you need to be.

You can argue that if someone gained access to your machine to the point
that they can look at your web.config, then it is too late anyway, and that
person already has enough access to inflict all sorts of damage.

Now, beyond that, it is about how much harder you want to make it for the
person who breached your security. Certainly reading it from a config file
is a lot less work then decompiling a dll (or many dll's), and searching
through it looking for the one spot where the encryption key is. Then the
person has to write a little program or something to decrypt using your
encryption key. Now you have added a lot more work, and so this hacker may
not actualy go and do all this.
 
P

Peter Rilling

Well, security is definitely a concern. First, do you want to trust Windows
in its security, however, it is not like they have had any significant
vulnerabilities. ;-)

Second, if anyone was to gain physical access to the machine they would be
able to see the credentials.

In short, best practices says that credentials should not be stored in
plaintext.

There are two ways of going about securing you databases.

1) Encryption is a possibility. You are correct about the problem with
storing a key. That kind of defines the chicken-and-the-egg problem in that
in order to secure secrets you must define new secrets. One way around this
would be to use the DPAPI that is part of Windows
(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/SecNetHT07.asp).
This does not require that you use a key because it derives the key from
information on the system.
2) You can use trusted connections between SqlServer and your website.
This means that you do not have to store the username and password. You can
simply tell IIS to trust the webserver account.
 
P

Peter Rilling

This only works with certain elements in the config file. I do not think it
works with any arbitrary content. This has been a complaint of mine for
some time about this utility.

-----
When you apply the hotfix that is described in Microsoft Knowledge Base
article 329250 (see "References"), you can use encrypted data that is stored
in the registry instead of plain text in the following configuration
sections: . <identity userName= password= />
. <processModel userName= password= />
. <sessionState stateConnectionString= sqlConnectionString= />
 
N

Nicholas Paldino [.NET/C# MVP]

In reality, there is a security concern. There is never a solution in
security, which is why everything is called a "deterrent".

If you set IIS up properly, and assuming that there are no security
flaws in IIS which would serve up the config file (ha!), you still have to
worry about internal threats. If someone has access to the machine, then
they can easily look in the web config file for the username and password
that accesses the database.

You can encrypt the string, but then you have to protect the key.
However, encryption is a deterrent, because no one is going to try and brute
force the decryption. Here is a blog entry regarding encrypting the
connection string in ASP.NET:

http://weblogs.asp.net/owscott/archive/2005/07/29/421063.aspx

However, I think that neither of these is a good solution. Personally,
I think that you should be using windows authentication to access your DB
server (SQL Server does this, I dont know about others). Of course, I don't
recommend that you allow the ASPNET user to access the SQL Server. Rather,
if you are using windows identities, and you are impersonating, I would use
a trusted connection.

Even if not using windows identities, I would place my data operations
in a class derived from ServicedComponent that ASPNET can access, and then
have the ServicedComponent (COM+) run under a single user account that has
acceess to the database. You can set the connection string as the
construction string for the ServicedComponent, and use a trusted connection.
Then, only administrators can access the components on the machine, and see
the connection string, and if they did, they wouldn't know the credentials
to the database.

Hope this helps.
 
M

Marc Gravell

You can encrypt several sections (including connection strings) using the
in-built encryption methods in ASP.NET 2.0;

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/paght000005.asp

This protects the file from plain text (reading) attacks. *however*, if
somebody can write a simple .NET web-page, it can *directly* read the
unencrypted values (the encryption is completely transparent to an ASP.NET
web-page running in the correct account). For this reason, using this
approach I would still not recommend storing passwords (trusted logins being
preferable). And because the connection-string section in ASP.NET is well
supported, it is also very easy to ask "what connection strings have you
got?" rather than needing to know anything in advance. This can be done with
a simple ashx dumped into the root of the web application - in less than a
page you can attempt to connect to all the servers listed and try to get
their catalogues...

IMO any DPAPI wrapper is, in its way, susceptible to the same type of
attack - as long as they can get code to run in an account that has access
to the read-keys (i.e. the web-server's account), it can be hacked. If
somebody can be bothered.

But as sombody else observed, if they can get this far you're already in
trouble...

Marc
 
G

Guest

THe problem with using trusted connections to SQL Server is that connection
pools don't work with trusted connections. Also, trusted connections only
work when the SQL Server is on the same machine as IIS.

The rest of what everyone has said is definitely correct, in the
circumstances where those solutions (or deterrents) work best.

If you're able to use the Enterprise Library, it has relatively secure
encryption capability for the connection string.

In the project I am currently working on, Enterprise Library is not an
option (which is fine with me - I'm not a big fan of it anyway) and because
the IIS machines are separate from the database (the database is DB2 on a
mainframe) and the IIS servers are, by policy, not allowed to access the
registry.

As a result, I just wrote a simple encryption/decryption utility based on my
article at
http://www.dalepreston.com/Blog/2005/02/i-just-want-to-encrypt-this-simple.html.

The problem with this, and all solutions that are not DPAPI based, is that
the server has to be able to access the encrypted data and the decryption
key. If someone can get to the server to find the web.config file in the
first place, they will have access to the encrypted connection string and the
key to decrypt it.

The best you can hope to do, and you should do it, is to encrypt the string,
hide the key as best you can using Windows security, either in the file
system or in the registry, or even in your app, and hope that is enough
deterrent for someone who penetrates your physical and file system security
otherwise.

Or, put IIS and SQL Server on the same box, forfit connection pooling, and
use Windows Integrated Authentication.
--
Dale Preston
MCAD C#
MCSE, MCDBA


Nicholas Paldino said:
In reality, there is a security concern. There is never a solution in
security, which is why everything is called a "deterrent".

If you set IIS up properly, and assuming that there are no security
flaws in IIS which would serve up the config file (ha!), you still have to
worry about internal threats. If someone has access to the machine, then
they can easily look in the web config file for the username and password
that accesses the database.

You can encrypt the string, but then you have to protect the key.
However, encryption is a deterrent, because no one is going to try and brute
force the decryption. Here is a blog entry regarding encrypting the
connection string in ASP.NET:

http://weblogs.asp.net/owscott/archive/2005/07/29/421063.aspx

However, I think that neither of these is a good solution. Personally,
I think that you should be using windows authentication to access your DB
server (SQL Server does this, I dont know about others). Of course, I don't
recommend that you allow the ASPNET user to access the SQL Server. Rather,
if you are using windows identities, and you are impersonating, I would use
a trusted connection.

Even if not using windows identities, I would place my data operations
in a class derived from ServicedComponent that ASPNET can access, and then
have the ServicedComponent (COM+) run under a single user account that has
acceess to the database. You can set the connection string as the
construction string for the ServicedComponent, and use a trusted connection.
Then, only administrators can access the components on the machine, and see
the connection string, and if they did, they wouldn't know the credentials
to the database.

Hope this helps.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

WebMatrix said:
Hello,

I have developed a web application that connects to 2 different database
servers. The connection strings with db username + password are stored in
web.config file.
After a code review, one developer suggested that it's a security flaw;
therefore connection strings should be kept somewhere else or encrypted.
My argument is that web.config file is protected by IIS and Windows
security
which is the case. And another argument is that encryption would probably
require a key or cipher which also would have to be stored somewhere. Hard
coding it in the code would mean that someone could easily disassemble web
app .dll file and get that key, if someone already was smart enough to
breach
IIS and Windows security.

My questions to you:
1. Any real life concerns keeping connection strings in .config files
2. Other locations where connection strings can be kept securely
3. If you do recommend encryption, what encryption methods, Where should
key
be kept.

Thank you
 
M

Marc Gravell

Also, trusted connections only work when the SQL Server is on the same
machine as IIS

No; trusted connections using a domain account will work anwhere within that
domain; if you use machine (not domain) accounts, you can mirror the account
(same name and password) on 2 machines trusted connections can work.

Marc
 
W

Willy Denoyette [MVP]

|> Also, trusted connections only work when the SQL Server is on the same
| > machine as IIS
|
| No; trusted connections using a domain account will work anwhere within
that
| domain; if you use machine (not domain) accounts, you can mirror the
account
| (same name and password) on 2 machines trusted connections can work.
|
| Marc
|
|

Very true, and connection pooling works also as long as they use the same
credentials to connect to the same Server instance.

Note that, "trusted connections" aren't used to authenticate when the client
and the server (here SQL server) are running on the same box. Trusted
connections are used by the 'local' LSA to connect to the 'remote' LSA, when
both client and server are on the same box the LSA is the same for the
client and the server and no authentication handshake is needed.

Willy.
 
G

Guest

IIS will not pass the users credentials to SQL Server on another machine even
if you set your application for impersonation. The only credentials it will
pass are those for the service account that your IIS application is running
under.
 
W

Willy Denoyette [MVP]

That's why I said, the "same user credentials", right?
Connection pooling is used when an "application" creates "multiple
connections" with the 'same' SQL Server using the 'same' windows
credentials. That means that you have as many pools as there are credentials
used to connect to the same SQL server.

The point is that you should use the same credentials when connecting to the
same instance of the server to take advantage of connection pooling, that
is, you shouldn't impersonate the client in IIS to connect to external
resources (which would require Kerberos delegation anyway).


Willy.

| From
|
http://msdn.microsoft.com/library/d...y/en-us/vsent7/html/vxconDatabaseSecurity.asp:
|
| "There are some drawbacks to using integrated security, most of which you
| can overcome. Because integrated security requires a Windows account, it
| defeats connection pooling if you impersonate each authenticated principal
| using an individual Windows account."
|
|
| --
| Dale Preston
| MCAD C#
| MCSE, MCDBA
|
|
| "Willy Denoyette [MVP]" wrote:
|
| >
| > | > |> Also, trusted connections only work when the SQL Server is on the
same
| > | > machine as IIS
| > |
| > | No; trusted connections using a domain account will work anwhere
within
| > that
| > | domain; if you use machine (not domain) accounts, you can mirror the
| > account
| > | (same name and password) on 2 machines trusted connections can work.
| > |
| > | Marc
| > |
| > |
| >
| > Very true, and connection pooling works also as long as they use the
same
| > credentials to connect to the same Server instance.
| >
| > Note that, "trusted connections" aren't used to authenticate when the
client
| > and the server (here SQL server) are running on the same box. Trusted
| > connections are used by the 'local' LSA to connect to the 'remote' LSA,
when
| > both client and server are on the same box the LSA is the same for the
| > client and the server and no authentication handshake is needed.
| >
| > Willy.
| >
| >
| >
| >
 
M

Marc Gravell

Ahh... No, I'm talking about a "Trusted Subsystem" model, where-by the
authentication (at the boundary to the web-server) is *not* the same as the
identity used to connect to remote resources. This would generally be a
single (least-priveleged) account, with access to exactly the servers etc
that it needs. This can be done using either app pools or serviced
components (the first being simpler to implement and manage, but potentially
more open to abuse if somebody can infect your web-server)

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/paght000008.asp

The title sounds promising: "How To: Connect to SQL Server Using Windows
Authentication in ASP.NET 2.0"

Marc
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top