Return-Path: Delivered-To: apmail-perl-embperl-archive@perl.apache.org Received: (qmail 80441 invoked by uid 500); 14 Jan 2003 22:30:05 -0000 Mailing-List: contact embperl-help@perl.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: list-post: Delivered-To: mailing list embperl@perl.apache.org Received: (qmail 80366 invoked from network); 14 Jan 2003 22:30:05 -0000 Mime-Version: 1.0 X-Sender: nazgul@somewhere.com@puremessaging.com Message-Id: Date: Tue, 14 Jan 2003 17:30:04 -0500 To: embperl@perl.apache.org From: Kee Hinckley Subject: DBIx::Recordset/Embperl security question Content-Type: text/plain; charset="us-ascii" ; format="flowed" X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N One of the great features of of the Embperl/DBIx::Recordset combination is the ability to pass %fdat directly to a database update or insert call. Recordset takes the parameters that exist in the record and ignores the rest. You can easily update your database and your web forms without having to update all the code inbetween. The risk, however, is when a malicious web user either knows, or guesses, some of your database structure and attempts to manipulate the update. For instance, they might take a form that creates a new account, and add a field to the form that sets the class of user, thus giving themselves administration rights instead of the default user rights. There are two solutions to this. The most secure one is that you never pass %fdat directly to the Recordset calls. Instead you pass a slice of it, where you explicitly determine which parameters you want to pass. foreach $key (qw(good1 good2 good3)) { $newhash{$key} = $fdat{$key}; } or @safe = qw(good1 good2 good3); @newhash{@safe} = @fdat{@safe}; The slightly more risky, but far more convenient, especially during development, solution is that you deliberately delete or override the fields you don't want the user to set. foreach $key (qw(bad1 bad2 bad3)) { delete $fdat{$key}; } The other day though, it occurred to me that there's a hole in the second case that isn't easy to plug. Namely, what if the attacker uses a different, or mixed case, version of the keyword name. $fdat is case sensitive. DBIx::Recordset is (normally) not. What happens when I set $fdat{foo} to 'user', and the attacker sets $fdat{FOO} to 'admin' and both get passed to Recordset? Does anyone have any suggestions here? Or is the only safe course to take the "explicitly specify what you want to pass" route? (And if so, is there a better way to copy one slice of a hash to another?) -- Kee Hinckley - Somewhere.Com, LLC http://consulting.somewhere.com/ I'm not sure which upsets me more: that people are so unwilling to accept responsibility for their own actions, or that they are so eager to regulate everyone else's. --------------------------------------------------------------------- To unsubscribe, e-mail: embperl-unsubscribe@perl.apache.org For additional commands, e-mail: embperl-help@perl.apache.org