Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading