Skip to content

Commit 928d321

Browse files
authored
⬆️ Upgrade GPT 3.5 Turbo Model (#398)
gpt-3.5-turbo-0613 has been removed, so replace it with new models. * Updated failed authentication logging codemod to use new models and `SarifToLLMForMultiOutcomeCodemod`. * Added a `Model` type to describe GPT models and colocates model-specific logic such as token counting. /close #work
1 parent ac345b2 commit 928d321

File tree

20 files changed

+1163
-97
lines changed

20 files changed

+1163
-97
lines changed
Lines changed: 60 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
package io.codemodder.codemods;
22

3-
import static io.codemodder.CodemodResources.getClassResourceAsString;
4-
5-
import com.contrastsecurity.sarif.Result;
6-
import com.github.difflib.patch.AbstractDelta;
7-
import com.github.difflib.patch.InsertDelta;
8-
import com.github.difflib.patch.Patch;
93
import io.codemodder.*;
4+
import io.codemodder.plugins.llm.CodeChangingLLMRemediationOutcome;
5+
import io.codemodder.plugins.llm.NoActionLLMRemediationOutcome;
106
import io.codemodder.plugins.llm.OpenAIService;
11-
import io.codemodder.plugins.llm.SarifToLLMForBinaryVerificationAndFixingCodemod;
7+
import io.codemodder.plugins.llm.SarifToLLMForMultiOutcomeCodemod;
8+
import io.codemodder.plugins.llm.StandardModel;
129
import io.codemodder.providers.sarif.semgrep.SemgrepScan;
1310
import java.util.List;
1411
import javax.inject.Inject;
@@ -17,39 +14,68 @@
1714
id = "pixee:java/log-failed-login",
1815
importance = Importance.HIGH,
1916
reviewGuidance = ReviewGuidance.MERGE_AFTER_REVIEW)
20-
public final class LogFailedLoginCodemod extends SarifToLLMForBinaryVerificationAndFixingCodemod {
17+
public final class LogFailedLoginCodemod extends SarifToLLMForMultiOutcomeCodemod {
2118

2219
@Inject
2320
public LogFailedLoginCodemod(
2421
@SemgrepScan(ruleId = "log-failed-login") final RuleSarif sarif, final OpenAIService openAI) {
25-
super(sarif, openAI);
22+
super(
23+
sarif,
24+
openAI,
25+
List.of(
26+
new NoActionLLMRemediationOutcome(
27+
"logs_failed_login_with_logger",
28+
"""
29+
The code uses a logger to log a message that indicates a failed login attempt.
30+
The message is logged at the INFO or higher level.
31+
"""
32+
.replace('\n', ' ')),
33+
new NoActionLLMRemediationOutcome(
34+
"logs_failed_login_with_console",
35+
"""
36+
The code sends a message to the console that indicates a failed login attempt.
37+
The code may output this message to either System.out or System.err.
38+
"""
39+
.replace('\n', ' ')),
40+
new NoActionLLMRemediationOutcome(
41+
"throws_exception",
42+
"""
43+
The code throws an exception that indicates a failed login attempt.
44+
Throwing such an exception is a reasonable alternative to logging the failed login attempt.
45+
When the username for the failed login is in-scope, the exception message includes the username.
46+
"""
47+
.replace('\n', ' ')),
48+
new NoActionLLMRemediationOutcome(
49+
"no_authentication",
50+
"""
51+
The login validation fails because the request lacks credentials to validate. This is not considered a failed login attempt that requires auditing.
52+
"""
53+
.replace('\n', ' ')),
54+
new CodeChangingLLMRemediationOutcome(
55+
"add_missing_logging",
56+
"""
57+
None of the other outcomes apply.
58+
The code that validates the login credentials does not log a message when the login attempt fails,
59+
NOR does it throw an exception that reasonably indicates a failed login attempt and includes the username in the exception message.
60+
"""
61+
.replace('\n', ' '),
62+
"""
63+
Immediately following the login failure, add precisely one statement to log the failed login attempt at the INFO level.
64+
If the username for the failed login is in scope, the new log message references the username.
65+
Add exactly one such log statement! Exactly one!
66+
The new log statement is consistent with the rest of the code with respect to formatting, braces, casing, etc.
67+
When no logger is in scope, the new code emits a log message to the console.
68+
"""
69+
.replace('\n', ' '))),
70+
StandardModel.GPT_4O,
71+
StandardModel.GPT_4);
2672
}
2773

2874
@Override
29-
protected String getThreatPrompt(
30-
final CodemodInvocationContext context, final List<Result> results) {
31-
return getClassResourceAsString(getClass(), "threat_prompt.txt");
32-
}
33-
34-
@Override
35-
protected String getFixPrompt() {
36-
return getClassResourceAsString(getClass(), "fix_prompt.txt");
37-
}
38-
39-
@Override
40-
protected boolean isPatchExpected(Patch<String> patch) {
41-
// This codemod should make two or fewer modifications.
42-
if (patch.getDeltas().size() > 2) {
43-
return false;
44-
}
45-
46-
// This codemod should only insert lines.
47-
for (AbstractDelta<String> delta : patch.getDeltas()) {
48-
if (!(delta instanceof InsertDelta<String>)) {
49-
return false;
50-
}
51-
}
52-
53-
return true;
75+
protected String getThreatPrompt() {
76+
return """
77+
The tool has cited an authentication check that does not include a means for auditing failed login attempt.
78+
"""
79+
.replace('\n', ' ');
5480
}
5581
}

core-codemods/src/main/resources/io/codemodder/codemods/LogFailedLoginCodemod/fix_prompt.txt

Lines changed: 0 additions & 4 deletions
This file was deleted.

core-codemods/src/main/resources/io/codemodder/codemods/LogFailedLoginCodemod/threat_prompt.txt

Lines changed: 0 additions & 18 deletions
This file was deleted.

core-codemods/src/test/java/io/codemodder/codemods/LogFailedLoginCodemodTest.java

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,45 @@
55
import io.codemodder.testutils.Metadata;
66
import org.junit.jupiter.api.Disabled;
77

8+
/**
9+
* Tests for the {@link LogFailedLoginCodemod}.
10+
*
11+
* <p>Test cases that should not have code changes:
12+
*
13+
* <dl>
14+
* <dt>safe/AuthProvider.java.before
15+
* <dd>Describes a type that performs authentication, but no authentication implemented here.
16+
* <dt>safe/JaaSAuthenticationBroker.java.before
17+
* <dd>Throws exceptions that indicate failed login attempts.
18+
* <dt>safe/LoginServlet.java.before
19+
* <dd>logs authentication failures at the WARN level.
20+
* <dt>safe/Main.java.before
21+
* <dd>Logs a message when authentication fails.
22+
* <dt>safe/MainPrint.before
23+
* <dd>prints to the console when a login attempt fails.
24+
* <dt>safe/Queue.java.before
25+
* <dd>is too large to be analyzed.
26+
* </dl>
27+
*
28+
* Test cases that should have code changes:
29+
*
30+
* <dl>
31+
* <dt>unsafe/LoginServlet.java.before
32+
* <dd>lacks a log statement before returning unauthorized response
33+
* <dt>unsafe/LoginValidate.java.before
34+
* <dd>lacks a print statement before redirecting to error page.
35+
* <dt>unsafe/MainFame.java.before
36+
* <dd>lacks a log statement before showing the dialog.
37+
* <dt>unsafe/SaltedHashLoginModule
38+
* <dd>lacks a log statement before returning the authenticated decision. That is the correct
39+
* place to log, because it has the username in scope.
40+
*/
841
@Metadata(
942
codemodType = LogFailedLoginCodemod.class,
1043
testResourceDir = "log-failed-login",
1144
dependencies = {})
1245
@OpenAIIntegrationTest
13-
@Disabled("codemod is in disrepair")
46+
@Disabled("codemod in disrepair - behavior is too indeterminate")
1447
public final class LogFailedLoginCodemodTest implements LLMVerifyingCodemodTestMixin {
1548

1649
@Override

core-codemods/src/test/resources/log-failed-login/vulnerable/MainFrame.java.after

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ ResultSet rs = stmt.executeQuery(sql);
154154
this.dispose();
155155
}
156156
else{
157-
Logger.getLogger(MainFrame.class.getName()).log(Level.WARNING, "Failed login attempt for user: " + uname1);
157+
Logger.getLogger(MainFrame.class.getName()).log(Level.INFO, "Failed login attempt for user: " + uname1);
158158
JOptionPane.showMessageDialog(null, "Incorrect Username Or Password", "Login Failed", 2);
159159
}
160160

@@ -211,6 +211,3 @@ ResultSet rs = stmt.executeQuery(sql);
211211
private javax.swing.JTextField upass;
212212
// End of variables declaration//GEN-END:variables
213213
}
214-
215-
216-

0 commit comments

Comments
 (0)