Genres and tags#165
Conversation
|
This pull request sets up GitHub code scanning for this repository. Once the scans have completed and the checks have passed, the analysis results for this pull request branch will appear on this overview. Once you merge this pull request, the 'Security' tab will show more code scanning analysis results (for example, for the default branch). Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results. For more information about GitHub code scanning, check out the documentation. |
| .ToListAsync(); | ||
|
|
||
| logger.LogInformation("Admin retrieved genre mappings: Count={Count}, Provider={Provider}, JitenGenre={JitenGenre}, Search={Search}", | ||
| mappings.Count, provider, jitenGenre, search); |
Check warning
Code scanning / CodeQL
Log entries created from user input Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 5 months ago
The best way to fix this problem is to sanitize the search user input before it is logged. Specifically, the sanitization should remove any line breaks (e.g., \n, \r) from the string and potentially trim whitespace. Since we're operating in a plaintext logging context, this avoids attack via control characters to forge new log entries.
To implement the fix:
- Within the
GetGenreMappingsmethod (Jiten.Api/Controllers/AdminController.Genres.cs), ensure that the value passed forsearchin the logger is sanitized. - Before logging, create a sanitized version of
searchby removing line breaks usingstring.Replacefor both\rand\n, or via a helper if desired. - Pass the sanitized value to
LogInformation(on line 39). - No changes are needed elsewhere in the code, and no dependencies are needed.
If there are other similar logs that use user input, same fix should be applied to each, but for this case, only line 39 needs change.
| @@ -35,8 +35,10 @@ | ||
| }) | ||
| .ToListAsync(); | ||
|
|
||
| // Sanitize 'search' to prevent log forging by removing newlines | ||
| var sanitizedSearch = search?.Replace("\r", "").Replace("\n", ""); | ||
| logger.LogInformation("Admin retrieved genre mappings: Count={Count}, Provider={Provider}, JitenGenre={JitenGenre}, Search={Search}", | ||
| mappings.Count, provider, jitenGenre, search); | ||
| mappings.Count, provider, jitenGenre, sanitizedSearch); | ||
|
|
||
| return Ok(mappings); | ||
| } |
| await dbContext.SaveChangesAsync(); | ||
|
|
||
| logger.LogInformation("Admin created genre mapping: MappingId={MappingId}, Provider={Provider}, ExternalName={ExternalName}, JitenGenre={JitenGenre}", | ||
| mapping.ExternalGenreMappingId, mapping.Provider, mapping.ExternalGenreName, mapping.JitenGenre); |
Check warning
Code scanning / CodeQL
Log entries created from user input Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 5 months ago
To fix this problem, sanitize user input before including it in log entries. For text log files, removing line breaks and other control characters from external user values prevents delimiter injection and log entry forging. The best, least disruptive fix is to ensure mapping.ExternalGenreName is sanitized before being logged:
- On line 68, update the log call to use a sanitized version of
mapping.ExternalGenreName. - This can be done inline by calling
.Replace("\r", "").Replace("\n", "")on the value, or by defining a helper method (if needed) to sanitize log input, but for a single case, inline works. - Only lines related to logging
mapping.ExternalGenreNameare affected; elsewhere, user input is not logged, or the log does not contain unsanitized user-content. - No external dependencies are required; use built-in string operations.
| @@ -65,7 +65,7 @@ | ||
| await dbContext.SaveChangesAsync(); | ||
|
|
||
| logger.LogInformation("Admin created genre mapping: MappingId={MappingId}, Provider={Provider}, ExternalName={ExternalName}, JitenGenre={JitenGenre}", | ||
| mapping.ExternalGenreMappingId, mapping.Provider, mapping.ExternalGenreName, mapping.JitenGenre); | ||
| mapping.ExternalGenreMappingId, mapping.Provider, mapping.ExternalGenreName.Replace("\r", "").Replace("\n", ""), mapping.JitenGenre); | ||
|
|
||
| return Ok(new { Message = "Genre mapping created successfully", Id = mapping.ExternalGenreMappingId }); | ||
| } |
| await dbContext.SaveChangesAsync(); | ||
|
|
||
| logger.LogInformation("Admin created tag mapping: MappingId={MappingId}, Provider={Provider}, ExternalName={ExternalName}, TagId={TagId}", | ||
| mapping.ExternalTagMappingId, mapping.Provider, mapping.ExternalTagName, mapping.TagId); |
Check warning
Code scanning / CodeQL
Log entries created from user input Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 5 months ago
To fix the problem, we should sanitize mapping.ExternalTagName before it is included in any log entry. This specifically means removing potentially dangerous characters, such as newline (\n, \r) and other control characters which can be used to inject new log entries. The best approach is to use string.Replace (or Regex) to remove these characters.
Only line 70 requires modification: before passing mapping.ExternalTagName to the logger, sanitize it by removing CR/LF. This can be done inline using
.Replace("\r", "").Replace("\n", "").
No new dependencies or external methods are necessary to implement this fix—use C# built-in string functions. No changes should be made to existing functionality except the sanitization for this log entry.
| @@ -67,7 +67,7 @@ | ||
| await dbContext.SaveChangesAsync(); | ||
|
|
||
| logger.LogInformation("Admin created tag mapping: MappingId={MappingId}, Provider={Provider}, ExternalName={ExternalName}, TagId={TagId}", | ||
| mapping.ExternalTagMappingId, mapping.Provider, mapping.ExternalTagName, mapping.TagId); | ||
| mapping.ExternalTagMappingId, mapping.Provider, mapping.ExternalTagName.Replace("\r", "").Replace("\n", ""), mapping.TagId); | ||
|
|
||
| return Ok(new { Message = "Tag mapping created successfully", Id = mapping.ExternalTagMappingId }); | ||
| } |
| dbContext.Tags.Add(tag); | ||
| await dbContext.SaveChangesAsync(); | ||
|
|
||
| logger.LogInformation("Admin created tag: TagId={TagId}, Name={Name}", tag.TagId, tag.Name); |
Check warning
Code scanning / CodeQL
Log entries created from user input Medium
|
|
||
| logger.LogInformation("Admin added new deck: Title={Title}, MediaType={MediaType}, SubdeckCount={SubdeckCount}", | ||
| model.OriginalTitle, model.MediaType, metadata.Children?.Count ?? 0); | ||
| model.OriginalTitle, model.MediaType, metadata.Children?.Count ?? 0); |
Check warning
Code scanning / CodeQL
Log entries created from user input Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 5 months ago
To fix the issue, we must sanitize user-provided input before logging it, ensuring it cannot affect or forge new log entries. For plain-text logs, the recommended approach is to remove (or encode) all newline sequences (\r, \n, and combinations), which could be achieved by replacing them in the string before logging:
- Update the call to
logger.LogInformationon line 170 to use a sanitized version ofmodel.OriginalTitlewhere all newline sequences (\r,\n) are removed. - Define the sanitized value immediately before the log statement for clarity.
- No new methods are strictly necessary, but you can use
string.Replaceor a regular expression to remove all line breaks. - If you're already using
System.Text.RegularExpressions, you can use it to remove all control characters if desired; otherwise, at minimum, replace\rand\nwith an empty string.
All changes are contained within the method in Jiten.Api/Controllers/AdminController.cs.
| @@ -166,8 +166,10 @@ | ||
|
|
||
| backgroundJobs.Enqueue<ParseJob>(job => job.Parse(metadata, model.MediaType, bool.Parse(config["StoreRawText"] ?? "false"))); | ||
|
|
||
| // Sanitize user-provided title to prevent log forging | ||
| var sanitizedTitle = model.OriginalTitle?.Replace("\r", "").Replace("\n", ""); | ||
| logger.LogInformation("Admin added new deck: Title={Title}, MediaType={MediaType}, SubdeckCount={SubdeckCount}", | ||
| model.OriginalTitle, model.MediaType, metadata.Children?.Count ?? 0); | ||
| sanitizedTitle, model.MediaType, metadata.Children?.Count ?? 0); | ||
|
|
||
| return Ok(new | ||
| { |
| { | ||
| logger.LogInformation("User reported deck issue: DeckId={DeckId}, IssueType={IssueType}", | ||
| request.DeckId, request.IssueType); | ||
| request.DeckId, request.IssueType); |
Check warning
Code scanning / CodeQL
Log entries created from user input Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 5 months ago
To fix this issue, sanitize the user input before logging it. Specifically, for log entries that might be written as plain text, remove or replace newline characters in user-provided data before passing them to the logger. In MediaDeckController.cs, this means sanitizing request.IssueType before passing it to the logger (lines 1523 and 1528). The fix involves introducing a utility method that strips or replaces newlines from user input, and using this method on request.IssueType wherever it is logged. The best placement for the helper is inside the existing method as a private helper, similar to SanitizeForDiscord.
Edits:
- Add a helper function (e.g.,
SanitizeForLog(string s)) inside theReportIssuemethod to replace or strip newlines. - Sanitize
request.IssueType(and, optionally, any other potentially controllable strings, but the alert specifically citesIssueType) before passing to the logger on lines 1523 and 1528. - No change to Discord-side sanitization.
| @@ -1519,15 +1519,26 @@ | ||
|
|
||
| if (result.IsSuccessStatusCode) | ||
| { | ||
| // Sanitize IssueType for logging to prevent log forging/newline injection | ||
| var safeLogIssueType = SanitizeForLog(request.IssueType); | ||
| logger.LogInformation("User reported deck issue: DeckId={DeckId}, IssueType={IssueType}", | ||
| request.DeckId, request.IssueType); | ||
| request.DeckId, safeLogIssueType); | ||
| return Ok(); | ||
| } | ||
|
|
||
| var safeLogIssueTypeFail = SanitizeForLog(request.IssueType); | ||
| logger.LogWarning("Failed to send deck issue report: DeckId={DeckId}, IssueType={IssueType}", | ||
| request.DeckId, request.IssueType); | ||
| request.DeckId, safeLogIssueTypeFail); | ||
| return BadRequest("Failed to send report"); | ||
|
|
||
| // Removes newlines, carriage returns, and trims the value for safe logging. | ||
| string SanitizeForLog(string input) | ||
| { | ||
| return string.IsNullOrEmpty(input) | ||
| ? string.Empty | ||
| : input.Replace("\r", "").Replace("\n", "").Trim(); | ||
| } | ||
|
|
||
| string SanitizeForDiscord(string input) | ||
| { | ||
| if (string.IsNullOrEmpty(input)) |
|
|
||
| logger.LogWarning("Failed to send deck issue report: DeckId={DeckId}, IssueType={IssueType}", | ||
| request.DeckId, request.IssueType); | ||
| request.DeckId, request.IssueType); |
Check warning
Code scanning / CodeQL
Log entries created from user input Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 5 months ago
To fix this issue, we need to ensure that user input (request.IssueType) does not introduce new lines or other control characters into the log entry. The best fix is to sanitize request.IssueType before logging: specifically, replace or remove any newline (\n, \r) or control characters from the input before passing it to the logger. This can be done by replacing such characters with an empty string using String.Replace or a regular expression. The fix should be minimally invasive: sanitize just before logging in the logger.LogWarning call on line 1528 and in the corresponding LogInformation call on line 1523 for consistency. No new dependencies are needed, as the required functionality is in the standard library.
| @@ -1519,13 +1519,15 @@ | ||
|
|
||
| if (result.IsSuccessStatusCode) | ||
| { | ||
| var sanitizedIssueType = request.IssueType.Replace("\r", "").Replace("\n", ""); | ||
| logger.LogInformation("User reported deck issue: DeckId={DeckId}, IssueType={IssueType}", | ||
| request.DeckId, request.IssueType); | ||
| request.DeckId, sanitizedIssueType); | ||
| return Ok(); | ||
| } | ||
|
|
||
| var sanitizedIssueType = request.IssueType.Replace("\r", "").Replace("\n", ""); | ||
| logger.LogWarning("Failed to send deck issue report: DeckId={DeckId}, IssueType={IssueType}", | ||
| request.DeckId, request.IssueType); | ||
| request.DeckId, sanitizedIssueType); | ||
| return BadRequest("Failed to send report"); | ||
|
|
||
| string SanitizeForDiscord(string input) |
No description provided.