bcrowell has asked for the wisdom of the Perl Monks concerning the following question:

I've written a Perl/Tk application that helps teachers keep track of their students' grades. So far, security is not that much of an issue, because the software runs locally on the teacher's machine. However, I do have a primitive provision for posting students' grades on the web so they can type in a password and see how they're doing in the course. The security is, admittedly, very low -- just one step above posting grades on your office door -- but presently it's not a big deal, since data only flows one way, from the teacher's machine to the web server. The worst consequence of a security breach is that someone finds out how someone else is doing in the class.

I have plans, however, to build a more ambitious suite of software, including things like online quizzes that would count towards the student's grade. For that, I'm going to need a more serious, systematic approach to security. I need to handle logins by both students and teachers, and I need to securely move larger amounts of data in both directions, not just from client to server.

I have a general idea of the techniques involved in doing this right, e.g., storing only encrypted passwords on the server, so that a person who gets access to the passwords file still can't use them for anything; using protocols like https and sftp, rather than http and ftp; checking for tricky stuff embedded in strings input to the CGI; etc. But I need some suggestions on how to learn more about the specifics of how to implement these things. Can anyone recommend a good book and/or a well-crafted open-source Perl CGI app that I could study for examples of these techniques?

I'm not really asking for complete explanations here, because this is obviously a very big topic. But here are some specific examples of the kind of information that I need pointers to:

  1. Net::SFTP isn't going to be a viable option for me, since it's too hard for my users to install. (Heck, it was too hard for me to install!) Is there a C alternative with the appropriate Perl interface?
  2. Http GET and POST are obviously not the right way to move large amounts of data (10-100k), or to do it securely. What's the alternative? How do you securely upload this amount of date to a subdirectory in the cgi-bin?
  3. There's obviously a lot of finicky stuff that one needs to take care of when users are logging in: letting them change their password if they've forgotten it; generating an error message if their browser doesn't allow the necessary mechanisms (JavaScript, cookies,...). Is there a good bulletproof package for this?
  4. In the past, I've written this kind of CGI login system for a lower-security system, and used a cookie to show that the person was logged in. This seems clearly wrong for a secure system, since they may forget to log out. Are hidden JavaScript variables the right way to do this? Again, I'd like to use a tested, canned package if possible.

Edited 2002-23-04 by Ovid

Replies are listed 'Best First'.
Re: secure CGI: books and examples?
by erikharrison (Deacon) on Apr 23, 2002 at 18:18 UTC

    You have the right ideas in general, which is good to hear for once. Ovid has a great CGI course which covers security in detail, and should be refered to if needed.

    A thing to keep in mind is that you shouldn't be looking for dangerous things to strip out of input, you should be looking for safe things to keep. You should be using secure protocols, as you mentioned. http://nms-cgi.sourceforge.net/ is a good place to look at secure drop in replacements for the insecure scripts that populate the web. merlyn's WebTechniquescolumn is ver useful, and discusses the secure use of cookies, amongst other things.

    Hope these things are useful.

    Cheers,
    Erik
      Excellent references. Here's a couple more: Lincoln Stein (author of CGI.pm) maintains a CGI-centric site here and more general info here. Hosted at w3.org, so I trust it;)
Re: secure CGI: books and examples?
by Necos (Friar) on Apr 23, 2002 at 18:28 UTC
    Aside from the good resources that Erik pointed out, you should also look at the Perl/CGI books on the O'Reilly webpage. You could also look at Amazon/B&N/etc., but I tend to trust O'Reilly books more. The books to look for are "CGI Programming with Perl, 2nd Ed" and "Programming the Perl DBI." The latter, just in case you decide to do some database work on the server-side.

    Hope this helps just a little bit, in addition to the other reply.

    Theodore Charles III
    Network Administrator
    Los Angeles Senior High
    4650 W. Olympic Blvd.
    Los Angeles, CA 90019
    323-937-3210 ext. 224
    email->secon_kun@hotmail.com
    perl -e "map{print++$_}split//,Mdbnr;"
(ichi) Re: secure CGI: books and examples?
by ichimunki (Priest) on Apr 23, 2002 at 19:09 UTC
    1 & 2. Why not use GET and POST over https? For a non-web-based solution (assuming the server is Unix/Linux), you might use scp (part of ssh)? ssh clients are easy to come by, and since the admin process is normal user management it might be easier than trying to web-fronted all that stuff (especially from scratch). The ssh tools are in widespread use too, so that gets to your "bulletproof" point. Just a thought.

    If you don't want to offer raw shell access, you could write a pseudo-shell for your clients/users (perhaps even in Perl). Something like KISS, or other menu-driven login. There's no reason users require access to BASH or KORN shells, after all.

    3. I don't keep up on what's available, so no comment.

    4. You can theoretically expire a cookie on the client side, you can also put a session ID into the cookie and track that, along with a time-limit, on the server side. In a stateless protocol like HTTP you're not going to be able to do a strict timeout, so this would be the next best thing.

Re: secure CGI: books and examples?
by Rex(Wrecks) (Curate) on Apr 23, 2002 at 19:17 UTC
      Here are a couple books I found invalid when I was learning CGI:

      I hope you found them invaluable as well;-)

Re: secure CGI: books and examples?
by beebware (Pilgrim) on Apr 23, 2002 at 20:56 UTC
    1: I haven't got a clue about secure FTP, I've never come across a site that needs it (yet!).
    2: POST is ideal for large data packets. Using the form-upload method (which is 'POST'ed data), 30Mb files are uploaded no sweat! (above that and things start to fall apart due to the time needed to transfer it all).
    3: Don't store the passwords in plain text. If someone forgets their password, email them a link which then takes them to a page with a 'security question' (for example: What is the last three digits of your student number and your date of birth?) and _then_ allow them to change their password (putting limits of 7+ characters, mixed case+numbers etc etc).
    4: Don't use Javascript for authentication.I would personally use the standard 'Browser Authentication' method of the 401 Unauthorised type (can't remember it's proper name at the moment). Add to that a session ID in the URL and hidden computed checksums on form uploads and you've got a nice secure system. Add https usage and you've got a ecommerce site :D. Look how sites similar to Amazon et al do things and improve upon them.
    To cut down on the encrypted connection side, only use it for user authentication and the actual question/answer pages.
    Don't forget to not trust user input! You may find How to code for Incorrect Clocks and Rapidly Expiring Cookies, Cookie based authentication: Is it Secure?, Essential CGI security Practices useful.
Re: secure CGI: books and examples?
by Zaxo (Archbishop) on Apr 23, 2002 at 22:40 UTC

    The big proplem is going to be identification, not authorization. A poor student may give her password to a better one if online quizzes are offered. That is a much harder problem than authorization, and I don't know a practical solution for schools. The students won't share a secret with you that they won't share with each other.

    After Compline,
    Zaxo

      BTW, thanks to everyone for their excellent, thoughtful replies!

      Zaxo, re the specific issue you raise, I don't think an onlin format is appropriate for quizzes that are high-stakes, but for a low-stakes quiz, I think it might do the job. Also, most people doing this kind of thing use a big bank of questions, so no two students are taking the same quiz. A bigger issue, from what I've heard, is that if you're using the quizzes to arm-twist the students into doing the reading, they may take the quiz with the book in their laps, without having read it first!

      To me, the big security issue is simply making sure students can't crack the system and change their grades at will...

Re: secure CGI: books and examples?
by cjf (Parson) on Apr 24, 2002 at 07:00 UTC
    Can anyone recommend a good book

    I Certainly can. CGI Programming with Perl, 2nd ed. is an excellent book. It has an entire chapter on security, as any good CGI book should, and is very well written and easy to understand. It also uses excellent examples, and covers CGI.pm, templates, email, and a whole bunch of other good stuff. I'll stop typing now so you don't think the author paid me to post this ;-).

Re: secure CGI: books and examples?
by DigitalKitty (Parson) on Apr 24, 2002 at 13:44 UTC
    Hi.

    The following two titles are excellent:

    Writing CGI Applications with Perl List Price: $39.95 Addison-Wesley Pub Co; ISBN: 0201710145 A very good book. Provides quite a few partial/complete in-depth examples. See below for table of contents

    CGI Programming with Perl List Price: $34.95 O'Reilly & Associates; ISBN: 1565924193 Concise text. Explains the fundamental aspects of web server/cgi interaction.

    Preface. Acknowledgments. 1. Perl, CGI, and this Book. What Is Perl? What Is CGI? Why Perl Is Good for CGI.

    About this Book. Who Is this Book For? Conventions Used in this Book. Using perldoc.

    Using the CPAN.

    2. What You Should Know. Prerequisites. Editors. File Permissions. Basic Security Concerns. Using -T. Checking for Taintedness and Laundering Data. Your PATH and -T. Installing a Script. Troubleshooting. Caching. The Expires HTTP Header. Cache-Control HTTP Header.

    Listings.

    3. Using Your Environment. Introduction to %ENV. Adding to %ENV. Form Input Primer. Example Script: Visitor Log. Example Script: Basic Report. Reader Exercise. What Have We Learned? Listings.

    4. Introduction to Web Forms. Introduction. Form Tags. Reading Form Input with CGI.pm. Making Your Users Happy. Final Example. User Exercises. Program Listings.

    5. Working with Cookies. Introduction. Security. Limitations. Cookie Pieces. Working with Cookies the Manual Way. Baking Cookies with CGI.pm. Controlling User Preferences with Cookies. User Exercises.

    6. Access Counters. Introduction. Example Script: SSI Text Counter. Example Script: SSI Image Counter. Example Script: SSI Text Counter, with a Twist. Example Script: An Imageless Image Counter. Counter Conclusion. Reader Exercises. Listings.

    7. Web-Based File Uploading. Introduction. File Uploading Basics. Viewing Files. Uploading Multiple Files. Reader Exercises. File Listings.

    8. Tracking Clicks. Introduction. Example Script: A Simple Click Tracker. Example Script: Random Images. Example Script: Click Tracking (Reprise). Reader Exercises. Listings.

    9. Using mod_perl. What Is mod_perl? Configuring mod_perl. Apache::Registry. Automatic Headers and Footers with Apache::Sandwich. A mod_perl Photo Album with Apache::Album. Authentication with Apache::AuthDBI. Writing a mod_perl Handler. Reader Exercises. Listings.

    10. Web-Based E-mail. Introduction. Example Script: Checking POP3 Mail via the Web. Example Script: Reading E-mail via the Web. Example Script: Displaying Attachments. Example Script: Composing E-mail. Reader Exercises. Listings.

    11. Introduction to DBI and Databases on the Web. Introduction. Using the Perl DBI. Connecting to the Database. Disconnecting from the Database.

    Preparing and Executing an SQL Query. Fetching Data. The fetchall_arrayref( ) Method. The fetchrow_arrayref( ) Method. The fetchrow_hashref( ) Method. The bind_columns( ) Method.

    Putting It All Together. The do( ) Method. Wrapping It Up.

    Reader Exercises. Listings.

    12. Tied Variables. Introduction. Setting It All Up. Getting Started. Diving In. The Main Program. Finishing the ShopCart Module. Running the Program. Wrapping It Up. Program Listings.

    13. Embedding Perl in HTML with Mason. Introduction. Installation. The Strategy. Mason Syntax. Special Mason Components. Cascading Execution. Moving Right Along. rss2html. my_news. footer. Wrapping It Up: The Code for the Example Site.

    14. Document Management via the Web. Introduction. The Plan. auth.cgi. shared.pl. main.cgi. upload.cgi. viewer.cgi. Program Listings.

    15. Dynamically Manipulating Images. Introduction. Adding Shapes and Text. Creating a Dynamic Graph. Creating Thumbnail Images. Filtering Images with Image::Magick. Animated Images. Reader Exercises. Listings.

    16. RSS And XML. XML and RSS Overview. Structure of an XML Document.

    News Portals with RSS. A Home Page News Portal.

    Creating an RSS File. Reader Exercises. Listings.

    Appendix A. Server Codes. Provide confirmation that a request is being processed. Request was performed. Request not performed. Request is incomplete. Internal server errors.

    Appendix B. Environment Variables. Appendix C. POSIX::strftime( ) Formats. Appendix D. General Public License. Appendix E. Artistic License. Appendix F. Perl Documentation. Appendix G. ASCII Codes. Appendix H. Special HTML Characters. Resources.

    You might also find the following links useful:

    http://www.devshed.com

    http://perl.about.com

    http://www.webmonkey.com

    Hope this helps,

    -Caitlin.