| 1 package edu.umd.cs.findbugs.detect; 2 3 import java.util.BitSet ; 4 import java.util.Iterator ; 5 6 import org.apache.bcel.Constants; 7 import org.apache.bcel.classfile.Method; 8 import org.apache.bcel.generic.ConstantPoolGen; 9 import org.apache.bcel.generic.INVOKEINTERFACE; 10 import org.apache.bcel.generic.Instruction; 11 import org.apache.bcel.generic.InstructionHandle; 12 import org.apache.bcel.generic.MethodGen; 13 import org.apache.bcel.generic.ReferenceType; 14 import org.apache.bcel.generic.Type; 15 16 import edu.umd.cs.findbugs.DeepSubtypeAnalysis; 17 import edu.umd.cs.findbugs.BugInstance; 18 import edu.umd.cs.findbugs.BugReporter; 19 import edu.umd.cs.findbugs.Detector; 20 import edu.umd.cs.findbugs.SourceLineAnnotation; 21 import edu.umd.cs.findbugs.ba.CFG; 22 import edu.umd.cs.findbugs.ba.CFGBuilderException; 23 import edu.umd.cs.findbugs.ba.ClassContext; 24 import edu.umd.cs.findbugs.ba.DataflowAnalysisException; 25 import edu.umd.cs.findbugs.ba.Location; 26 import edu.umd.cs.findbugs.ba.type.NullType; 27 import edu.umd.cs.findbugs.ba.type.TopType; 28 import edu.umd.cs.findbugs.ba.type.TypeDataflow; 29 import edu.umd.cs.findbugs.ba.type.TypeFrame; 30 31 public class FindNonSerializableStoreIntoSession implements Detector { 32 33 private BugReporter bugReporter; 34 35 private static final boolean DEBUG = false; 36 37 public FindNonSerializableStoreIntoSession(BugReporter bugReporter) { 38 this.bugReporter = bugReporter; 39 } 40 41 public void visitClassContext(ClassContext classContext) { 42 Method[] methodList = classContext.getJavaClass().getMethods(); 43 44 for (Method method : methodList) { 45 if (method.getCode() == null) 46 continue; 47 48 try { 49 analyzeMethod(classContext, method); 50 } catch (CFGBuilderException e) { 51 bugReporter.logError("Detector " + this.getClass().getName() 52 + " caught exception", e); 53 } catch (DataflowAnalysisException e) { 54 } 56 } 57 } 58 59 private void analyzeMethod(ClassContext classContext, Method method) 60 throws CFGBuilderException, DataflowAnalysisException { 61 MethodGen methodGen = classContext.getMethodGen(method); 62 if (methodGen == null) 63 return; 64 BitSet bytecodeSet = classContext.getBytecodeSet(method); 65 if (bytecodeSet == null) return; 66 if (bytecodeSet.get(Constants.INSTANCEOF) || bytecodeSet.get(Constants.CHECKCAST)) 68 return; 69 CFG cfg = classContext.getCFG(method); 70 TypeDataflow typeDataflow = classContext.getTypeDataflow(method); 71 ConstantPoolGen cpg = classContext.getConstantPoolGen(); 72 73 String sourceFile = classContext.getJavaClass().getSourceFileName(); 74 if (DEBUG) { 75 String methodName = methodGen.getClassName() + "." 76 + methodGen.getName(); 77 System.out.println("Checking " + methodName); 78 } 79 80 for (Iterator <Location> i = cfg.locationIterator(); i.hasNext();) { 81 Location location = i.next(); 82 InstructionHandle handle = location.getHandle(); 83 Instruction ins = handle.getInstruction(); 84 85 if (!(ins instanceof INVOKEINTERFACE)) 86 continue; 87 88 INVOKEINTERFACE invoke = (INVOKEINTERFACE) ins; 89 String mName = invoke.getMethodName(cpg); 90 if (!mName.equals("setAttribute")) 91 continue; 92 String cName = invoke.getClassName(cpg); 93 if (!cName.equals("javax.servlet.http.HttpSession")) 94 continue; 95 96 TypeFrame frame = typeDataflow.getFactAtLocation(location); 97 if (!frame.isValid()) { 98 continue; 100 } 101 Type operandType = frame.getTopValue(); 102 103 if (operandType.equals(TopType.instance())) { 104 continue; 106 } 107 if (!(operandType instanceof ReferenceType)) { 108 continue; 110 } 111 ReferenceType refType = (ReferenceType) operandType; 112 113 if (refType.equals(NullType.instance())) { 114 continue; 115 } 116 String refSig = refType.getSignature(); 117 118 try { 119 120 double isSerializable = DeepSubtypeAnalysis.isDeepSerializable(refSig); 121 122 if (isSerializable < 0.9) { 123 SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation 124 .fromVisitedInstruction(classContext, methodGen, 125 sourceFile, handle); 126 127 bugReporter 128 .reportBug(new BugInstance( 129 this, 130 "J2EE_STORE_OF_NON_SERIALIZABLE_OBJECT_INTO_SESSION", 131 isSerializable < 0.15 ? HIGH_PRIORITY 132 : isSerializable > 0.5 ? LOW_PRIORITY 133 : NORMAL_PRIORITY) 134 .addClassAndMethod(methodGen, sourceFile) 135 .addClass(DeepSubtypeAnalysis.getComponentClass(refSig)) 136 .addSourceLine(sourceLineAnnotation) 137 ); 138 } 139 } catch (ClassNotFoundException e) { 140 } 142 } 143 } 144 145 public void report() { 146 } 147 148 } 149 | Popular Tags |