Skip to content

Commit

Permalink
New remediation code shapes (#469)
Browse files Browse the repository at this point in the history
Adding other form of ZipSlip remediation
Added XSS reported in `ResponseEntity`
  • Loading branch information
nahsra authored Nov 20, 2024
1 parent 0fd8818 commit 2c4bb17
Show file tree
Hide file tree
Showing 19 changed files with 2,747 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ void it_remediates_webgoat_2023_8() throws Exception {
.flatMap(Collection::stream)
.toList();

assertThat(fileChanges.size(), is(50));
assertThat(fileChanges.size(), is(51));

verifyStandardCodemodResults(fileChanges);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public static List<Class<? extends CodeChanger>> asList() {
CodeQLUnverifiedJwtCodemod.class,
CodeQLXSSCodemod.class,
CodeQLXXECodemod.class,
CodeQLZipSlipHandler.class,
DeclareVariableOnSeparateLineCodemod.class,
DefectDojoSqlInjectionCodemod.class,
DefineConstantForLiteralCodemod.class,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package io.codemodder.codemods.codeql;

import com.contrastsecurity.sarif.Result;
import com.github.javaparser.ast.CompilationUnit;
import io.codemodder.*;
import io.codemodder.codetf.DetectorRule;
import io.codemodder.providers.sarif.codeql.ProvidedCodeQLScan;
import io.codemodder.remediation.GenericRemediationMetadata;
import io.codemodder.remediation.Remediator;
import io.codemodder.remediation.zipslip.ZipSlipRemediator;
import java.util.Optional;
import javax.inject.Inject;

/** A codemod for automatically fixing Zip Slip issues from CodeQL. */
@Codemod(
id = "codeql:java/zipslip",
reviewGuidance = ReviewGuidance.MERGE_AFTER_CURSORY_REVIEW,
importance = Importance.HIGH,
executionPriority = CodemodExecutionPriority.HIGH)
public final class CodeQLZipSlipHandler extends CodeQLRemediationCodemod {

private final Remediator<Result> remediator;

@Inject
public CodeQLZipSlipHandler(@ProvidedCodeQLScan(ruleId = "java/zipslip") final RuleSarif sarif) {
super(GenericRemediationMetadata.ZIP_SLIP.reporter(), sarif);
this.remediator = new ZipSlipRemediator<>();
}

@Override
public DetectorRule detectorRule() {
return new DetectorRule(
"zipslip",
"Arbitrary file access during archive extraction (\"Zip Slip\")\n",
"https://codeql.github.com/codeql-query-help/java/java-zipslip/");
}

@Override
public CodemodFileScanningResult visit(
final CodemodInvocationContext context, final CompilationUnit cu) {
return remediator.remediateAll(
cu,
context.path().toString(),
detectorRule(),
ruleSarif.getResultsByLocationPath(context.path()),
SarifFindingKeyUtil::buildFindingId,
r -> r.getLocations().get(0).getPhysicalLocation().getRegion().getStartLine(),
r -> Optional.of(r.getLocations().get(0).getPhysicalLocation().getRegion().getEndLine()),
r ->
Optional.of(
r.getLocations().get(0).getPhysicalLocation().getRegion().getStartColumn()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.codemodder.codemods.codeql;

import io.codemodder.testutils.CodemodTestMixin;
import io.codemodder.testutils.Metadata;

@Metadata(
codemodType = CodeQLZipSlipHandler.class,
testResourceDir = "codeql-zipslip",
renameTestFile = "Path Traversal/ZipTraversal.java",
expectingFixesAtLines = {11},
dependencies = {})
final class CodeQLZipSlipHandlerTest implements CodemodTestMixin {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import java.util.zip.ZipFile;
import java.util.zip.ZipEntry;
class Foo { // added this to make this a valid file for testing
public void extract(ZipFile zip) {

String toDir = "/my/target/directory/";
Enumeration entries = zip.entries();
while (entries.hasMoreElements()) {
ZipEntry zipEntry = entries.nextElement();

File file = new File(toDir, sanitizeZipFilename(zipEntry.getName()));
InputStream istr = zipFile.getInputStream(zipEntry);
final OutputStream os = Files.newOutputStream(file.toPath());
bos = new BufferedOutputStream(os);
IOUtils.copy(bis, bos);

}
}

String sanitizeZipFilename(String entryName) {
if (entryName == null || entryName.trim().isEmpty()) {
return entryName;
}
while (entryName.contains("../") || entryName.contains("..\\")) {
entryName = entryName.replace("../", "").replace("..\\", "");
}
return entryName;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import java.util.zip.ZipFile;
import java.util.zip.ZipEntry;
class Foo { // added this to make this a valid file for testing
public void extract(ZipFile zip) {

String toDir = "/my/target/directory/";
Enumeration entries = zip.entries();
while (entries.hasMoreElements()) {
ZipEntry zipEntry = entries.nextElement();

File file = new File(toDir, zipEntry.getName());
InputStream istr = zipFile.getInputStream(zipEntry);
final OutputStream os = Files.newOutputStream(file.toPath());
bos = new BufferedOutputStream(os);
IOUtils.copy(bis, bos);

}
}
}
Loading

0 comments on commit 2c4bb17

Please sign in to comment.