com.h3xstream.findsecbugs.taintanalysis.TaintClassConfig Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of findsecbugs-plugin Show documentation
Show all versions of findsecbugs-plugin Show documentation
Core module of the project. It include all the SpotBugs detectors.
The resulting jar is the published plugin.
The newest version!
/**
* Find Security Bugs
* Copyright (c) Philippe Arteau, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.h3xstream.findsecbugs.taintanalysis;
import java.io.IOException;
import java.util.regex.Pattern;
/**
* Summary of information about a class related to taint analysis,
* allows to configure default behavior for return types and type casts.
*
* Default configuration is mutable class with null taint state.
*
* @author Tomas Polesovsky (Liferay, Inc.)
*/
public class TaintClassConfig implements TaintTypeConfig {
public static final Taint.State DEFAULT_TAINT_STATE = Taint.State.NULL;
private static final String IMMUTABLE = "#IMMUTABLE";
private Taint.State taintState = DEFAULT_TAINT_STATE;
private boolean immutable;
private String typeSignature;
private static final Pattern typePattern;
private static final Pattern taintConfigPattern;
static {
String javaIdentifierRegex = "\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*";
String classWithPackageRegex = javaIdentifierRegex+"(\\/"+javaIdentifierRegex+")*";
String typeRegex = "(\\[)*((L" + classWithPackageRegex + ";)|B|C|D|F|I|J|S|Z)";
typePattern = Pattern.compile(typeRegex);
String taintConfigRegex = "([A-Z_]+|#IMMUTABLE|[A-Z_]+#IMMUTABLE)";
taintConfigPattern = Pattern.compile(taintConfigRegex);
}
public static boolean accepts(String typeSignature, String taintConfig) {
return typePattern.matcher(typeSignature).matches() && taintConfigPattern.matcher(taintConfig).matches();
}
/**
* Loads class summary from String
*
* The summary should have the following syntax:
* defaultTaintState #IMMUTABLE
, where
* defaultTaintState
means the Taint state for type casting and return types. Usually SAFE
is used to specify classes that cannot contain injection escape characters
* #IMMUTABLE
flags is used for classes that cannot be subject to taint state mutation during taint analysis
* - at least one of two above are required
*
*
* Example:
* Ljava/lang/Boolean;:SAFE#IMMUTABLE
*
* - Here the summary is:
SAFE#IMMUTABLE
* - When a object is casted to Boolean or Boolean is a method result type, the taint state will be always SAFE
* - When applying taint mutation to method arguments, Boolean arguments cannot change taint state
* - Practically, Booleans cannot transfer characters that could cause injections and thus are SAFE as return types and casts
*
*
* Example:
* Ljava/lang/String;:#IMMUTABLE
*
* - String is immutable class and therefore String method arguments cannot change taint state
* - Practically, String can carry injection sensitive characters but is always immutable
*
*
* Example:
* Ljava/util/concurrent/atomic/AtomicBoolean;:SAFE
*
* - AtomicBoolean value can be changed but cannot carry injection sensitive value
*
*
* @param taintConfig state#IMMUTABLE
, where state is one of Taint.STATE or empty
* @return initialized object with taint class summary
* @throws java.io.IOException for bad format of parameter
* @throws NullPointerException if argument is null
*/
@Override
public TaintClassConfig load(String taintConfig) throws IOException {
if (taintConfig == null) {
throw new NullPointerException("Taint config is null");
}
taintConfig = taintConfig.trim();
if (taintConfig.isEmpty()) {
throw new IOException("No taint class config specified");
}
if (taintConfig.endsWith(IMMUTABLE)) {
immutable = true;
taintConfig = taintConfig.substring(0, taintConfig.length() - IMMUTABLE.length());
}
if (!taintConfig.isEmpty()) {
taintState = Taint.State.valueOf(taintConfig);
}
return this;
}
public Taint.State getTaintState() {
return taintState;
}
public boolean isImmutable() {
return immutable;
}
public Taint.State getTaintState(Taint.State defaultState) {
if (taintState.equals(DEFAULT_TAINT_STATE)) {
return defaultState;
}
return taintState;
}
/**
* Set full class and method signature for the analyzed method
*
* @param typeSignature method signature
*/
public void setTypeSignature(String typeSignature) {
this.typeSignature = typeSignature;
}
/**
* Returns the analyzed method full signature
*
* @return signature of the method
*/
public String getTypeSignature() {
return typeSignature;
}
}