SuaveIO / suave

Suave is a simple web development F# library providing a lightweight web server and a set of combinators to manipulate route flow and task composition.
https://suave.io
Other
1.32k stars 198 forks source link

Multipart form-data file upload security question #775

Closed djonphillips closed 1 year ago

djonphillips commented 1 year ago

I have a question about multipart form-data file upload. It seems that files are saved to disk as .tmp files and then stored in ctx.request.files which is of type HttpUpload list. This occurs before we have chance to interact with the request. Does this present a security issue because files can be saved to the server temp folder before any authorisation can be done on the request?

Additional comments: a) Would it be possible to configure the save location for these files so that temporary files can be saved to a location other than the temp folder? b) The defaultConfig has a maxContentLength field which is of type integer. This limits multipart form-data uploads to just under 2Gb. Would it be possible to use a long data type instead so that larger requests can be made? In ASP.NET there is a RequestFormLimits attribute which has a property of MultipartBodyLengthLimit which is of type long.

Thank you for looking into this.

ademar commented 1 year ago

You are correct. An early version of suave allowed to have control over this but users complained it made the api cumbersome so it was abandoned in favour of the simpler model.

https://github.com/SuaveIO/suave/issues/198 https://github.com/SuaveIO/suave/issues/186

I think it would be nice to have a solution for this.

The other changes you mention also would be welcome PRs :).

phillidgithub commented 1 year ago

Thank you for your reply. I have forked the Suave repository, followed by a dotnet paket restore and dotnet build. In Suave.Tests the command dotnet run --framework=net7.0 runs about 9 tests and then the run fails with the message: TCP server failed System.Net.Sockets.SocketException (10048): Only one usage of each socket address (protocol/network address/port) is normally permitted. Please could I have some guidance on how to run unit tests on this project using my local machine?

ademar commented 1 year ago

How to Build

To execute the build script, invoke following command on the Linux or MacOs console:

./build.sh

Or in the Microsoft Windows MSDOS console:

build

phillidgithub commented 1 year ago

Thank you. I got this result on Windows: 230 tests run in 00:00:03.9100283 for miscellaneous – 134 passed, 0 ignored, 1 failed, 95 errored.

ademar commented 1 year ago

The tests are run once with the default tcp engine (pure .net), and then with the libuv tcp engine. You need to drop libuv.dll somewhere in the path for these to work (usually on C:\Windows\system32).

Other solution is to disable them by tweaking the code of src/Suave.Tests/Program.fss, just remove from line 34 till the end and put a zero at the end.

Note that very soon I'll be pushing some major changes (https://github.com/SuaveIO/suave/pull/772); one of them is dropping the libuv engine.

phillidgithub commented 1 year ago

Great. Using the second solution: EXPECTO! 230 tests run in 00:00:07.0336295 for miscellaneous – 230 passed, 0 ignored, 0 failed, 0 errored. Success!