• Yes I have searched and yes I have found lots of answers, but I am not sure I have found the correct answer.

    I have a form with an image upload. I am using wp_handler_upload() to upload the image to my uploads file. The code works fine as long as ‘test_form’ => false is in the $overrides array. So here is my question everything I have found online says to set this this way, but in the codex it says

    $overrides
    (array) (optional) An associative array to override default behaviors. When called while handling a form, ‘action’ must be set to match the ‘action’ parameter in the form or the upload will be rejected. When there is no form being handled, use ‘test_form’ => false to bypass this test, and set ‘action’ to something other than the default (“wp_handle_upload”) to bypass security checks requiring the file in question to be a user-uploaded file.

    Default: false

    The source file says

    // All tests are on by default. Most can be turned off by `$overrides[{test_name}] = false;
    $test_form = isset( $overrides[‘test_form’] ) ? $overrides[‘test_form’] : true;
    $test_size = isset( $overrides[‘test_size’] ) ? $overrides[‘test_size’] : true;`

    // If you override this, you must provide $ext and $type!!
    ` $test_type = isset( $overrides[‘test_type’] ) ? $overrides[‘test_type’] : true;
    $mimes = isset( $overrides[‘mimes’] ) ? $overrides[‘mimes’] : false;`

    // A correct form post will pass this test.
    ` if ( $test_form && ( ! isset( $_POST[‘action’] ) || ( $_POST[‘action’] != $action ) ) ) {
    return call_user_func( $upload_error_handler, $file, __( ‘Invalid form submission.’ ) );
    }`

    So my questions are first how do I set action to my forms action parameter? I tried 'action'=>'' which didn’t work.

    Second is setting 'test_form' => false just an easy fix that is bypassing a security measure? or is it really supposed to be set that way? The only example in codex uses it and every example I have found online uses it, but it says a form should be able to pass the test. I am so confused.

    Here is my current code:

    if ( ! function_exists( 'wp_handle_upload' ) ) {
    				require_once( ABSPATH . 'wp-admin/includes/file.php' );
    			}
    
    			$uploadedfile = $_FILES['fileToUpload'];
    
    			$upload_overrides = array( 'test_form' => false, 'mimes' => array('jpg' => 'image/jpeg', 'png' => 'image/png') );
    
    			$movefile = wp_handle_upload( $uploadedfile, $upload_overrides );
    
    			if ( $movefile && !isset( $movefile['error'] ) ) {
    				echo "File is valid, and was successfully uploaded.\n";
    				//var_dump( $movefile);
    				$image=$movefile[url];
    
    			} else {
    				/**
    				 * Error generated by _wp_handle_upload()
    				 * @see _wp_handle_upload() in wp-admin/includes/file.php
    				 */
    				echo $movefile['error'];
    			}

    and the form

    <form method="post" action="<?php echo htmlspecialchars('');?>" enctype="multipart/form-data">
       <input type="file" name="fileToUpload" id="fileToUpload"><br>
       <input type="submit" name="submit" value="Save">
    </form>

Viewing 5 replies - 1 through 5 (of 5 total)
  • Re: how to set the handler’s action to the form’s action, in the form pageelf I would set a variable like

    $myaction = htmlspecialchars( $_SERVER['PHP_SELF'] );

    and then pass in

    $upload_overrides = array( 'action' => $myaction, 'test_form' => false, 'mimes' => array('jpg' => 'image/jpeg', 'png' => 'image/png') );

    Re: Does setting test to false just override security, the short answer is yes.

    Moderator bcworkz

    (@bcworkz)

    I don’t know why everyone overrides these tests, it sounds like lazy coding to me. The tests do offer some security, though they are far from comprehensive. Considering that file uploads is one of the biggest ways to compromise a site, one should take advantage of any security measures available, even if rather weak.

    Additionally, running the tests provides some minimal error handling so that if there is a problem with the upload, there is some indication of what the problem is instead of failing for no apparent reason.

    Providing an action parameter on your form is just a matter of adding a hidden input field named “action” with its value set to an arbitrary string (but not empty). The $overrides['action'] in your code is then set to the same string. This helps to ensure that your form is the only way to upload a file through the code page. Hackers cannot successfully POST file uploads without first going through your form. This significantly slows down typical brute force attacks.

    If you use ‘wp_handle_upload’ as the action parameter, you must ensure the $file array is properly formed. Using it is sort of like a signature attesting that “Hey, I know what I’m doing and have provided a properly constructed $file array, gimme your most stringent tests.”

    Thread Starter Mariah_A_C

    (@mariah_a_c)

    Doug,
    Thank you for your input. The code works with the action as long as I leave the test as false, but fails if I remove it.

    BCWorkz,
    Your solution of the hidden input field fixed it! It is passing the test. I am however not sure I understand your second option of using ‘wp_handler_upload’ as the action parameter. I would like to have the highest level of security, even though I clearly can’t say “Hey, I know what I’m doing.”

    Thank you both for your input.

    Moderator bcworkz

    (@bcworkz)

    ??
    It’s not necessarily that big of an increase in security. If you set the hidden ‘action’ field and the $overrides['action'] argument both to ‘wp_handle_upload’, you are signaling that the $files parameter has been properly & completely formed and wp_handle_upload() need not automatically fill in certain fields. It merely checks that the fields exist instead.

    Thus your other code would need to fill in the fields that wp_handle_upload() could have otherwise done for you. Your code could perform additional validation and sanitizing unique to your situation, increasing security. If wp_handle_upload() were to re-populate these fields, it’d be thwarting your added efforts. If you’re just going to auto-populate the same way wp_handle_upload() does, it serves little purpose.

    Thread Starter Mariah_A_C

    (@mariah_a_c)

    Thanks for the explanation.

Viewing 5 replies - 1 through 5 (of 5 total)
  • The topic ‘wp_handle_upload () setting $overrides correctly’ is closed to new replies.