Helping ordinary people create extraordinary websites!
GET OUR NEWSLETTER
Your Email:
 

Build a Perl/CGI Voting System

By Allan Peda
2005-07-05


Details: Not-so-secret ballots

The call to the $castBallot->dumpHTMLentrys() method would echo back a detailed accounting of who voted for whom. In practice I would comment this call out, scheduling the Web server to be shut down when elections were over by using the Linux at batch command.

With the server off, you can uncomment this section and restart with the Web server temporarily set to listen only on the localhost address. The full results would be then be echoed back to anyone clicking on a previously submitted link, which can be collected through a copy sent to a dedicated free e-mail account.

Notice that ballots are not tallied twice in this example. These results are hidden using a short JavaScript function in case it was decided to make them discreetly available to everyone in an unobtrusive manner. Admittedly some people would prefer totally anonymous voting, but since club elections are often done as a show of hands, that hardly constitutes a secret ballot.

SASL authentication
Many service providers allow e-mail to be relayed only from mail clients that use SASL authentication. Simple Authentication and Security Layer is a method for adding authentication support to connection-based protocols in which a protocol includes a command to identify and authenticate a user to a server and optionally negotiate protection of subsequent protocol interactions. If its use is negotiated, a security layer is inserted between the protocol and the connection.

When using SASL authentication, you have two options: Either point the script to a machine that can forward the e-mail using correct credentials, or rewrite the script to contact the external SMTP server directly using the Perl Net::SMTP_auth and Authen::SASL modules. (The second option is slower.)

As I thought about this workflow scheme, I realized that the necessity of using a GET-based verification link and the use of unencrypted verification links made it a trivial exercise to read these links and construct a false confirmation ballot based on a specific e-mail address and some known verification links. In order to discourage this, while still allowing the easy debugging via unencrypted links, I decided to add one more twist to the verification process: adding a unique identifier to each draft ballot.

This identifier was based on the operating system process identifier (PID) of the executing script. This was combined with a random number in order to make it difficult to predict the URL to validate a draft ballot. I was concerned about this because a malicious individual might be able to deconstruct the very visible URL patterns in order to create false confirmation ballots. This is the one part of the code that would not translate directly to a mod_perl version, since it relies on the use of the PID of the running Perl instance concatenated with random digits. If the form is generated from a reused mod_perl instance, the PID number will not necessarily change between invocations.

In hindsight, I realize that the best way to obfuscate this link would be to use an MD5-generated hash value, effectively hiding all voter information. This would have the dual benefit of being pretty tough to forge, while remaining portable to mod_perl-based scripts. The drawback would be that the code is slightly more difficult to debug by inspecting the exchange of information between the client and the server.



Tutorial Pages:
» Using locked DBM files with CGI-driven forms saves client data without DBMS overkill
» CGI considerations: Simplicity vs. complexity
» Functional design considerations
» Details: Hash keys
» Details: E-mail gotchas
» Details: Not-so-secret ballots
» Details: File layout
» Details: Static vs. dynamic DNS
» Details: Is GET harmful?
» Other possible improvements
» Conclusion
» Resources


First published by IBM DeveloperWorks


 | Bookmark
Related Tutorials:
» Random subroutines in Perl
» Log Script Use
» Creating Perl Modules for Web Sites
» Bit Vector, Using Perl Vec
» Perl Range Operator
» Creating Perl Modules for Websites

Advertise with Us!


Tutorials Scripts Web Hosting Developer Manuals
Resources