mwhiting has asked for the wisdom of the Perl Monks concerning the following question:
From my original question about .htaccess for password protection on a website that wants to do some credit card stuff:
Hey - thanks for the answers. I am using an SSL server, the original website is on a 'regular' (?) server, and there is also some space I'm using on their SSL server. This is the 'secure' area I was referring to. I've now got the script to create a file (didn't actually realize Perl would be able to just do it anyway, regardless of anything in .htaccess) the way I want it to.
This directory with CC information is not quite an online transaction thing like in bigger companies. The script sends an email to the office staff that there is data to download, so they ftp to the /data directory and copy the file to their own PC. Then they delete the file after they are done. Also the script will look for older files and delete them itself, so there's nothing irrelevant hanging around to cause a problem. It's much more low volume, low tech than what you may have been thinking. The fact that the file & it's contents is physically removed from the server within a short timeframe was my suggestion to the boss. Having nothing there most of the time seemed like the best security to me. I just need to be relatively secure for a short time period.
Freddo411 (if I may call you that :) ), you mentioned "keep the CGI code (except a stub) ... outside of the webroot" What did you mean by 'except a stub'? Just a short cgi script to launch the main one, or what?
Thanks muchly everyone!
Michael
Re: Passing a username/password from HTML to a Perl script
by Abigail-II (Bishop) on Feb 04, 2004 at 22:32 UTC
|
I just want to give a general piece of advice. If you are
going to deal with sensitive data of others (for instance,
credit card numbers) in a hostile environment (the internet),
you better be well prepared, and really know your stuff.
The kind of questions you are asking sets off all kinds of
alarms bells for me; it just screams "I don't really know
what I'm doing, and what to defend against" between the lines.
Prepare yourself well. Go follow a course. Follow another
one. Pick the brains of experienced people - people you trust. Make a plan. Shred it. Make a better plan. Present
that plan to co-workers. Have them shred it. Make an even
better plan. Don't just post a bunch of lose questions on
perlmonks.
Abigail | [reply] |
Re: Passing a username/password from HTML to a Perl script
by freddo411 (Chaplain) on Feb 04, 2004 at 22:11 UTC
|
I have an HTML page there (a product order page) with a form which calls a perl script once the customer has entered all their details in. The perl script needs to create a file in the /data folder and write out some of the information being entered (credit card #, etc).
<Freddo411>: Shudders at the thought of buying things online ;-!
There are many things to worry about when designing and coding web apps for security. Here are a few:
* write the data where the web server cannot see it. This is often done by: a) using a DB on another physical machine b) using a part of the filesystem that NOT visable to the web server (chroot and not under the web root)
Keep in mind that your cgi process must have permission to write/read the file, that means that every CGI on your machine has permission to write/read the file ... IF you store the information unencrypted.
* Encrypt the info. Use your CGI to encrypt the info. Encryption isn't hard to do, but isn't a panacia either. Encryption is based upon using a key and an algorythm to scramble the data. Usually one uses a well known and tested algorythm (see cpan). But the encrypted data is only as safe as the key. Where do keep the key that the CGI must use? If you keep it on the filesystem in a place that the CGI can read it, then it is "open", potentially, for any CGI (or hacked CGI) on the system to read. Really well funded operations use a Hardware Encryption device that securely stores the key, and provides a software interface for encrypting data.
Based upon what you've said so far, the best you can do is to keep the CGI code (except a stub), the encrypted data, and the key file outside the web root using chroot. Make sure that the user that the web server is running as has permission to read (but not write) the key file and the CGI code files. Make sure that no one else can read/write/execute the files or the directories they are in.
Note that this level of security breaks down if the web server is compromised, or if root user is compromised, or if another CGI on the box is compromised.
Good Luck.
-------------------------------------
Nothing is too wonderful to be true
-- Michael Faraday
| [reply] |
|
| [reply] |
|
<Freddo411>: Shudders at the thought of buying things online
/me generally sends a check. Credit cards are risky IRL
just as much as online. Every place where you use a
credit card, there is the potential for an unscrupulous
employee to jot down, memorize, or otherwise keep your
number and use it a year later after they've changed
jobs twice and you've used your card in dozens of other
places. Anything can happen in this scenerio that can
happen if your number is stolen online. You can choose
not to worry about either scenerio, figuring either
that A) it won't happen to you or B) the credit card
company will believe it wasn't you and eat the cost or
C) God has everything under control and will protect
you from any problems that are not his will, but these
things are just as true if you use the card online as
they are if you use it IRL. (The real reason I send
a check though is because I refuse to own a credit
card, because they make it too %$@! convenient to
spend money all the time. One can nickle and dime
oneself into the poor house.)
The thing that's risky about buying online is that if
the website is bogus you may not get your merchandise.
As yet, I've only had that happen four times, and in
each case I was able to get it straightened out (which
implies that the site was not, in fact, bogus, merely
less than altogether on the ball) and
either got the merchandise shipped or got a refund.
(Twice I got a refund, and twice the merchandise
shipped. Only one of the four cases was a real
hassle.) Maybe I've been fortunate in that regard.
But yes, the OP really ought to do something more
robust with the credit card numbers than store them
in a data/ directory. If nothing else, it's *very*
embarrassing for a business to have to announce to
all of its customers that their credit card numbers
have been stolen. For a small business, that can
just totally ruin your public image.
$;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b->()}}
split//,".rekcah lreP rehtona tsuJ";$\=$ ;->();print$/
| [reply] [d/l] |
|
I take your point that credit card numbers can be compromised off-line as well as online.
What's different about online credit card crime? A number of things:
a) volume, steal 100 or 10K numbers in a single swoop. Drop a latte-sized randomized charge on each one.
b) Inclusion of additional info. When I use plastic in a cafe, I don't give them my address/phone/email. Often this is included in an online transaction.
Just so we all don't panic and chop up on the plastic right now, keep in mind that you can disavow any charges you did not make, or that have not be satisfactorially fulfilled. It is the responsibility of the vendor to prove that you did make the charge and that the service has been fulfilled. Until then, you don't pay. This can come in handy when you are not satisfied with the goods ( and yes this is a legal and ethical use of this feature of plastic).
-------------------------------------
Nothing is too wonderful to be true
-- Michael Faraday
| [reply] |
|
> Note that this level of security breaks down if the web
> server is compromised, or if root user is compromised,
> or if another CGI on the box is compromised.
If root user is compromised, what's left there not breaking down?
pelagic
| [reply] |
Re: Passing a username/password from HTML to a Perl script
by scottj (Monk) on Feb 05, 2004 at 00:09 UTC
|
My initial reaction to this post is that I sure hope you're doing all this stuff over an SSL connection. Without SSL, the password protection doesn't reallt even matter.
Sure, htaccess is great, but it's not secure* unless you're on an SSL connection. I use htaccess with SSL all the time.
I guess I just can't stress SSL enough. Especially when dealing with credit cards, SSL is a MUST.
* Exception: Digest Authentication, which probably won't work for you in many cases. | [reply] |
Re: Passing a username/password from HTML to a Perl script
by hardburn (Abbot) on Feb 04, 2004 at 21:26 UTC
|
.htaccess security happens at the web server level. It only comes up when a user tries to access documents in that directory through an HTTP request. Your Perl CGI is running at the OS level. It's only stoped from reading/writing files if the system permissions don't allow it to. htaccess won't stop it at all.
---- I wanted to explore how Perl's closures can be manipulated, and ended up creating an object
system by accident. -- Schemer
: () { :|:& };:
Note: All code is untested, unless otherwise stated
| [reply] [d/l] |
Re: Passing a username/password from HTML to a Perl script
by CountZero (Bishop) on Feb 06, 2004 at 17:34 UTC
|
Write a very short application which relies mostly on a module you have in your Perl tree, which lives outside of the webroot. It limits the interference with your scripts if there is any breach in security on the webserver. They can then read your application and change it, but the main part of the code would be beyond them (well, nothing ever is 100% safe, but that is no reason not to aim for the best possible solution).
CountZero "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law
| [reply] |
Re: Passing a username/password from HTML to a Perl script
by zentara (Archbishop) on Feb 06, 2004 at 18:44 UTC
|
Just thinking about your problem...... It seems you could keep the data encrypted the entire path, except at 1 point ..where you actually receive the ssl-encrypted form data
#instead of
my $ccdata = param('ccinfo');
my $ccdata_enc = encrypt($ccdata);
#maybe use
my $ccdata_enc = encrypt(param('ccinfo'));
This is the weak point, because unless you use some sort
of javascript encryption at the user end, before the data is sent, the sysadmin(or hacker) can intercept the data at that
point of you reading the param.
I must say that it's really unlikely that a hacker would go thru that effort to get 1 cc info at a time. They are looking for big juicy lists.
You could have a system with good security, if you ask the user to download a script, to take the cc data, encrypt it with your public key,
and send it all as a big file, using LWP. That way, you have
additional encryption, beyond the ssl, which the sysadmin(or hacker) would not be able to see. They would see the info, but it would be an ascii-armored pgp encrypted file. In this scenario, you could even bypass the secure server, and have the LWP-perl script email the encrypted data directly to your staff. BUT you would still have to worry about someone sending bogus scripts.
Ah...just brainstorming on an icy Friday afternoon.
| [reply] [d/l] |
Re: Passing a username/password from HTML to a Perl script
by zentara (Archbishop) on Feb 05, 2004 at 15:13 UTC
|
Abigail and Scottj are right. Don't even consider credit card
transactions unless you have SSL, and if you don't have enough saavy to setup a local test server, to test your methods, wait until you do. In the meantime, you could do
something like make a store on your site, but have the payments handled by a third party, which will credit you the amount. That takes the worry off of you, because you never see the cc info. Ebay Sellers work that way. I can't comment on Ebay's Security, but at least it won't be you getting sued. Ebay sellers can have a "homepage store" in addition to what is offered on Ebay, and Ebay will handle the sales for you through their PayPal operation. If you don't like Paypal, there are other similar operations...search for them
and compare the rates they charge for handling your cc transactions. | [reply] |
|
Hi - thanks for the answers. I am using an SSL server, the original website is on a 'regular' (?) server, and there is also some space I'm using on their SSL server. This is the 'secure' area I was referring to. I've now got the script to create a file (didn't actually realize Perl would be able to just do it anyway, regardless of anything in .htaccess) the way I want it to.
This directory with CC information is not quite an online transaction thing like in bigger companies. The script sends an email to the office staff that there is data to download, so they ftp to the /data directory and copy the file to their own PC. Then they delete the file after they are done. Also the script will look for older files and delete them itself, so there's nothing irrelevant hanging around to cause a problem. It's much more low volume, low tech than what you may have been thinking. The fact that the file & it's contents is physically removed from the server within a short timeframe was my suggestion to the boss. Having nothing there most of the time seemed like the best security to me. I just need to be relatively secure for a short time period.
Freddo411 (if I may call you that :) ), you mentioned "keep the CGI code (except a stub) ... outside of the webroot" What did you mean by 'except a stub'? Just a short cgi script to launch the main one, or what?
Thanks muchly everyone!
Michael
p.s. - how do you guys get the carriage returns to stay in your messages? mine are all getting stripped out, which the site says they will be ... but yours aren't?
| [reply] |
|
I'm not a security expert, but have been around long enough to know what the problems are.
First, if your office staff are going to ftp the file, is the file going to be encrypted? Is it going to use ftp-ssl? If not, the cc info can be captured during the transfer. There are some things you are just becoming aware of.... 1. It's not just data on the computer which puts you at risk, its also the transfer of the data...search for network snoopers and you will have your eyes opened. 2. Saying "the data is only going to be there a short time" is a problem. Computer time is measured in milliseconds, and scripts can be written to grab things just that quickly. 3. Keep everything encrypted all the time, and even then you will have to worry about savvy sysadmins who will scrape data off of the memory, where you are using it
unencrypted. Anyways, as you can see, there is very little you can do to ensure security on a remote server. If you really need to be sure, get your own private server setup at your place of business, and keep it locked in a secure room, under a camera. If you can't afford to that, then keep everything encrypted all the way from the user-submit-form to your office staff ftp download. There are still holes in that method, but they can all point to the remote server sysadmin, who you have to trust.
still holes in that method
| [reply] |
|
#!/usr/local/bin/perl
use lib "/Application_Perl_Modules";
use History;
my $webapp = History->new();
$webapp->run();
where "History" is in a file History.pm in the directory /Application_Perl_Modules well outside of the docroot. This makes it impossible for the webserver to display the guts of the CGI source code if the .htaccess controls on the CGI directory fail (for example). You can use this trick without using CGI::Application too. Also note this structure allows you to "reuse" code by having many stubs point to the same module, providing an advantage in code maintenence.
Changing subjects, to answer your other question, paragraph breaks are provided by using standard HTML tags. Read the help ....
Welcome to the monastery. IMHO most useful site on the internet.
Cheers
Nothing is too wonderful to be true
-- Michael Faraday
| [reply] [d/l] |
|
|