Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Safe I/O] Only allow creating files with whitelisted filetypes #682

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

GeckoEidechse
Copy link
Member

@GeckoEidechse GeckoEidechse commented Mar 22, 2024

Only allow creating files with whitelisted filetypes to prevent writing .bat or .vb files with Safe I/O that could then be called using some exploit (e.g. #674), we should prevent writing file types that by default are interpreted as executable.

Whitelisting was chosen over blacklisting as we can always extend the list and don't have to worry about potentially forgetting to blacklist a certain filetype.

Of course this doesn't prevent writing a bash script to a .txt file and then somehow getting Windows to interpret it as a batch file.

Reading files is not restricted to filetypes as we are primarily concerned with creating files here.

Supersedes #675

Completely untested atm.

Testing instructions:

(to be extended)
Basically write a save I/O file with and without a disallowed file extension and check that it handles it respectively.

@GeckoEidechse
Copy link
Member Author

I wrote this on a system that is unable to compile Northstar and without having written C++ for like more than half a year, would be surprised if it even compiles xD

@Alystrasz
Copy link
Contributor

@ASpoonPlaysGames is also working on that (#675), are you aware of that? 😄

@ASpoonPlaysGames
Copy link
Contributor

@ASpoonPlaysGames is also working on that (#675), are you aware of that? 😄

ngl that PR is kinda dead, i've just not had the time to do much lately. Honestly this PR might be preferable to mine.

}

// TODO: move into list of global consts?
std::set<std::string> whitelist = {".txt", ".json"};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason for this being a set instead of like an vector or array or is it just an arbitrary choice?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly arbitrary choice

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then it should probably be a vector.

Copy link
Contributor

@barnabwhy barnabwhy Aug 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can probably also be made static const
compiler might already optimise it to static idrk but just in case it isn't doing that, this'll prevent unnecessary allocs

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@barnabwhy done via 314b86a

@catornot going back to this, wouldn't a set make more sense as soon as the list of extensions gets quite long? Like rn it's only 2 cause that's the two most important plaintext filetypes I could think of but the idea is that the list would get extended quite a bit later down the line.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how many filetypes will you need?

@Alystrasz
Copy link
Contributor

@GeckoEidechse you created the branch on the main repo so we cannot update it 😢

std::string extension = file.extension().string();
if (whitelist.find(extension) == whitelist.end())
{
spdlog::error("SAVE FAILED!");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should maybe make it more clear that it's an issue with a mod so users don't freak out.

// Check if has extension and return early if not
if (!file.has_extension())
{
spdlog::error("SAVE FAILED!");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See other comment

@barnabwhy
Copy link
Contributor

This isn't directly related to the PR but I noticed while reviewing that the code immediately below directly locks and unlocks the mutex, but ideally it should be using std::lock_guard at the start of the try catch block so that we don't need to explcitly unlock on every scope exit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: No status
Development

Successfully merging this pull request may close these issues.

5 participants