0
votes

I have a form that is type => file, with an file upload control.

When I submit this form without a file, it submits as expected.

However, When I submit the form with a file attached, I get a CSRF Token Mismatch.

Any ideas why this might be happening?


EDIT: I noticed that the csrf token is the same when i refresh the page, maybe this is part of the problem?


EDIT-2: When I disable the CSRF protection, the $this->request->getData() array is empty


EDIT-3: I have hooked XDebug up and these are the results...

Xdebug File Upload CSRF Token Mismatch

Apparently $post and $header are null/empty on line 194, resulting in token mismatch

Xdebug File Upload CSRF Token Mismatch 2

Here is my Form

    <div class="col-lg-offset-1 col-lg-10">
        <?php if(isset($ledger->id)) { ?>
        <?= $this->Form->create($ledger, ['url' => '/shortcut/ledger_save/' . $ledger->id, 'type' => 'file', 'class' => 'form-horizontal']); ?>
        <?php } else { ?>
        <?= $this->Form->create($ledger, ['url' => '/shortcut/ledger_new', 'type' => 'file', 'class' => 'form-horizontal']); ?>
        <?php } ?>
        <?php $this->Form->setTemplates(['inputContainer' => '{{content}}', 'submitContainer' => '{{content}}']); ?>
        <!-- Default box -->
            <div class="box">
                <div class="box-header with-border">
                    <?php if(isset($ledger->id)) { ?>
                    <h3 class="box-title">Edit <?= $ledger->ledger_title ?> Form</h3>
                    <?php } else { ?>
                    <h3 class="box-title">Create Ledger Form</h3>
                    <?php } ?>
                </div>
                <div class="box-body">
                    <div class="form-group">
                        <center>
                            <?php if($ledger->disabled == 'n') { ?>
                                <?= $this->Form->control('disabled', ['type' => 'checkbox', 'label' => false, 'class' => 'minimal']) ?>&nbsp;&nbsp;Check to disable (hide) ledger.
                            <?php } else { ?>
                                <?= $this->Form->control('disabled', ['type' => 'checkbox', 'label' => false, 'class' => 'minimal', 'checked']) ?>&nbsp;&nbsp;Uncheck to enable (show) ledger.
                            <?php } ?>
                        </center>
                    </div>
                    <div class="form-group">
                        <label for="inputEmail3" class="col-sm-2 control-label">Ledger Title</label>

                        <div class="col-sm-10">
                            <?= $this->Form->control('ledger_title', ['label' => false, 'class' => 'form-control', 'placeholder' => 'Ledger Title', 'autofocus']) ?>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="inputPassword3" class="col-sm-2 control-label">Total Plates</label>

                        <div class="col-sm-10">
                            <?= $this->Form->control('total_plates', ['label' => false, 'class' => 'form-control', 'placeholder' => 'Total Plates (Total Images)']) ?>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="inputPassword3" class="col-sm-2 control-label">Total Pages</label>

                        <div class="col-sm-10">
                            <?= $this->Form->control('total_pages', ['label' => false, 'class' => 'form-control', 'placeholder' => 'Total Pages (Total Physical Pages)']) ?>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="inputPassword3" class="col-sm-2 control-label">Check Tribes</label>
                    </div>
                    <div class="form-group">
                        <?php $x = 0; ?>
                        <?php foreach($tribes as $tribe) { ?>
                            <?php if($x == 0) { echo '<div class="form-group"><div class="col-sm-3">&nbsp;</div>'; } ?>
                                <div class="col-sm-4">
                                    <?php if(in_array($tribe->id, $ledger_tribes)) { ?>
                                    <?= $this->Form->control('tribe_id[]', ['type' => 'checkbox', 'label' => false, 'class' => 'minimal', 'value' => $tribe->id, 'checked']) ?>&nbsp;&nbsp;<?= $tribe->name ?>
                                    <?php } else { ?>
                                    <?= $this->Form->control('tribe_id[]', ['type' => 'checkbox', 'label' => false, 'class' => 'minimal', 'value' => $tribe->id]) ?>&nbsp;&nbsp;<?= $tribe->name ?>
                                    <?php } ?>
                                </div>
                            <?php $x = $x + 1; ?>
                            <?php if($x == 2) { echo '</div>'; $x = 0; } ?>
                        <?php } ?>
                        <?php if($x == 1) { echo '</div>'; $x = 0; } ?>
                    </div>
                    <div class="form-group">
                        <label for="inputPassword3" class="col-sm-2 control-label">Custodian</label>

                        <div class="col-sm-10">
                            <?= $this->Form->control('custodian', ['type' => 'textarea', 'label' => false, 'class' => 'form-control', 'style' => 'width: 100%', 'placeholder' => 'Custodian']) ?>
                            <?php if(!isset($ledger->overwrite_custodian) || $ledger->overwrite_custodian == 'n') { ?>
                                <?= $this->Form->control('overwrite_custodian_checkbox', ['type' => 'checkbox', 'label' => false, 'class' => 'minimal', 'value' => 'y']); ?> Overwrite Plate Custodian
                            <?php } else { ?>
                                <?= $this->Form->control('overwrite_custodian_checkbox', ['type' => 'checkbox', 'label' => false, 'class' => 'minimal', 'value' => 'y', 'checked']); ?> Overwrite Plate Custodian
                            <?php } ?>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="inputPassword3" class="col-sm-2 control-label">Image Source</label>

                        <div class="col-sm-10">
                            <?= $this->Form->control('image_source', ['label' => false, 'type' => 'text', 'class' => 'form-control', 'placeholder' => 'Image Source']) ?>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="inputPassword3" class="col-sm-2 control-label">Provenance</label>

                        <div class="col-sm-10">
                            <?= $this->Form->control('provenance', ['type' => 'textarea', 'label' => false, 'class' => 'form-control', 'style' => 'width: 100%', 'placeholder' => 'Provenance']) ?>
                        </div>
                    </div>
                    <div class="form-group">
                        <label class="col-sm-2 control-label">Global Keywords</label>
                        <div class="col-sm-10">
                            <?php $keywordOptions = []; ?>
                            <?php $keywordValues = []; ?>
                            <?php $foundKeywords = []; ?>
                            <?php foreach($keywords as $keyword) { ?>
                            <?php       if(trim($keyword->keyword) == '') { continue; } ?>
                            <?php       $keywordOptions[$keyword->keyword] = $keyword->keyword; ?>
                            <?php       if(in_array($keyword->keyword, $ledger_keywords)) { $keywordValues[$keyword->id] = $keyword->keyword; $foundKeywords[] = $keyword->keyword; } ?>
                            <?php } ?>
                            <?= $this->Form->select('keyword', $keywordOptions, ['class' => 'form-control select2', 'value' => $keywordValues, 'multiple' => true]); ?>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="inputPassword3" class="col-sm-2 control-label">Additional Keywords</label>

                        <div class="col-sm-10">
                            <?php $additionalKeywords = ''; ?>
                            <?php foreach($ledger_keywords as $keyword) { ?>
                            <?php       if(in_array($keyword, $foundKeywords) == false) { ?>
                            <?php           $additionalKeywords = $additionalKeywords . $keyword . ', '; ?>
                            <?php       } ?>
                            <?php } ?>
                            <?php $additionalKeywords = substr($additionalKeywords, 0, strlen($additionalKeywords) - 2); ?>

                            <?= $this->Form->control('additional_keywords', ['type' => 'textarea', 'value' => $additionalKeywords, 'label' => false, 'class' => 'form-control', 'style' => 'width: 100%', 'placeholder' => 'Additional Keywords']) ?>

                            <p class="help-block">Seperated by commas.</p>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="inputPassword3" class="col-sm-2 control-label">Arist</label>

                        <div class="col-sm-10">
                            <?= $this->Form->control('artist', ['label' => false, 'class' => 'form-control', 'placeholder' => 'Artist']) ?>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="inputPassword3" class="col-sm-2 control-label">Media</label>

                        <div class="col-sm-10">
                            <?= $this->Form->control('media', ['label' => false, 'class' => 'form-control', 'placeholder' => 'Media']) ?>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="inputPassword3" class="col-sm-2 control-label">Dimensions</label>

                        <div class="col-sm-10">
                            <?= $this->Form->control('dimensions', ['label' => false, 'class' => 'form-control', 'placeholder' => 'Dimensions']) ?>
                        </div>
                    </div>
                    <?php if(!isset($ledger->id)) { ?>
                        <div class="form-group">
                            <label for="exampleInputFile" class="col-sm-2 control-label">Batch Upload</label>

                            <div class="col-sm-10">
                                <?= $this->Form->file('uploadfile', array('label' => false, 'type' => 'file')) ?>

                                <p class="help-block">Select the ledger images archive here.</p>
                            </div>
                        </div>
                    <?php } ?>
                </div>
                <!-- /.box-body -->
                <div class="box-footer">
                    <?= $this->Form->button('Submit', ['type' => 'submit', 'class' => 'btn btn-success btn-pill pull-right']) ?>
                </div>
            <!-- /.box-footer-->
            </div>
        <?= $this->Form->end() ?>
    <!-- /.box -->
    </div>

Here is the Form html output

<!-- Main content -->
<section class="content">

    <div class="col-lg-offset-1 col-lg-10">
                    <form enctype="multipart/form-data" method="post" accept-charset="utf-8" class="form-horizontal" action="/shortcut/ledger_new"><div style="display:none;"><input type="hidden" name="_method" value="POST"/><input type="hidden" name="_csrfToken" autocomplete="off" value="06d11527d1e431fd1d1b73a6b96e9af1eec6a1fd6c2ede60cfdb06afdcff5b3c02216614f61ba68bf1bf0beeba8b5f7500319ec94ec278141ee4f480b4a4505f"/></div>   


                ..... SNIPPED TO MAKE MAX CHARS ALLOWED ....


                <div class="box-footer">
                    <button type="submit" class="btn btn-success btn-pill pull-right">Submit</button>                    </div>
            <!-- /.box-footer-->
            </div>
                    </form>        <!-- /.box -->
    </div>
</section>

Here is the inspection headers

Chrome Inspection Headers

Here is the inspection headers without the file upload populated, as you can see, in the above picture there is no Form Data, and in the below picture there is.

Chrome Inspection Headers 2

1
debug new/patchEntitySalines
Are you sending csrf token..?Send it with ajax request.Confused
example: $products = $this->Products->newEntity(); debug($products); Salines
The newEntity/patchEntity code never fires as the CSRF MiddleWare is where the CSRF Token Mismatch occurs.Jeffrey L. Roberts
@ndm any ideas? Is there any other information that would help debug this scenario?Jeffrey L. Roberts

1 Answers

0
votes

The post_max_size inside the /etc/php.ini file was set to 8M, it has to be set larger than the uploaded file size.

So, what I did was, I set

 post_max_size = 80M

and I set

 upload_max_filesize = 60M

and the form submitted as expected after that