@Override protected InjectionPoint getInjectionPoint(InvokeInstruction invoke, ConstantPoolGen cpg, InstructionHandle handle) { assert invoke != null && cpg != null; String method = invoke.getMethodName(cpg); String sig = invoke.getSignature(cpg); if(method.equals("registerReceiver")){ if(sig.contains("Ljava/lang/String;")){ if(sig.contains(";I)")){ return new InjectionPoint(new int[]{2}, ANDROID_REGISTER_RECEIVER_TYPE); }else{ return new InjectionPoint(new int[]{1}, ANDROID_REGISTER_RECEIVER_TYPE); } } } return InjectionPoint.NONE; }
public void reportMatch(ClassContext classContext, Method method, ByteCodePatternMatch match) { MethodGen methodGen = classContext.getMethodGen(method); JavaClass javaClass = classContext.getJavaClass(); BindingSet bindingSet = match.getBindingSet(); // Note that the lookup of "h" cannot fail, and // it is guaranteed to be bound to a FieldVariable. Binding binding = bindingSet.lookup("h"); FieldVariable field = (FieldVariable) binding.getVariable(); // Ignore fields generated for accesses to Foo.class if (field.getFieldName().startsWith("class$")) return; // Find start and end instructions (for reporting source lines) InstructionHandle start = match.getLabeledInstruction("startDC"); InstructionHandle end = match.getLabeledInstruction("endDC"); String sourceFile = javaClass.getSourceFileName(); bugReporter.reportBug(new BugInstance(this, "BCPDC_DOUBLECHECK", NORMAL_PRIORITY) .addClassAndMethod(methodGen, sourceFile) .addField(field).describe("FIELD_ON") .addSourceLine(methodGen, sourceFile, start, end)); }
public void transfer(BasicBlock basicBlock, InstructionHandle end, Fact start, Fact result) throws DataflowAnalysisException { startTransfer(basicBlock, start); copy(start, result); if (isFactValid(result)) { Iterator<InstructionHandle> i = isForwards() ? basicBlock.instructionIterator() : basicBlock.instructionReverseIterator(); while (i.hasNext()) { InstructionHandle handle = i.next(); if (handle == end) break; if (DEBUG && end == null) System.out.print("Transfer " + handle); // Transfer the dataflow value transferInstruction(handle, basicBlock, result); if (DEBUG && end == null) System.out.println(" ==> " + result.toString()); } } endTransfer(basicBlock, end, result); }
public void transferInstruction(InstructionHandle handle, BasicBlock basicBlock, ValueNumberFrame fact) throws DataflowAnalysisException { Location location = new Location(handle, basicBlock); ValueNumberFrame atLocation = getFactAtLocation(location); copy(fact, atLocation); visitor.setFrame(fact); visitor.setHandle(handle); Instruction ins = handle.getInstruction(); ins.accept(visitor); ValueNumberFrame afterLocation = getFactAfterLocation(location); copy(fact, afterLocation); }
@Override protected InjectionPoint getInjectionPoint(InvokeInstruction invoke, ConstantPoolGen cpg, InstructionHandle handle) { assert invoke != null && cpg != null; String method = invoke.getMethodName(cpg); String sig = invoke.getSignature(cpg); if(sig.startsWith("(Ljava/lang/String;)")) { if(method.startsWith("set")) { // Targeting : x.setPassword("abc123") String methodLowerCase = method.toLowerCase(); for (String password : PASSWORD_WORDS) { if (methodLowerCase.contains(password)) { return new InjectionPoint(new int[]{0}, HARD_CODE_PASSWORD_TYPE); } } } else if(PASSWORD_WORDS.contains(method.toLowerCase())) { // Targeting : DSL().user("").password(String x) return new InjectionPoint(new int[]{0}, HARD_CODE_PASSWORD_TYPE); } } return InjectionPoint.NONE; }
public void transferInstruction(InstructionHandle handle, BasicBlock basicBlock, LockSet fact) throws DataflowAnalysisException { Instruction ins = handle.getInstruction(); short opcode = ins.getOpcode(); if (opcode == Constants.MONITORENTER || opcode == Constants.MONITOREXIT) { ValueNumberFrame frame = vnaDataflow.getFactAtLocation(new Location(handle, basicBlock)); // NOTE: if the CFG is pruned, there may be unreachable instructions, // so make sure frame is valid. if (frame.isValid()) { int lockNumber = frame.getTopValue().getNumber(); lockOp(fact, lockNumber, opcode == Constants.MONITORENTER ? 1 : -1); } } else if ((ins instanceof ReturnInstruction) && isSynchronized && !isStatic) { lockOp(fact, vna.getThisValue().getNumber(), -1); } }
public void transfer(BasicBlock basicBlock, InstructionHandle end, BlockType start, BlockType result) throws DataflowAnalysisException { result.copyFrom(start); if (start.isValid()) { if (basicBlock.isExceptionHandler()) { CodeExceptionGen exceptionGen = basicBlock.getExceptionGen(); ObjectType catchType = exceptionGen.getCatchType(); if (catchType == null) { // Probably a finally block, or a synchronized block // exception-compensation catch block. result.pushFinally(); } else { // Catch type was explicitly specified: // this is probably a programmer-written catch block result.pushCatch(); } } } }
@Override protected InjectionPoint getInjectionPoint(InvokeInstruction invoke, ConstantPoolGen cpg, InstructionHandle handle) { assert invoke != null && cpg != null; String method = invoke.getMethodName(cpg); String sig = invoke.getSignature(cpg); // System.out.println(sig); if(sig.contains("Ljava/lang/String;")) { if(method.contains("send") && method.contains("Broadcast") && !method.contains("Sticky")){ // System.out.println(method); if("sendOrderedBroadcastAsUser".equals(method)){ return new InjectionPoint(new int[]{5}, ANDROID_BROADCAST_TYPE); } if("sendOrderedBroadcast".equals(method) && sig.contains("Landroid/content/BroadcastReceiver;")){ return new InjectionPoint(new int[]{5}, ANDROID_BROADCAST_TYPE); } return new InjectionPoint(new int[]{0}, ANDROID_BROADCAST_TYPE); } } return InjectionPoint.NONE; }
/** * @see org.apache.bcel.classfile.Visitor#visitCode */ public void visitCode(Code aCode) { for (Iterator iter = mVisitors.iterator(); iter.hasNext();) { IDeepVisitor visitor = (IDeepVisitor) iter.next(); Visitor v = visitor.getClassFileVisitor(); aCode.accept(v); } // perform a deep visit final byte[] code = aCode.getCode(); final InstructionList list = new InstructionList(code); final Iterator it = list.iterator(); for (Iterator iter = list.iterator(); iter.hasNext();) { InstructionHandle instruction = (InstructionHandle) iter.next(); visitInstructionHandle(instruction); } }
/** * Constructs the instance and stores immutable values for reporting * * @param detector detctor for reporting * @param bugType reported bug type * @param originalPriority original priority (without sink confirmation) * @param classContext class with the sink * @param method method with the sink * @param instructionHandle instruction with the sink * @param sinkMethod called method (sink) * @throws NullPointerException if any argument is null */ public InjectionSink(Detector detector, String bugType, int originalPriority, ClassContext classContext, Method method, InstructionHandle instructionHandle, String sinkMethod) { Objects.requireNonNull(detector, "detector"); Objects.requireNonNull(bugType, "bugType"); Objects.requireNonNull(classContext, "classContext"); Objects.requireNonNull(method, "method"); Objects.requireNonNull(instructionHandle, "instructionHandle"); this.detector = detector; this.bugType = bugType; this.originalPriority = originalPriority; this.classContext = classContext; this.method = method; this.instructionHandle = instructionHandle; this.sinkMethod = (sinkMethod == null) ? "unknown" : sinkMethod; }
/** * Factory method for creating a source line annotation describing the * source line number for a visited instruction. * * @param methodGen the MethodGen object representing the method * @param handle the InstructionHandle containing the visited instruction * @return the SourceLineAnnotation, or null if we do not have line number information * for the instruction */ public static SourceLineAnnotation fromVisitedInstruction(MethodGen methodGen, String sourceFile, InstructionHandle handle) { LineNumberTable table = methodGen.getLineNumberTable(methodGen.getConstantPool()); String className = methodGen.getClassName(); int bytecodeOffset = handle.getPosition(); if (table == null) return createUnknown(className, sourceFile, bytecodeOffset, bytecodeOffset); int lineNumber = table.getSourceLine(handle.getPosition()); return new SourceLineAnnotation(className, sourceFile, lineNumber, lineNumber, bytecodeOffset, bytecodeOffset); }
/** * Factory method for creating a source line annotation describing * the source line numbers for a range of instruction in a method. * * @param methodGen the method * @param start the start instruction * @param end the end instruction (inclusive) */ public static SourceLineAnnotation fromVisitedInstructionRange(MethodGen methodGen, String sourceFile, InstructionHandle start, InstructionHandle end) { LineNumberTable lineNumberTable = methodGen.getLineNumberTable(methodGen.getConstantPool()); String className = methodGen.getClassName(); if (lineNumberTable == null) return createUnknown(className, sourceFile, start.getPosition(), end.getPosition()); int startLine = lineNumberTable.getSourceLine(start.getPosition()); int endLine = lineNumberTable.getSourceLine(end.getPosition()); return new SourceLineAnnotation(className, sourceFile, startLine, endLine, start.getPosition(), end.getPosition()); }
private void reportNullDeref(ClassContext classContext, Method method, InstructionHandle exceptionThrowerHandle, String type, int priority) { MethodGen methodGen = classContext.getMethodGen(method); String sourceFile = classContext.getJavaClass().getSourceFileName(); BugInstance bugInstance = new BugInstance(this, type, priority) .addClassAndMethod(methodGen, sourceFile) .addSourceLine(methodGen, sourceFile, exceptionThrowerHandle); if (DEBUG) bugInstance.addInt(exceptionThrowerHandle.getPosition()).describe("INT_BYTECODE_OFFSET"); bugReporter.reportBug(bugInstance); }
private void reportRedundantNullCheck(ClassContext classContext, Method method, InstructionHandle handle, RedundantBranch redundantBranch) { String sourceFile = classContext.getJavaClass().getSourceFileName(); MethodGen methodGen = classContext.getMethodGen(method); boolean redundantNullCheck = redundantBranch.redundantNullCheck; String type = redundantNullCheck ? "RCN_REDUNDANT_CHECKED_NULL_COMPARISION" : "RCN_REDUNDANT_COMPARISON_TO_NULL"; int priority = redundantNullCheck ? LOW_PRIORITY : NORMAL_PRIORITY; bugReporter.reportBug(new BugInstance(this, type, priority) .addClassAndMethod(methodGen, sourceFile) .addSourceLine(methodGen, sourceFile, handle)); }
/** * Add a source line annotation describing a range of instructions. * * @param methodGen the method * @param sourceFile source file the method is defined in * @param start the start instruction in the range * @param end the end instruction in the range (inclusive) * @return this object */ public BugInstance addSourceLine(MethodGen methodGen, String sourceFile, InstructionHandle start, InstructionHandle end) { // Make sure start and end are really in the right order. if (start.getPosition() > end.getPosition()) { InstructionHandle tmp = start; start = end; end = tmp; } SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstructionRange(methodGen, sourceFile, start, end); if (sourceLineAnnotation != null) add(sourceLineAnnotation); return this; }
public void transfer(BasicBlock basicBlock, InstructionHandle end, BitSet start, BitSet result) throws DataflowAnalysisException { // Start with intersection of dominators of predecessors copy(start, result); if (!isTop(result)) { // Every block dominates itself result.set(basicBlock.getId()); } }
public String instructionAnnotate(InstructionHandle handle, BasicBlock bb) { try { Fact result = analysis.getFactAtLocation(new Location(handle, bb)); return " " + analysis.factToString(result); } catch (DataflowAnalysisException e) { throw new IllegalStateException("Caught exception: " + e.toString()); } }
public void transferInstruction(InstructionHandle handle, BasicBlock basicBlock, StackDepth fact) throws DataflowAnalysisException { Instruction ins = handle.getInstruction(); int produced = ins.produceStack(cpg); int consumed = ins.consumeStack(cpg); if (produced == Constants.UNPREDICTABLE || consumed == Constants.UNPREDICTABLE) throw new IllegalStateException("Unpredictable stack delta for instruction: " + handle); int depth = fact.getDepth(); depth += (produced - consumed); if (depth < 0) fact.setDepth(BOTTOM); else fact.setDepth(depth); }
/** * Get the dataflow fact representing the point just after given Location. * Note "after" is meant in the logical sense, so for backward analyses, * after means before the location in the control flow sense. */ public Fact getFactAfterLocation(Location location) throws DataflowAnalysisException { BasicBlock basicBlock = location.getBasicBlock(); InstructionHandle handle = location.getHandle(); if (handle == basicBlock.getLastInstruction()) return getResultFact(basicBlock); else return getFactAtLocation(new Location(isForwards() ? handle.getNext() : handle.getPrev(), basicBlock)); }
public void print(PrintStream out) { Iterator<BasicBlock> i = cfg.blockIterator(); while (i.hasNext()) { BasicBlock bb = i.next(); out.println(); out.println("BASIC BLOCK: " + bb.getId() + (bb.isExceptionThrower() ? " [EXCEPTION THROWER]" : "") + blockStartAnnotate(bb)); if (bb.isExceptionThrower()) { out.println(" Exception thrower: " + bb.getExceptionThrower()); } CodeExceptionGen exceptionGen = bb.getExceptionGen(); if (exceptionGen != null) { System.out.println(" CATCHES " + exceptionGen.getCatchType()); } Iterator<InstructionHandle> j = instructionIterator(bb); while (j.hasNext()) { InstructionHandle handle = j.next(); out.println(handle + instructionAnnotate(handle, bb)); } out.println("END" + blockAnnotate(bb)); Iterator<Edge> edgeIter = isForwards ? cfg.outgoingEdgeIterator(bb) : cfg.incomingEdgeIterator(bb); while (edgeIter.hasNext()) { Edge edge = edgeIter.next(); out.println(" " + edge.formatAsString(!isForwards) + " " + edgeAnnotate(edge)); } } }
public void checkIntegrity() { // Ensure that basic blocks have only consecutive instructions for (Iterator<BasicBlock> i = blockIterator(); i.hasNext();) { BasicBlock basicBlock = i.next(); InstructionHandle prev = null; for (Iterator<InstructionHandle> j = basicBlock.instructionIterator(); j.hasNext();) { InstructionHandle handle = j.next(); if (prev != null && prev.getNext() != handle) throw new IllegalStateException("Non-consecutive instructions in block " + basicBlock.getId() + ": prev=" + prev + ", handle=" + handle); prev = handle; } } }
private void addHandler(InstructionHandle handle, CodeExceptionGen exceptionHandler) { List<CodeExceptionGen> handlerList = codeToHandlerMap.get(handle); if (handlerList == null) { handlerList = new LinkedList<CodeExceptionGen>(); codeToHandlerMap.put(handle, handlerList); } handlerList.add(exceptionHandler); }
/** * Get the successor of given instruction within the basic block. * @param handle the instruction * @return the instruction's successor, or null if the instruction * is the last in the basic block */ public InstructionHandle getSuccessorOf(InstructionHandle handle) { if (VERIFY_INTEGRITY) { if (!containsInstruction(handle)) throw new IllegalStateException(); } return handle == lastInstruction ? null : handle.getNext(); }
/** * Get the predecessor of given instruction within the basic block. * @param handle the instruction * @return the instruction's predecessor, or null if the instruction * is the first in the basic block */ public InstructionHandle getPredecessorOf(InstructionHandle handle) { if (VERIFY_INTEGRITY) { if (!containsInstruction(handle)) throw new IllegalStateException(); } return handle == firstInstruction ? null : handle.getPrev(); }
/** * Add an InstructionHandle to the basic block. * * @param handle the InstructionHandle */ public void addInstruction(InstructionHandle handle) { if (firstInstruction == null) { firstInstruction = lastInstruction = handle; } else { if (VERIFY_INTEGRITY && handle != lastInstruction.getNext()) throw new IllegalStateException("Adding non-consecutive instruction"); lastInstruction = handle; } }
@Override protected InjectionPoint getInjectionPoint(InvokeInstruction invoke, ConstantPoolGen cpg, InstructionHandle handle) { assert invoke != null && cpg != null; if(HASHTABLE_PUT_METHOD.matches(invoke,cpg) || HASHTABLE_SET_PROPERTY.matches(invoke,cpg)) { return new InjectionPoint(new int[]{0}, HARD_CODE_PASSWORD_TYPE); //Only the value is } return InjectionPoint.NONE; }
public InstructionHandle next() { if (!hasNext()) throw new NoSuchElementException(); InstructionHandle result = next; next = (result == last) ? null : next.getNext(); return result; }
public InstructionHandle next() throws NoSuchElementException { if (!hasNext()) throw new NoSuchElementException(); InstructionHandle result = next; next = (result == first) ? null : next.getPrev(); return result; }
/** * Return whether or not the basic block contains the given instruction. * * @param handle the instruction * @return true if the block contains the instruction, false otherwise */ public boolean containsInstruction(InstructionHandle handle) { Iterator<InstructionHandle> i = instructionIterator(); while (i.hasNext()) { if (i.next() == handle) return true; } return false; }
/** * Return whether or not the basic block contains the instruction * with the given bytecode offset. * * @param offset the bytecode offset * @return true if the block contains an instruction with the given offset, * false if it does not */ public boolean containsInstructionWithOffset(int offset) { Iterator<InstructionHandle> i = instructionIterator(); while (i.hasNext()) { if (i.next().getPosition() == offset) return true; } return false; }
public MatchResult match(InstructionHandle handle, ConstantPoolGen cpg, ValueNumberFrame before, ValueNumberFrame after, BindingSet bindingSet) throws DataflowAnalysisException { Instruction ins = handle.getInstruction(); if (!(ins instanceof NEW)) return null; LocalVariable result = new LocalVariable(after.getTopValue()); return addOrCheckDefinition(result, bindingSet); }
public MatchResult match(InstructionHandle handle, ConstantPoolGen cpg, ValueNumberFrame before, ValueNumberFrame after, BindingSet bindingSet) throws DataflowAnalysisException { // See if the instruction is an InvokeInstruction Instruction ins = handle.getInstruction(); if (!(ins instanceof InvokeInstruction)) return null; InvokeInstruction inv = (InvokeInstruction) ins; String methodName = inv.getMethodName(cpg); boolean isStatic = inv.getOpcode() == Constants.INVOKESTATIC; boolean isCtor = methodName.equals("<init>"); int actualMode = 0; if (isStatic) actualMode |= STATIC; if (isCtor) actualMode |= CONSTRUCTOR; if (!isStatic && !isCtor) actualMode |= INSTANCE; // Intersection of actual and desired modes must be nonempty. if ((actualMode & mode) == 0) return null; // Check class name, method name, and method signature. if (!methodNameMatcher.match(methodName) || !methodSigMatcher.match(inv.getSignature(cpg)) || !classNameMatcher.match(inv.getClassName(cpg))) return null; // It's a match! return new MatchResult(this, bindingSet); }
/** * Return Iterator over states representing dominated instructions * that continue the match. */ public Iterator<State> dominatedInstructionStateIterator() throws DataflowAnalysisException { if (!lookForDominatedInstruction()) throw new IllegalStateException(); LinkedList<State> stateList = new LinkedList<State>(); State dup = this.duplicate(); if (currentMatch != null) { // Find the referenced instruction. PatternElementMatch dominator = currentMatch.getFirstLabeledMatch(patternElement.getDominatedBy()); BasicBlock domBlock = dominator.getBasicBlock(); // Find all basic blocks dominated by the dominator block. for (Iterator<BasicBlock> i = cfg.blockIterator(); i.hasNext();) { BasicBlock block = i.next(); if (block == domBlock) continue; BitSet dominators = domAnalysis.getResultFact(block); if (dominators.get(domBlock.getId())) { // This block is dominated by the dominator block. // Each instruction in the block which matches the current pattern // element is a new state continuing the match. for (Iterator<InstructionHandle> j = block.instructionIterator(); j.hasNext();) { MatchResult matchResult = dup.matchLocation(new Location(j.next(), block)); if (matchResult != null) { stateList.add(dup); dup = this.duplicate(); } } } } } return stateList.iterator(); }
public MatchResult match(InstructionHandle handle, ConstantPoolGen cpg, ValueNumberFrame before, ValueNumberFrame after, BindingSet bindingSet) throws DataflowAnalysisException { // Instruction must be MONITORENTER. Instruction ins = handle.getInstruction(); if (!(ins instanceof MONITORENTER)) return null; // Ensure the object being locked matches any previous // instructions which bound our variable name to a value. Variable lock = new LocalVariable(before.getTopValue()); return addOrCheckDefinition(lock, bindingSet); }
public MatchResult match(InstructionHandle handle, ConstantPoolGen cpg, ValueNumberFrame before, ValueNumberFrame after, BindingSet bindingSet) throws DataflowAnalysisException { for (int i = 0; i < childList.length; ++i) { PatternElement child = childList[i]; MatchResult matchResult = child.match(handle, cpg, before, after, bindingSet); if (matchResult != null) return matchResult; } return null; }
/** * This method is used to track calls made on a specific object. For instance, this could be used to track if "setHttpOnly(true)" * was executed on a specific cookie object. * * This allows the detector to find interchanged calls like this * * Cookie cookie1 = new Cookie("f", "foo"); <- This cookie is unsafe * Cookie cookie2 = new Cookie("b", "bar"); <- This cookie is safe * cookie1.setHttpOnly(false); * cookie2.setHttpOnly(true); * * @param cpg ConstantPoolGen * @param startLocation The Location of the cookie initialization call. * @param objectStackLocation The index of the cookie on the stack. * @param invokeInstruction The instruction we want to detect.s * @return The location of the invoke instruction provided for the cookie at a specific index on the stack. */ private Location getCookieInstructionLocation(ConstantPoolGen cpg, Location startLocation, int objectStackLocation, String invokeInstruction) { Location location = startLocation; InstructionHandle handle = location.getHandle(); int loadedStackValue = 0; // Loop until we find the setSecure call for this cookie while (handle.getNext() != null) { handle = handle.getNext(); Instruction nextInst = handle.getInstruction(); // We check if the index of the cookie used for this invoke is the same as the one provided if (nextInst instanceof ALOAD) { ALOAD loadInst = (ALOAD)nextInst; loadedStackValue = loadInst.getIndex(); } if (nextInst instanceof INVOKEVIRTUAL && loadedStackValue == objectStackLocation) { INVOKEVIRTUAL invoke = (INVOKEVIRTUAL) nextInst; String methodNameWithSignature = invoke.getClassName(cpg) + "." + invoke.getMethodName(cpg); if (methodNameWithSignature.equals(invokeInstruction)) { Integer val = ByteCode.getConstantInt(handle.getPrev()); if (val != null && val == TRUE_INT_VALUE) { return new Location(handle, location.getBasicBlock()); } } } } return null; }
/** * Deep visit of an InstructionHandle * @param aInstruction the InstructionHandle */ private void visitInstructionHandle(InstructionHandle aInstruction) { for (Iterator iter = mVisitors.iterator(); iter.hasNext();) { final IDeepVisitor visitor = (IDeepVisitor) iter.next(); org.apache.bcel.generic.Visitor v = visitor.getGenericVisitor(); aInstruction.accept(v); } }
@Override protected InjectionPoint getInjectionPoint(InvokeInstruction invoke, ConstantPoolGen cpg, InstructionHandle handle) { assert invoke != null && cpg != null; //1. Verify if the class used has a known sink String fullMethodName = getFullMethodName(invoke, cpg); //This will skip the most common lookup if ("java/lang/Object.<init>()V".equals(fullMethodName)) { return InjectionPoint.NONE; } InjectionPoint injectionPoint = injectionMap.get(fullMethodName); if (injectionPoint != null) { return injectionPoint; } try { //2. Verify if the super classes match a known sink JavaClass classDef = Repository.lookupClass(invoke.getClassName(cpg)); for (JavaClass superClass : classDef.getSuperClasses()) { if ("java.lang.Object".equals(superClass.getClassName())) { continue; } String superClassFullMethodName = superClass.getClassName().replace('.','/') + "." + invoke.getMethodName(cpg) + invoke.getSignature(cpg); injectionPoint = injectionMap.get(superClassFullMethodName); if (injectionPoint != null) { return injectionPoint; } } } catch (ClassNotFoundException e) { AnalysisContext.reportMissingClass(e); } return InjectionPoint.NONE; }
@Override protected void analyzeLocation(ClassContext classContext, Method method, InstructionHandle handle, ConstantPoolGen cpg, InvokeInstruction invoke, TaintFrame fact, String currentMethod) throws DataflowAnalysisException { SourceLineAnnotation sourceLine = SourceLineAnnotation.fromVisitedInstruction(classContext, method, handle); checkSink(cpg, invoke, fact, sourceLine, currentMethod); InjectionPoint injectionPoint = getInjectionPoint(invoke, cpg, handle); for (int offset : injectionPoint.getInjectableArguments()) { int priority = getPriorityFromTaintFrame(fact, offset); if (priority == Priorities.IGNORE_PRIORITY) { continue; } Taint parameterTaint = fact.getStackValue(offset); InjectionSink injectionSink = new InjectionSink(this, injectionPoint.getBugType(), priority, classContext, method, handle, injectionPoint.getInjectableMethod()); injectionSink.addLines(parameterTaint.getAllLocations()); injectionSink.addUnknownSources(parameterTaint.getUnknownLocations()); if (parameterTaint.hasParameters()) { // add sink to multi map Set<InjectionSink> sinkSet = injectionSinks.get(currentMethod); if (sinkSet == null) { sinkSet = new HashSet<InjectionSink>(); } assert !sinkSet.contains(injectionSink) : "duplicate sink"; sinkSet.add(injectionSink); injectionSinks.put(currentMethod, sinkSet); sinkTaints.put(new MethodAndSink(currentMethod, injectionSink), parameterTaint); } else { // sink cannot be influenced by other methods calls, so report it immediately bugReporter.reportBug(injectionSink.generateBugInstance(true)); } return; } }
@Override protected InjectionPoint getInjectionPoint(InvokeInstruction invoke, ConstantPoolGen cpg, InstructionHandle handle) { InjectionPoint injectionPoint = null; for (InjectionSource source : getInjectionSource()) { injectionPoint = source.getInjectableParameters(invoke, cpg, handle); if (injectionPoint != InjectionPoint.NONE) { break; } } if (injectionPoint == null || injectionPoint == InjectionPoint.NONE) { injectionPoint = super.getInjectionPoint(invoke, cpg, handle); } return injectionPoint; }