Consider subtypes of Expression and ExpressionParser

Add parseRaw as additional taint step
This commit is contained in:
Tony Torralba
2021-06-15 15:22:47 +02:00
parent b0852f6c16
commit 569426b04e
10 changed files with 392 additions and 13 deletions

View File

@@ -105,7 +105,7 @@ private predicate isSimpleEvaluationContextBuilderCall(Expr expr) {
*/
private class ExpressionEvaluationMethod extends Method {
ExpressionEvaluationMethod() {
this.getDeclaringType() instanceof Expression and
this.getDeclaringType().getASupertype*() instanceof Expression and
this.hasName(["getValue", "getValueTypeDescriptor", "getValueType", "setValue"])
}
}
@@ -116,8 +116,8 @@ private class ExpressionEvaluationMethod extends Method {
*/
private predicate expressionParsingStep(DataFlow::Node node1, DataFlow::Node node2) {
exists(MethodAccess ma, Method m | ma.getMethod() = m |
m.getDeclaringType().getAnAncestor*() instanceof ExpressionParser and
m.hasName("parseExpression") and
m.getDeclaringType().getASupertype*() instanceof ExpressionParser and
m.hasName(["parseExpression", "parseRaw"]) and
ma.getAnArgument() = node1.asExpr() and
node2.asExpr() = ma
)

View File

@@ -3,6 +3,7 @@ import java.io.InputStream;
import java.net.Socket;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.SimpleEvaluationContext;
import org.springframework.expression.spel.support.StandardEvaluationContext;
@@ -23,6 +24,17 @@ public class SpelInjectionTest {
expression.getValue(); // $hasSpelInjection
}
public void testGetValueWithParseRaw(Socket socket) throws IOException {
InputStream in = socket.getInputStream();
byte[] bytes = new byte[1024];
int n = in.read(bytes);
String input = new String(bytes, 0, n);
SpelExpressionParser parser = new SpelExpressionParser();
SpelExpression expression = parser.parseRaw(input);
expression.getValue(); // $hasSpelInjection
}
public void testGetValueWithChainedCalls(Socket socket) throws IOException {
InputStream in = socket.getInputStream();

View File

@@ -1,14 +1,65 @@
/*
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.springframework.expression;
import org.springframework.lang.Nullable;
public interface Expression {
String getExpressionString();
Object getValue() throws EvaluationException;
<T> T getValue(@Nullable Class<T> desiredResultType) throws EvaluationException;
Object getValue(@Nullable Object rootObject) throws EvaluationException;
<T> T getValue(@Nullable Object rootObject, @Nullable Class<T> desiredResultType)
throws EvaluationException;
Object getValue(EvaluationContext context) throws EvaluationException;
Object getValue(EvaluationContext context, @Nullable Object rootObject)
throws EvaluationException;
<T> T getValue(EvaluationContext context, @Nullable Class<T> desiredResultType)
throws EvaluationException;
<T> T getValue(EvaluationContext context, @Nullable Object rootObject,
@Nullable Class<T> desiredResultType) throws EvaluationException;
Class<?> getValueType() throws EvaluationException;
Class<?> getValueType(@Nullable Object rootObject) throws EvaluationException;
Class<?> getValueType(EvaluationContext context) throws EvaluationException;
void setValue(Object rootObject, Object value) throws EvaluationException;
}
Class<?> getValueType(EvaluationContext context, @Nullable Object rootObject)
throws EvaluationException;
boolean isWritable(@Nullable Object rootObject) throws EvaluationException;
boolean isWritable(EvaluationContext context) throws EvaluationException;
boolean isWritable(EvaluationContext context, @Nullable Object rootObject)
throws EvaluationException;
void setValue(@Nullable Object rootObject, @Nullable Object value) throws EvaluationException;
void setValue(EvaluationContext context, @Nullable Object value) throws EvaluationException;
void setValue(EvaluationContext context, @Nullable Object rootObject, @Nullable Object value)
throws EvaluationException;
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.springframework.expression;
import org.springframework.lang.Nullable;
public class ExpressionException extends RuntimeException {
public ExpressionException(String message) {}
public ExpressionException(String message, Throwable cause) {}
public ExpressionException(@Nullable String expressionString, String message) {}
public ExpressionException(@Nullable String expressionString, int position, String message) {}
public ExpressionException(int position, String message) {}
public ExpressionException(int position, String message, Throwable cause) {}
public final String getExpressionString() {
return null;
}
public final int getPosition() {
return 0;
}
@Override
public String getMessage() {
return null;
}
public String toDetailedString() {
return null;
}
public String getSimpleMessage() {
return null;
}
}

View File

@@ -1,6 +1,23 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.springframework.expression;
public interface ExpressionParser {
Expression parseExpression(String expressionString) throws ParseException;
Expression parseExpression(String string);
}
Expression parseExpression(String expressionString, ParserContext context)
throws ParseException;
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.springframework.expression;
import org.springframework.lang.Nullable;
public class ParseException extends ExpressionException {
public ParseException(@Nullable String expressionString, int position, String message) {
super(expressionString, message);
}
public ParseException(int position, String message, Throwable cause) {
super(message, cause);
}
public ParseException(int position, String message) {
super(message);
}
}

View File

@@ -0,0 +1,26 @@
/*
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.springframework.expression;
public interface ParserContext {
boolean isTemplate();
String getExpressionPrefix();
String getExpressionSuffix();
ParserContext TEMPLATE_EXPRESSION = null;
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.springframework.expression.common;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.ParseException;
import org.springframework.expression.ParserContext;
import org.springframework.lang.Nullable;
public abstract class TemplateAwareExpressionParser implements ExpressionParser {
@Override
public Expression parseExpression(String expressionString) throws ParseException {
return null;
}
@Override
public Expression parseExpression(String expressionString, @Nullable ParserContext context)
throws ParseException {
return null;
}
}

View File

@@ -0,0 +1,137 @@
/*
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.springframework.expression.spel.standard;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.Expression;
import org.springframework.lang.Nullable;
public class SpelExpression implements Expression {
public void setEvaluationContext(EvaluationContext evaluationContext) {}
public EvaluationContext getEvaluationContext() {
return null;
}
@Override
public String getExpressionString() {
return null;
}
@Override
public Object getValue() throws EvaluationException {
return null;
}
@Override
public <T> T getValue(@Nullable Class<T> expectedResultType) throws EvaluationException {
return null;
}
@Override
public Object getValue(@Nullable Object rootObject) throws EvaluationException {
return null;
}
@Override
public <T> T getValue(@Nullable Object rootObject, @Nullable Class<T> expectedResultType)
throws EvaluationException {
return null;
}
@Override
public Object getValue(EvaluationContext context) throws EvaluationException {
return null;
}
@Override
public <T> T getValue(EvaluationContext context, @Nullable Class<T> expectedResultType)
throws EvaluationException {
return null;
}
@Override
public Object getValue(EvaluationContext context, @Nullable Object rootObject)
throws EvaluationException {
return null;
}
@Override
public <T> T getValue(EvaluationContext context, @Nullable Object rootObject,
@Nullable Class<T> expectedResultType) throws EvaluationException {
return null;
}
@Override
public Class<?> getValueType() throws EvaluationException {
return null;
}
@Override
public Class<?> getValueType(@Nullable Object rootObject) throws EvaluationException {
return null;
}
@Override
public Class<?> getValueType(EvaluationContext context) throws EvaluationException {
return null;
}
@Override
public Class<?> getValueType(EvaluationContext context, @Nullable Object rootObject)
throws EvaluationException {
return null;
}
@Override
public boolean isWritable(@Nullable Object rootObject) throws EvaluationException {
return false;
}
@Override
public boolean isWritable(EvaluationContext context) throws EvaluationException {
return false;
}
@Override
public boolean isWritable(EvaluationContext context, @Nullable Object rootObject)
throws EvaluationException {
return false;
}
@Override
public void setValue(@Nullable Object rootObject, @Nullable Object value)
throws EvaluationException {}
@Override
public void setValue(EvaluationContext context, @Nullable Object value)
throws EvaluationException {}
@Override
public void setValue(EvaluationContext context, @Nullable Object rootObject,
@Nullable Object value) throws EvaluationException {}
public boolean compileExpression() {
return false;
}
public void revertToInterpreted() {}
public String toStringAST() {
return null;
}
}

View File

@@ -1,10 +1,26 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.springframework.expression.spel.standard;
import org.springframework.expression.*;
public class SpelExpressionParser implements ExpressionParser {
import org.springframework.expression.ParseException;
import org.springframework.expression.common.TemplateAwareExpressionParser;
public class SpelExpressionParser extends TemplateAwareExpressionParser {
public SpelExpressionParser() {}
public Expression parseExpression(String string) { return null; }
}
public SpelExpression parseRaw(String expressionString) throws ParseException {
return null;
}
}