Re: DBI & CGI Security
by samtregar (Abbot) on Jun 03, 2004 at 16:19 UTC
|
Security question is can I do some sort of include to include the auth info for the DB server so I do not have that in my main CGI?
I suggest you pick up a good on CGI programming in Perl, like O'Reilly's CGI Progamming with Perl. Any good CGI book will cover building a simple login system. Once you see how it's done adapting it to "include the auth info for the DB server" (whatever that means) shouldn't be hard.
My idea for sanity checking is to load the PTR and A record tables into an array for given domain name and then use Array::Compare to test for the data set in both
I don't know much about your application, but this sounds like a really poor idea. You should find a way to express this check as one or more SQL statements which will let MySQL do the heavy lifting for you. With the proper indexes I'm sure MySQL can beat Array::Compare.
-sam
| [reply] |
|
Well the auth on the server side is not a real issue I can hendle that via .htaccess but the security I was and am looking for is more or less for the DBI connect I want to hide that so as to take more of the risk out the DB being compromised, Does that make more sense?
| [reply] |
|
What kind of attack are you trying to prevent? Are you trying to make it so that an attacker could get into the web server but not be able to get into the database? That's an unusual requirement...
I'm not sure what the best way to do it would be. Maybe encrypt the DB password and store it on disk. Then require the admin to enter the decryption password whenever the server is started. The server would load the decrypted password into memory and use it to connect to the DB. It's still vulnerable to a root compromise since the plaintext password will exist in memory, but it would keep the password unreadable on disk. You'd still be vulnerable to key-loggers and the like, of course.
Ultimately it's hard to create a system that can do a given job but won't let an attacker do the same job if they break in.
-sam
| [reply] |
|
I assume you don't want the users to supply the password for the DBI connect string, right? If that is the case you could store the password in a file (encrypted with some sort of PKI possibly). Just a suggestion, hopefully some monk will give a better one. Also you might want to poke around the Monastery some more. I've seen this issue discussed before here. I asked a simiular question a while back and got many good suggestions.
Plankton: 1% Evil, 99% Hot Gas. |
| [reply] |
|
|
| [reply] |
Re: DBI & CGI Security
by jZed (Prior) on Jun 03, 2004 at 16:11 UTC
|
| [reply] |
Re: DBI & CGI Security
by jayrom (Pilgrim) on Jun 03, 2004 at 16:47 UTC
|
What I do for the DB auth info is put the login and password in a text file outside the web server realm.
You can open the file from your DB login script and parse it to retrieve the login and password.
Something like this:
my $file = '/path/db.txt';
open FILE, '<', $file or die $!;
chomp(my ($auth) = <FILE>);
my ($dbuser, $dbpasswd) = split('\t', $auth);
close FILE;
Hope this helps.
jayrom | [reply] [d/l] |
|
I have followed this exact scenario, though I encrypt it with Crypt::CBC.
Here's how my code looks:
my ($username, $keyfile, $domain) = @_;
open (PASS, "</home/$username/$keyfile") or die "Error: $!\n";
flock (PASS, 2);
my @keypass = <PASS>;
close (PASS);
foreach (@keypass) {
chomp $_;
}
my $cipher = Crypt::CBC->new($keypass[0], 'Blowfish');
my $dbpass = $cipher->decrypt($keypass[1]);
use DBI qw(:sql_types);
my $userdatabaseName = "DBI:mysql:$domain";
my $userdatabaseUser = $username;
my $userdatabasePw = $dbpass;
$dbh = DBI->connect($userdatabaseName, $userdatabaseUser,
$userdatabasePw, { RaiseError => 1},) or die "Connect failed: $DBI::er
+rstr\n";
I also recommend the aforementioned O'Reilly's "CGI Progamming with Perl." And take a look at this node on CGI and passwords.
—Brad "A little yeast leavens the whole dough."
| [reply] [d/l] |
|
I like the way you used encryption. I also often forget to lock the file when I only read it ;-)
This may be a silly question, and it doesn't mean to be ironic, but does encryption make a difference?
Indeed having a text file with the db auth on the server is only slightly better than having it in a script within the web server realm.
But, if you bear with me, if someone gets access to that file couldn't we assume that they also had access to the script? Also given that the key has to be included somewhere, how hard would it be to figure out the whole thing?
Should we encrypt the auth by default for the sake of good security practice?
jayrom
| [reply] |
|
|
|
One note with that code is that you may want to structure it something like this:
use vars qw[$dbuser $dbpass $dbsecret_time];
my $secretfile = '/path/db.txt';
my $secretfile_modtime = stat($secretfile)[9];
if (!$dbsecret_time or $dbsecret_time < $secretfile_modtime)
{
open FILE, '<', $file or die $!;
chomp(my ($auth) = <FILE>);
($dbuser, $dbpasswd) = split('\t', $auth);
close FILE;
$dbsecret_time = $secretfile_modtime;
}
The reason is that if you ever want to run this code under mod_perl or something similar, you probably won't want to hit the dbpass/secret file more often than necessary.
--
@/=map{[/./g]}qw/.h_nJ Xapou cets krht ele_ r_ra/;
map{y/X_/\n /;print}map{pop@$_}@/for@/
| [reply] [d/l] [select] |