Improve security and prevent shell injection for push2applications#15628
Conversation
Review Summary by QodoPrevent shell injection vulnerabilities in push-to-application implementations
WalkthroughsDescription• Prevent shell injection vulnerabilities across push-to-application implementations - Replaced shell command concatenation with ProcessBuilder argument arrays - Added input validation for citation command prefixes and CAYW command parameters - Removed unsafe shell metacharacter escaping patterns • Improve error handling and user feedback in push operations - Added detailed error notifications with actionable guidance for users - Enhanced error detection for connection failures and missing executables - Implemented proper process exit code checking • Refactor command execution to use ProcessBuilder safely - Converted Runtime.exec() calls to ProcessBuilder for better argument handling - Fixed macOS osascript invocation to pass arguments safely - Removed shell wrapper invocations (sh -c, cmd.exe /c) where possible • Add thread-safety for GUI error notifications in push operations - Wrapped DialogService calls with UiTaskExecutor for JavaFX thread safety Diagramflowchart LR
A["Shell Injection Risks"] -->|"Replace with ProcessBuilder"| B["Safe Argument Handling"]
A -->|"Add Input Validation"| C["Command Parameter Validation"]
D["GUI Push Classes"] -->|"Add Thread Safety"| E["UiTaskExecutor Wrapper"]
F["Push Logic Classes"] -->|"Improve Error Handling"| G["Detailed Error Notifications"]
H["CAYW Resource"] -->|"Validate Command Parameter"| I["Regex Pattern Matching"]
B --> J["Secure Implementation"]
C --> J
E --> J
G --> J
I --> J
File Changes1. jabgui/src/main/java/org/jabref/gui/push/GuiPushToEmacs.java
|
Code Review by Qodo
1.
|
| if (!OS.OS_X) { | ||
| sendErrorNotification(Localization.lang("Push to application"), Localization.lang("Pushing citations to TeXShop is only possible on macOS!")); | ||
| return; |
There was a problem hiding this comment.
4. Texshop text has exclamation 📘 Rule violation ⚙ Maintainability
A new user-facing localized string ends with an exclamation mark, which violates the UI text style rules. This introduces inconsistent tone across UI messages.
Agent Prompt
## Issue description
A localized UI message ends with `!`, which is disallowed by UI text style rules.
## Issue Context
UI text should be sentence case and avoid exclamation marks.
## Fix Focus Areas
- jablib/src/main/java/org/jabref/logic/push/PushToTexShop.java[45-47]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| void getCommandLineEscapingUnix() { | ||
| CitationCommandString maliciousCommand = new CitationCommandString("\\cite{'; touch /tmp/pwned; #", ",", "}"); | ||
| when(preferences.getCiteCommand()).thenReturn(maliciousCommand); | ||
|
|
||
| pushToSublimeText.pushEntries(java.util.List.of()); | ||
|
|
||
| String[] commandLine = pushToSublimeText.getCommandLine("key"); | ||
|
|
There was a problem hiding this comment.
5. Test triggers external process 📘 Rule violation ☼ Reliability
The new unit test calls pushEntries(...), which will attempt to start the real /usr/bin/subl process and makes the test environment-dependent and flaky. Tests should be deterministic and not execute external processes.
Agent Prompt
## Issue description
The test calls `pushEntries`, which may spawn an external process and makes the test flaky across environments.
## Issue Context
The test’s intent is to validate command-line construction/escaping; it can assert on `getCommandLine(...)` output directly without executing anything.
## Fix Focus Areas
- jablib/src/test/java/org/jabref/logic/push/PushToSublimeTextTest.java[34-41]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
There was a problem hiding this comment.
We want to test the real commandline invocation
|
@junie-agent Fix the test |
|
Junie is failed! Details: ❌ Junie output file path is not set. This indicates that Junie execution did not complete properly. |
| // We use ProcessBuilder to avoid shell injection. | ||
| // 'start' is a cmd builtin, so we still need cmd /c start, | ||
| // but we should be careful with arguments. | ||
| // However, 'start' itself has special handling for double quotes (first quoted arg is title). | ||
| processBuilder.command("cmd.exe", | ||
| "/c", | ||
| "start", | ||
| "", | ||
| "\"%s\"".formatted(command[0]), | ||
| "\"%s\"".formatted(command[1]), | ||
| "\"%s\"".formatted(command[2]), | ||
| "\"+normal %s|\"".formatted(Integer.toString(column))); | ||
| "JabRef to Vim", | ||
| command[0], | ||
| command[1], | ||
| command[2], | ||
| command[3]); |
There was a problem hiding this comment.
I'm not sure about this, I think it still can be exploited but I didnt manage to get it done so far
There was a problem hiding this comment.
But we can merge and if I sometime manage to exploit it, we can change it again
|
Is that a method from the prefs? I am at phone right now |
It is a method of a Map#getOrDefault |
|
The only thing I could see why not using getOrDefault is if, for some weird case, the value stored to the application is null |
…urityIssues * upstream/fixSecurityIssues: fix jbang (#15649) Add initial claude action support Chore(deps): Bump org.glassfish.grizzly:grizzly-bom in /versions (#15648) Update IntelliJ settings (#15629) Chore(deps): Bump org.openrewrite.recipe:rewrite-recipe-bom (#15626) Fixed year not appearing on citation key for In-* entries due to orphaned crossref links (#9071) (#15582)
* upstream/main: Chore(deps): Bump dev.langchain4j:langchain4j-bom in /versions (#15652) Chore(deps): Bump com.dlsc.gemsfx:gemsfx in /versions (#15651) Chore(deps): Bump org.openrewrite.rewrite from 7.31.0 to 7.32.1 (#15645) Chore(deps): Bump com.autonomousapps:dependency-analysis-gradle-plugin (#15646) Chore(deps): Bump com.autonomousapps:dependency-analysis-gradle-plugin (#15647) Chore(deps): Bump jablib/src/main/resources/csl-locales (#15637) Chore(deps): Bump timheuer/base64-to-file from 1 to 2 (#15636) Chore(deps): Bump org.glassfish.hk2:hk2-api in /versions (#15639) Chore(deps): Bump jablib/src/main/resources/csl-styles (#15638) Chore(deps): Bump org.postgresql:postgresql in /versions (#15641) Chore(deps): Bump org.glassfish.hk2:hk2-locator in /versions (#15640) Chore(deps): Bump org.glassfish.hk2:hk2-utils in /versions (#15642) Chore(deps): Bump com.dlsc.gemsfx:gemsfx in /versions (#15643) Chore(deps): Bump gradle-wrapper from 9.5.0-rc-2 to 9.5.0 (#15632)
In that case there really should be an exception been thrown. |
|
I changed it to getOrDefault, see no issues with it |
* upstream/main: chore(deps): update jackson monorepo to v3.1.3 (#15659) chore(deps): update dependency org.glassfish.hk2:hk2-utils to v4.0.1 (#15657) chore(deps): update dependency org.glassfish.hk2:hk2-locator to v4.0.1 (#15656) fix gemsfx missing icon resolving (#15655) chore(deps): update dependency org.glassfish.hk2:hk2-api to v4.0.1 (#15654) chore(deps): update dependency org.postgresql:postgresql to v42.7.11 (#15634) Chore(deps): Bump tools.jackson:jackson-bom in /versions (#15653)
|
failing test is coming from #15655 |
CI Feedback 🧐A test triggered by this PR failed. Here is an AI-generated analysis of the failure:
|
…rity * upstream/main: (204 commits) New Crowdin updates (JabRef#15669) Fix OpenRewrite (JabRef#15670) Udpate heylogs (and fix CHANGELOG.md) (JabRef#15671) Improve security and prevent shell injection for push2applications (JabRef#15628) Fix depdency analysis (JabRef#15668) Always use CI-local "gradle", instead of gradlew (JabRef#15667) Change OpenRewrite task to use rewriteDryRun (JabRef#15664) Add small documentation to parameter (JabRef#15666) Fix markbaseChanged for "imported entries" (JabRef#15610) Add forgotten --fresh chore(deps): update dependency com.github.ben-manes.caffeine:caffeine to v3.2.4 (JabRef#15662) chore(deps): update jackson monorepo to v3.1.3 (JabRef#15659) chore(deps): update dependency org.glassfish.hk2:hk2-utils to v4.0.1 (JabRef#15657) chore(deps): update dependency org.glassfish.hk2:hk2-locator to v4.0.1 (JabRef#15656) fix gemsfx missing icon resolving (JabRef#15655) chore(deps): update dependency org.glassfish.hk2:hk2-api to v4.0.1 (JabRef#15654) chore(deps): update dependency org.postgresql:postgresql to v42.7.11 (JabRef#15634) Chore(deps): Bump tools.jackson:jackson-bom in /versions (JabRef#15653) Chore(deps): Bump dev.langchain4j:langchain4j-bom in /versions (JabRef#15652) Chore(deps): Bump com.dlsc.gemsfx:gemsfx in /versions (JabRef#15651) ...
* upstream/main: (775 commits) Chore(deps): Bump com.konghq:unirest-modules-gson in /versions (#15682) Chore(deps): Bump org.glassfish.jaxb:jaxb-runtime in /versions (#15681) Update dependency com.konghq:unirest-modules-gson to v4.9.0 (#15679) Integrate with SearchRxiv (#15373) Fix requirements (#15600) refactor: less objects during writing (#15677) Fix: suppress WARN for empty or blank column name in MainTableColumnModel#parse() (#15576) New Crowdin updates (#15676) Chore(deps): Bump com.github.ben-manes.caffeine:caffeine in /versions (#15673) Fix Nullwarnings - C (Mark bst package as nonnull by default) (#15663) Chore(deps): Bump com.github.javaparser:javaparser-symbol-solver-core (#15674) Chore(deps): Bump com.github.javaparser:javaparser-core in /versions (#15672) New Crowdin updates (#15669) Fix OpenRewrite (#15670) Udpate heylogs (and fix CHANGELOG.md) (#15671) Improve security and prevent shell injection for push2applications (#15628) Fix depdency analysis (#15668) Always use CI-local "gradle", instead of gradlew (#15667) Change OpenRewrite task to use rewriteDryRun (#15664) Add small documentation to parameter (#15666) ...
Related issues and pull requests
Fix some security issues
Secure Push2Applications and improve error handling and one FXthread issue
Secure CAYW
PR Description
Steps to test
Checklist
CHANGELOG.mdin a way that can be understood by the average user (if change is visible to the user)