Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Is this a bug in HTML::Form::Input or am I doing something wrong?

by Pug (Monk)
on Mar 01, 2002 at 00:24 UTC ( [id://148438]=perlquestion: print w/replies, xml ) Need Help??

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

Sorry this is kind of long winded.

I have a program, acting like a browser, that logs into a server. It needs fill out a form (that is done) and then when the program hits submit, upload a file to the server.

I have use HTML::Form to fill out the form and to give the HTML::Form the proper path and file name, which works. But when LWP::UserAgent->request($form->click("submit")) happens I get a 500. The code I wrote is below.

# This works fine. Here I get the form. $form=_get_new_form($self,$response->as_string,$response->base); if($form==0) { return 0; } # Here I am filling out the form. foreach $input ($form->inputs) { if($input->name eq "email") { $form->value($input->name,$email); } if($input->name eq "clientCertReq") { $form->value($input->name,$file); } } #Here is where the problem is. $response=$agent->request($form->click("submit")); if(!$response->is_success) { $ERROR=$response->error_as_html; return 0; } return 1; } sub _get_new_form { my ($self,$html,$uri,$form)=@_; $form=HTML::Form->parse($html,$uri); if(!defined ($form)) { return 0; } return $form; } }
$ERROR has in it your basic 500 error page. At $form->click("submit") I did a
print $form->click("submit")->as_string();
Which gave me the following output.

POST http://server:8080/Foo/servlet Content-Length: 332 Content-Type multipart/form-data; boundary=xYzZY --xYzZY Content-Disposition: form-data; name="email" this_email@address.com --xYzZY Content-Disposition: form-data; name="clientCertReq" /tmp/CERTS/new.cr.DER --xYzZY Content-Disposition: form-data; name="submit" submit --xYzZY--
Which when you look at the code for LWP::UserAgent It does not do anything special with Content-Disposition. The input that has the name "clientCertReq" is a HTML::Form::TextInput object. But if you look at HTML::Form::TextInput (it is in the HTML::Form file.) The comments below that point say
#input/text
#input/password
#input/file
#input/hidden
#textarea
But there is no code to open a file and add the data from the file to the Content-Disposition field. I have looked for other soluations using HTTP::Request::Common->POST but that seems more work for me considering that LWP::UserAgent->request seems to eventay calls HTTP::Request::Common->POST.

So is this a bug or am I doing something wrong?

Edit by dws to add <readmore> tag

Replies are listed 'Best First'.
Re: Is this a bug in HTML::Form::Input or am I doing something wrong?
by Speedy (Monk) on Mar 01, 2002 at 01:27 UTC
    I think this is the case of a security feature rather than a module bug.

    The input="file" form element in the HTML DOM is read-only from any script. In short, it can be filled out or entered only by a live user, not by a script.

    This same issue came up 3 nights ago in another question about using a script for automatic uploading using the contents of a cookie.

    Ovid's answer explained that "If you could just supply the filename in a cookie, this would be a major security hole because you could silently upload files without the user's consent." I spent some time trying to find a work-around, but finally concluded that, for good security reasons, there is none, especially when the type="file" form element is read-only from a script. So no script nor module can do what you are proposing, but this is a feature, not a bug.

    Live in the moment.
      Ops I missed that talk. You would think that because I am writing the client side of things. (I am writing a program to test a HTTP server) I could do that. Ohh well. Thanks for the help.
      The input="file" form element in the HTML DOM is read-only from any script. In short, it can be filled out or entered only by a live user, not by a script.

      This is not right. You can upload a file from script if you include its correctly encoded contents in the script generated HTTP request.

      Ovid's comment regarding filenames in cookies is not related to this. As I understood it he just meant that there is no way to make a browser upload a file whose name has been provided by the server in a cookie.

      I haven't tested myself but the problem seems to be that HTML::FORM::click will not automatically read the file from the hardisk and encode it in the HTTP::request object it generates, when submitting a "file" form element (this would require having a way of associating actual files to "file" form elements in HTML::Form. I think this would be a good improvement to this module).

        Maybe we are talking at cross-purposes. The scenario I am thinking of is that no script, whether client-browser-based (like JavaScript) or generated in a browser by a script should be able to force a value into the INPUT TYPE=FILE form element AND on its own issue a SUBMIT. I understood that to be the basis of the problem described above: test an existing browser form by using a script to execute it, including the definition of a value from the script for the VALUE element of the INPUT TYPE=FILE form element.

        The W3C HTML 4 specifications are quite explicit about this:
        "A user agent should not send any file that the user has not explicitly asked to be sent. Thus, HTML user agents are expected to confirm any default file names that might be suggested by the value attribute of the INPUT element. Hidden controls must not specify files."
        http://www.w3.org/TR/html401/appendix/notes.html#forms-security

        I also found an email exchange about the issue on the W3C site.

        > And about the security considerations, lets just hope that
        > Java/J/ECMAscript and the DOMs aren't allowing write access to
        > the INPUT TYPE=FILE VALUE attributes and submitting forms by
        > themselves these days.

        The response:
        Luckily Microsoft and Netscape have indeed noticed this, and both have made file input VALUE attributes read-only (you can write to them but it fails silently). This is contrary to the documentation at msdn.microsoft.com though. (Which says value and outerHTML are both read/write.)
        http://lists.w3.org/Archives/Public/www-html/2000Apr/0018.html

        Are you suggesting that a script be able to input the VALUE of the INPUT TYPE=FILE form element without user intervention in a browser file and force a SUBMIT, or do you have some ohter scenario in mind?

        Live in the present
        I wrote a module that makes HTML::Form work for file inputs. Can any one see any problems before I submit it to GAAS (The maintainer of this modual.).
        # put this in line #15 # I need to registar the new class. file=>"FileInput", # somewhere else package HTML::Form::FileInput; @HTML::Form::FileInput::ISA=qw(HTML::Form::Input); sub value { my $self=shift; if(@_) { my @temp=($_[0]); return $self::SUPER::value(\@temp); } else { return $self::SUPER::value(@_); } }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://148438]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (5)
As of 2024-04-19 10:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found