Add missing string replacement sanitizers to log-injection and string-break#11910
Conversation
6282385 to
9d2d4f4
Compare
|
Performance evaluation showed no changes |
| class StringsNewReplacerCall extends DataFlow::CallNode { | ||
| StringsNewReplacerCall() { this.getTarget().hasQualifiedName("strings", "NewReplacer") } | ||
|
|
||
| /** | ||
| * Gets an argument to this call corresponding to a string that will be | ||
| * replaced. | ||
| */ | ||
| DataFlow::Node getAReplacedArgument() { | ||
| exists(int n | n % 2 = 0 and result = this.getArgument(n)) | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * A configuration for tracking flow from a call to `strings.NewReplacer` to | ||
| * the receiver of a call to `strings.Replacer.Replace` or | ||
| * `strings.Replacer.WriteString`. | ||
| */ | ||
| class StringsNewReplacerConfiguration extends DataFlow2::Configuration { | ||
| StringsNewReplacerConfiguration() { this = "StringsNewReplacerConfiguration" } | ||
|
|
||
| override predicate isSource(DataFlow::Node source) { source instanceof StringsNewReplacerCall } | ||
|
|
||
| override predicate isSink(DataFlow::Node sink) { | ||
| exists(DataFlow::MethodCallNode call | | ||
| sink = call.getReceiver() and | ||
| call.getTarget().hasQualifiedName("strings", "Replacer", ["Replace", "WriteString"]) | ||
| ) | ||
| } | ||
| } |
There was a problem hiding this comment.
This part seems to be identical between LogInjectionCustomizations and StringBreakCustomizations. Would it make sense / be possible to de-duplicate this in a shared location?
There was a problem hiding this comment.
Good idea. It feels like something that should be usable in many different places. I've moved it to StringOps.qll, which should hopefully make that simple. I've started a performance evaluation as this is a fairly major change.
There was a problem hiding this comment.
The performance analysis was neutral.
9d2d4f4 to
3fda9f6
Compare
|
I've updated this to use its own copy of the dataflow library. The failing QLDoc test is because of an undocumented predicate in the dataflow library, which obviously I'm not going to fix in this PR, so I believe it should be ignored. |
smowton
left a comment
There was a problem hiding this comment.
Made an import of an internal library private; otherwise LGTM
…ion (CWE-117) Replace custom byte-level loop with package-level strings.NewReplacer variable (logSanitizer). CodeQL explicitly recognizes strings.Replacer.Replace as a sanitizer for go/log-injection since github/codeql#11910. Call logSanitizer.Replace() directly at each log site. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…176) * Add lifecycle management for sandbox processes Introduces new lifecycle features to the sandbox API, including the ability to force stop processes and retrieve the current sandbox status. The `/stop` endpoint allows for immediate or scheduled removal of the keepAlive flag from running processes, enabling auto-hibernation. The `/status` endpoint provides information on the current state of the sandbox and active keepAlive processes. Additionally, integrates the lifecycle management with the MCP tools, enhancing the overall process control and monitoring capabilities. The scale-to-zero functionality is also improved with crash recovery mechanisms. Updates include: - New `LifecycleHandler` for managing lifecycle operations. - API documentation updates for new endpoints. - Integration of keepAlive functionality in process management. - Comprehensive tests for lifecycle features and MCP integration. * Enhance scale-to-zero functionality with improved error handling and logging * Remove lifecycle management endpoints and related functionality This commit removes the `/stop` and `/status` endpoints from the sandbox API, along with the associated `LifecycleHandler` and related data structures. The lifecycle management features, including the ability to force stop processes and retrieve the current sandbox status, have been deprecated. Updates include: - Deletion of lifecycle-related API routes and handlers. - Removal of lifecycle management types and structures from the codebase. - Adjustments to documentation to reflect the removal of these features. This change simplifies the API and focuses on core process management functionalities. * Fix PR * Fix bug introduce with AI check * Implement keepAlive timeout handling for restarted processes This commit introduces functionality to manage timeouts for processes with the keepAlive flag enabled. If a process is restarted and keepAlive is active with a specified timeout, a goroutine is initiated to monitor the timeout and kill the process if it exceeds the limit. For processes with an infinite timeout, the goroutine simply waits for the process to complete. This enhancement improves process management and ensures better resource handling. * Fix some recommendation from AI * Enhance logging in ProcessManager to include process name in scale-to-zero warnings and timeout messages. Clear KeepAlive state before killing processes to prevent double ScaleEnable calls. Refactor related log messages for consistency. * Refactor logging in ProcessManager to use structured log entries for KeepAlive events. Enhance clarity by including process details in log messages for scale-to-zero operations and timeout handling. This improves consistency and debuggability of process management logs. * Sanitize user-provided values in log entries to prevent log injection (CWE-117) Add sanitizeLogValue() helper that escapes newlines and control characters. Replace structured logging (logrus.WithFields) with simple logrus.Infof/Warnf calls that use sanitized values - clearer and more readable. Addresses all CodeQL 'Log entries created from user input' warnings. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * Improve sanitizeLogValue to strip all control characters (CWE-117) Replace strings.NewReplacer with byte-level filtering that strips all control characters (< 0x20) including newlines. This provides more thorough sanitization against log injection. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * Use strings.NewReplacer as CodeQL-recognized sanitizer for log injection (CWE-117) Replace custom byte-level loop with package-level strings.NewReplacer variable (logSanitizer). CodeQL explicitly recognizes strings.Replacer.Replace as a sanitizer for go/log-injection since github/codeql#11910. Call logSanitizer.Replace() directly at each log site. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * Use %q format directive for user-provided values in log entries (CWE-117) CodeQL's SafeFormatArgumentSanitizer explicitly recognizes %q as safe because it escapes newline characters. This is the simplest and most idiomatic fix - no helper functions or variables needed. Removes the logSanitizer variable entirely. User-provided values (name, command) are now logged with %q which produces Go-syntax quoted strings, making any control characters visible in the output. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * Revert sanitize/log changes - restore original structured logging Reverts commits 6902a62, 16773fb, 4eeb6f7, 3a5b776 which added log sanitization for CWE-117. Keeps all other agent recommendations (structured logging with logrus.WithFields, race condition fix, etc). Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * Fix StopProcess keepAlive leak and KeepAlive data race - StopProcess (SIGTERM path) now clears KeepAlive and calls ScaleEnable, preventing the scale-to-zero counter from leaking when a keepAlive process is gracefully stopped. - All reads/writes of process.KeepAlive are now synchronized via pm.mu: KillProcess and StopProcess write under Lock(), completion goroutines read under RLock(). This eliminates the data race between the kill/stop path and the completion goroutine. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * Fix data race on oldProcess.KeepAlive read in restartProcess Protect the read of oldProcess.KeepAlive and oldProcess.Timeout in restartProcess with pm.mu.RLock(), matching the synchronization used by KillProcess/StopProcess which write under pm.mu.Lock(). Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: cploujoux <ch.ploujoux@gmail.com> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Add
strings.Replacer.Replaceandstrings.Replacer.WriteStringas sanitizers for log-injection and string-break.This is a resurrection of github/codeql-go#731.