All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.codemodder.remediation.xss.PrintingMethodFixer Maven / Gradle / Ivy

package io.codemodder.remediation.xss;

import static io.codemodder.javaparser.JavaParserTransformer.wrap;

import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.MethodCallExpr;
import com.github.javaparser.ast.expr.NameExpr;
import com.github.javaparser.ast.nodeTypes.NodeWithType;
import io.codemodder.ast.ASTs;
import io.codemodder.codetf.DetectorRule;
import io.codemodder.remediation.RemediationMessages;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;

/**
 * Fixes a method invocation that prints {@link String} expression.
 *
 * 
{@code
 * out.println(foo); // should become return out.println(Encode.forHtml(foo));
 * }
*/ final class PrintingMethodFixer implements XSSCodeShapeFixer { private static final Set writingMethodNames = Set.of("print", "println", "write"); @Override public XSSCodeShapeFixResult fixCodeShape( final CompilationUnit cu, final String path, final DetectorRule detectorRule, final List issues, final Function getKey, final Function getLine, final Function getColumn) { int line = getLine.apply(issues.get(0)); Integer column = getColumn.apply(issues.get(0)); List writingMethodCalls = cu.findAll(MethodCallExpr.class).stream() .filter(mce -> writingMethodNames.contains(mce.getNameAsString())) .filter(mce -> mce.getArguments().size() == 1) .filter(mce -> mce.getRange().isPresent()) .filter(mce -> mce.getRange().get().begin.line == line) .filter(mce -> column == null || mce.getRange().get().begin.column == column) .filter( mce -> { Expression arg = mce.getArgument(0); if (arg instanceof NameExpr nameExpr) { Optional source = ASTs.findNonCallableSimpleNameSource(nameExpr.getName()); if (source.isPresent() && source.get() instanceof NodeWithType typedNode) { String typeAsString = typedNode.getTypeAsString(); return "String".equals(typeAsString) || "java.lang.String".equals(typeAsString); } } return false; }) .toList(); if (writingMethodCalls.isEmpty()) { return new XSSCodeShapeFixResult(false, false, null, line); } else if (writingMethodCalls.size() > 1) { return new XSSCodeShapeFixResult(true, false, RemediationMessages.multipleNodesFound, line); } MethodCallExpr call = writingMethodCalls.get(0); wrap(call.getArgument(0)).withStaticMethod("org.owasp.encoder.Encode", "forHtml", false); return new XSSCodeShapeFixResult(true, true, null, line); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy