fix(security): add file content validation for map transfer#1819
fix(security): add file content validation for map transfer#1819bobtista wants to merge 26 commits intoTheSuperHackers:mainfrom
Conversation
630dbcb to
218f4b9
Compare
218f4b9 to
97d61d7
Compare
|
Were all comments from SkyAero worked on? |
|
| Filename | Overview |
|---|---|
| Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp | Moved transfer file validation to ConnectionManager with full INI null-byte scanning and proper TGA footer validation using TGA2_SIGNATURE macro |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Receive file transfer] --> B[Extract file extension]
B --> C{Extension exists?}
C -->|No| D[Reject: No extension]
C -->|Yes| E[Get file type from lookup]
E --> F{Valid file type?}
F -->|No| G[Reject: Unknown extension]
F -->|Yes| H{Size <= limit?}
H -->|No| I[Reject: Size exceeded]
H -->|Yes| J{File type?}
J -->|.map| K[Validate CkMp magic bytes]
J -->|.ini| L[Scan entire file for null bytes]
J -->|.tga| M[Validate TGA2 footer signature]
J -->|.str/.txt/.wak| N[Size check only]
K --> O{Valid?}
L --> O
M --> O
N --> O
O -->|Yes| P[Write file to disk]
O -->|No| Q[Reject: Content validation failed]
P --> R[Transfer complete]
Q --> S[Clean up buffer and abort]
D --> S
G --> S
I --> S
Last reviewed commit: bf1adbd
Skyaero42
left a comment
There was a problem hiding this comment.
This looks good to me.
Nice security addition to the game.
PR has changed quite a bit. Haven't re-reviewed yet.
…ConnectionManager
| #include "GameClient/InGameUI.h" | ||
| #include "TARGA.h" | ||
|
|
||
| static Bool hasValidTransferFileExtension(const AsciiString& filePath) |
There was a problem hiding this comment.
When this is merged, can you make a follow refactor and merge this logic with the new stuff added below? It looks like this function can be greatly simplified.
See getTransferFileType
| { ".str", 512 * 1024 }, | ||
| { ".txt", 512 * 1024 }, | ||
| { ".tga", 2 * 1024 * 1024 }, | ||
| { ".wak", 512 * 1024 }, |
There was a problem hiding this comment.
I was about to merge this change, but looking over these sizes I do wonder how they came to be. TGA size looks pretty big, INI maybe too small for a massive Mod Map?
And why is TXT there? Does the game actually transfer it?
Also, I think we need to make these values configurable in an INI file, so that Mods can customize file transfer limits.
There was a problem hiding this comment.
According to Kabuse, a 2 MB map is already insane, so 5 MB is on the safe side.
.str, .wak and .txt are always small, so 512 kb is more then enough.
Can't find the data on .tga and ini anymore. I think tga is fine, ini may need to go to 1 MB.
I would be against a configurable ini. This would defeat the purpose of the security measure as a malicious host could still transfer large files.
There was a problem hiding this comment.
HLH - Black Dawn has a map.ini file slightly larger than 1024 KB fwiw.
There was a problem hiding this comment.
I would be against a configurable ini. This would defeat the purpose of the security measure as a malicious host could still transfer large files.
Can you elaborate on this security threat? How would that work?
There was a problem hiding this comment.
I would be against a configurable ini. This would defeat the purpose of the security measure as a malicious host could still transfer large files.
Can you elaborate on this security threat? How would that work?
Uncapped file size in general poses a security thread (denial of service), which could lead to overfilled memory and/or disk - causing game or computer crash.
The 2 minute timeout in the transfer window partially that infinite dos isn't possible - which alleviates some of the thread.
File size of transfers should be capped in the application for proper security. Allowing users to configure that as an option defeats the purpose of such a cap.
Make it 5 or 10 MB if you want to play it safe, but I think it is better to understand what a realistic filesize is for each type. I've got 500 maps installed on my PC, the largest files are .tga and .map, each still well under 1 MB, so we are looking at the extreme maps.
Based on @Caball009 feedback, ini may have to go to 2 MB, but the rest should be good.
There was a problem hiding this comment.
Allowing users to configure that as an option defeats the purpose of such a cap.
It still is unclear how that would become an issue. INI file settings are local. If the local user does not change them, then there is no threat level for his local machine.
The INI configurability allows Mod Creators to customize the limits for when they ship larger content than the base game does.
There was a problem hiding this comment.
I see your point. Agreed, making this configurable in the ini options gives mod creators the freedom they need.
There was a problem hiding this comment.
No legitimate mod maker is going to instruct a player in the match chat to go edit their .ini files; if we're priming users to make local security changes based on lobby chat, we have much bigger problems than file size limits, the threat is social not technical.
We have GenHub for larger mods and we shouldn't increase the configuration surface here. Adding a file limit user option implies we also have to add a configurable timeout limit. I think bobtista original approach is the correct one.
There was a problem hiding this comment.
No legitimate mod maker is going to instruct a player in the match chat to go edit their .ini files
That is not the intent. The intent is that the Mod Creator can customize these limits that previously did not exist, if he knows that his Mod has different requirements than the retail game content.
Implements file content validation during map transfer operations to prevent malformed or malicious files from being processed.
Implementation
Adds
FileSystem::hasValidTransferFileContent()which validates transferred file content in memory before writing to disk. If validation fails, the file is never written and the transfer is silently aborted.Validation methods:
.mapfiles - Validates magic bytesCkMp(Chunky Map header).inifiles - Checks for null bytes to ensure text format (rejects binary).tgafiles - Validates minimum size (18 bytes for valid TGA header).str,.txt,.wak- Size validation onlyMaximum file sizes:
.map: 5 MB.ini: 512 KB.str/.txt: 512 KB.tga: 2 MB.wak: 512 KB