Welcome Guest, Not a member yet? Register   Sign In
Large file upload results in 403 error
#1

I am troubleshooting my file upload with no success. I have a form that is submitted via AJAX and if a user tries to upload a file that is larger than the upload_max_filesize setting codeigniter will throw a 403 error. Specifically:

PHP Code:
CodeIgniter\Security\Exceptions\SecurityExceptionThe action you requested is not allowed

Currently my max filesize is set to 8M and my file upload validation is at 4M. I am only handling small PDF files that should be no larger than 500KB. If the file supplied is smaller than the upload_max filesize (8M) setting but above what I have specified (4M) my code will handle the large file like it should and show the user an error message but anything above 8M results in the generic Codeigniter 403 error above. Since the exception is thrown before my handler even executes there is so far nothing I have found that I can do.

Realistically, there is no reason for someone to attempt to upload a 8M (or larger) file but I would like to be able to handle the error properly and show a "File is too large" message instead of showing a generic 403 error to the user. Is there anything I am missing or is this something that needs to be fixed in the Framework?
Reply
#2

This exception and the HTTP response code are not related to the file upload.
This error appears only in one case. When CSRF protection was triggered.

Your ajax request must contain either X-CSRF-TOKEN header (default name) with hash value (look csrf_hash() function)
Or a field with the token name and hash value ((look csrf_token() csrf_hash() functions).

Do not forget that after each POST request you need to send an updated csrf hash.
Reply
#3

(02-23-2021, 11:33 PM)iRedds Wrote: This exception and the HTTP response code are not related to the file upload.
This error appears only in one case. When CSRF protection was triggered.

Your ajax request must contain either X-CSRF-TOKEN header (default name) with hash value (look csrf_hash() function)
Or a field with the token name and hash value ((look csrf_token() csrf_hash() functions).

Do not forget that after each POST request you need to send an updated csrf hash.

I am sending the csrf token with all of my post requests and responses. When I try the exact same function only with a smaller file, everything works as intended. I'm thinking that maybe there is somewhere in the framework that errors on the filesize if it is larger than the server allows and then discards the post information which in turn clears the csrf token. This is just an idea but if anyone has suggestions I am open to them.

Thanks.
- Kyle
Reply
#4

Ok, so I found out what is causing the problem but I still don't really know how to fix it. 
Quote:post_max_size int

Sets max size of post data allowed. This setting also affects file upload. To upload large files, this value must be larger than upload_max_filesize. Generally speaking, memory_limit should be larger than post_max_size. When an int is used, the value is measured in bytes. Shorthand notation, as described in this FAQ, may also be used. If the size of post data is greater than post_max_size, the $_POST and $_FILES superglobals are empty. This can be tracked in various ways, e.g. by passing the $_GET variable to the script processing the data, i.e. <form action="edit.php?processed=1">, and then checking if $_GET['processed'] is set.

post-max-size - PHP Manual

This explains why I'm getting the CSRF error as PHP is returning an empty $_POST value without the CSRF Token. As a temporary fix, I have added a simple file size check in my AJAX code that prevents the form from submitting if the file is too large. So far the only solutions I have seen for this are client side, but I would really like to find a way to fix this server side. 

Any input is appreciated.

 - Kyle
Reply
#5

(02-24-2021, 09:31 AM)kyle Wrote: Ok, so I found out what is causing the problem but I still don't really know how to fix it. 
Quote:post_max_size int

Sets max size of post data allowed. This setting also affects file upload. To upload large files, this value must be larger than upload_max_filesize. Generally speaking, memory_limit should be larger than post_max_size. When an int is used, the value is measured in bytes. Shorthand notation, as described in this FAQ, may also be used. If the size of post data is greater than post_max_size, the $_POST and $_FILES superglobals are empty. This can be tracked in various ways, e.g. by passing the $_GET variable to the script processing the data, i.e. <form action="edit.php?processed=1">, and then checking if $_GET['processed'] is set.

post-max-size - PHP Manual

This explains why I'm getting the CSRF error as PHP is returning an empty $_POST value without the CSRF Token. As a temporary fix, I have added a simple file size check in my AJAX code that prevents the form from submitting if the file is too large. So far the only solutions I have seen for this are client side, but I would really like to find a way to fix this server side. 

Any input is appreciated.

 - Kyle

You can set this in php.ini or in .htaccess (If that is what you mean by "server side")
Simpler is always better
Reply
#6

(02-24-2021, 12:51 PM)donpwinston Wrote: You can set this in php.ini or in .htaccess (If that is what you mean by "server side")

Thanks, but I tried this in testing. The server will still attempt to upload the large file because it can't see the size until an upload is attempted. When it does it will exhibit the above behavior and return with empty $_POST and $_FILE superglobals which are causing the CSRF error.

By "Server Side", I would like to find a solution for ether codeigniter or my controller code that either won't allow a form to be submitted or to catch the empty superglobals and throw a specific error instead of "This Action is Not Allowed".

I don't really want to set my upload_max_filesize and post_max_size to something absurdly large just to stop unwanted behavior for uploading 500K files.
Reply
#7

Use a header to send the CSRF hash
Reply




Theme © iAndrew 2016 - Forum software by © MyBB