@Override public void visitLDC(LDC ldc) { Taint taint = new Taint(Taint.State.SAFE); Object value = ldc.getValue(cpg); if (value instanceof String) { taint.setConstantValue((String) value); } if (FindSecBugsGlobalConfig.getInstance().isDebugTaintState()) { if (value instanceof String) { taint.setDebugInfo("\"" + value + "\""); } else { taint.setDebugInfo("LDC " + ldc.getType(cpg).getSignature()); } } getFrame().pushValue(taint); }
private void analyzeMethod(Method m, ClassContext classContext) throws CFGBuilderException, DataflowAnalysisException { ConstantPoolGen cpg = classContext.getConstantPoolGen(); CFG cfg = classContext.getCFG(m); for (Iterator<Location> i = cfg.locationIterator(); i.hasNext(); ) { Location location = i.next(); Instruction inst = location.getHandle().getInstruction(); if (inst instanceof LDC) { LDC ldc = (LDC) inst; if (ldc != null) { if("java.naming.security.authentication".equals(ldc.getValue(cpg)) && "none".equals(ByteCode.getConstantLDC(location.getHandle().getNext(), cpg, String.class))){ JavaClass clz = classContext.getJavaClass(); bugReporter.reportBug(new BugInstance(this, LDAP_ANONYMOUS, Priorities.LOW_PRIORITY) // .addClass(clz) .addMethod(clz, m) .addSourceLine(classContext, m, location)); break; } } } } }
private StringAppendState updateStringAppendState(Location location, ConstantPoolGen cpg, StringAppendState stringAppendState) { InstructionHandle handle = location.getHandle(); Instruction ins = handle.getInstruction(); if (!isConstantStringLoad(location, cpg)) { throw new IllegalArgumentException("instruction must be LDC"); } LDC load = (LDC) ins; Object value = load.getValue(cpg); String stringValue = ((String) value).trim(); if (stringValue.startsWith(",") || stringValue.endsWith(",")) stringAppendState.setSawComma(handle); if (isCloseQuote(stringValue) && stringAppendState.getSawOpenQuote(handle)) stringAppendState.setSawCloseQuote(handle); if (isOpenQuote(stringValue)) stringAppendState.setSawOpenQuote(handle); return stringAppendState; }
private boolean isSafeValue(Location location, ConstantPoolGen cpg) throws CFGBuilderException { Instruction prevIns = location.getHandle().getInstruction(); if (prevIns instanceof LDC || prevIns instanceof GETSTATIC) return true; if (prevIns instanceof InvokeInstruction) { String methodName = ((InvokeInstruction) prevIns).getMethodName(cpg); if (methodName.startsWith("to") && methodName.endsWith("String") && methodName.length() > 8) return true; } if (prevIns instanceof AALOAD) { CFG cfg = classContext.getCFG(method); Location prev = getPreviousLocation(cfg, location, true); if (prev != null) { Location prev2 = getPreviousLocation(cfg, prev, true); if (prev2 != null && prev2.getHandle().getInstruction() instanceof GETSTATIC) { GETSTATIC getStatic = (GETSTATIC) prev2.getHandle().getInstruction(); if (getStatic.getSignature(cpg).equals("[Ljava/lang/String;")) return true; } } } return false; }
@Override public void visitLDC(LDC obj) { Object constantValue = obj.getValue(cpg); ValueNumber value; if (constantValue instanceof ConstantClass) { ConstantClass constantClass = (ConstantClass) constantValue; String className = constantClass.getBytes(cpg.getConstantPool()); value = factory.getClassObjectValue(className); } else { value = constantValueMap.get(constantValue); if (value == null) { value = factory.createFreshValue(ValueNumber.CONSTANT_VALUE); constantValueMap.put(constantValue, value); // Keep track of String constants if (constantValue instanceof String) { stringConstantMap.put(value, (String) constantValue); } } } getFrame().pushValue(value); }
/** * Return whether or not the given instruction can throw exceptions. * * @param handle * the instruction * @return true if the instruction can throw an exception, false otherwise */ private boolean isPEI(InstructionHandle handle) { Instruction ins = handle.getInstruction(); if (!(ins instanceof ExceptionThrower)) return false; if (ins instanceof NEW) return false; // if (ins instanceof ATHROW) return false; if (ins instanceof GETSTATIC) return false; if (ins instanceof PUTSTATIC) return false; if (ins instanceof ReturnInstruction) return false; if (ins instanceof INSTANCEOF) return false; if (ins instanceof MONITOREXIT) return false; if (ins instanceof LDC) return false; return true; }
/** Checks if the constraints of operands of the said instruction(s) are satisfied. */ // LDC and LDC_W (LDC_W is a subclass of LDC in BCEL's model) public void visitLDC(LDC o){ indexValid(o, o.getIndex()); Constant c = cpg.getConstant(o.getIndex()); if (c instanceof ConstantClass){ addMessage("Operand of LDC or LDC_W is CONSTANT_Class '"+c+"' - this is only supported in JDK 1.5 and higher."); } else{ if (! ( (c instanceof ConstantInteger) || (c instanceof ConstantFloat) || (c instanceof ConstantString) ) ){ constraintViolated(o, "Operand of LDC or LDC_W must be one of CONSTANT_Integer, CONSTANT_Float or CONSTANT_String, but is '"+c+"'."); } } }
/** * <<GET_IMODEL(THIS)>> * LDC className * INVOKEINTERFACE createObject */ @Override public void genCreate(Create c, GenScope scope) { InstructionList il = scope.getInstructionList(); InstructionFactory ifact = scope.getInstructionFactory(); ConstantPoolGen cpg = scope.getConstantPool(); // generate model access scope.generateGetModel(modelName); // CommonGen.generateGetModel(modelName, il, ifact, scope.getTransformationContext() ); // push className il.append(new LDC(cpg.addString(c.getClassName()))); // invoke il.append(ifact.createInvoke(DefaultTypes.IModel.getClassName(), "createObject", Type.OBJECT, new Type[] { Type.STRING }, DefaultTypes.IModelCall)); }
private void analyzeMethod(Method m, ClassContext classContext) throws CFGBuilderException{ JavaClass clazz = classContext.getJavaClass(); ConstantPoolGen cpg = classContext.getConstantPoolGen(); CFG cfg = classContext.getCFG(m); for (Iterator<Location> i = cfg.locationIterator(); i.hasNext(); ) { Location loc = i.next(); Instruction inst = loc.getHandle().getInstruction(); if (inst instanceof INVOKEVIRTUAL) { INVOKEVIRTUAL invoke = (INVOKEVIRTUAL)inst; if( "java.lang.StringBuilder".equals(invoke.getClassName(cpg)) && "append".equals(invoke.getMethodName(cpg))) { Instruction prev = loc.getHandle().getPrev().getInstruction(); if (prev instanceof LDC) { LDC ldc = (LDC)prev; Object value = ldc.getValue(cpg); if (value instanceof String) { String v = (String)value; if ("redirect:".equals(v)) { BugInstance bug = new BugInstance(this, SPRING_UNVALIDATED_REDIRECT_TYPE, Priorities.NORMAL_PRIORITY); bug.addClass(clazz).addMethod(clazz,m).addSourceLine(classContext,m,loc); reporter.reportBug(bug); } } } } } } }
private void analyzeMethod(Method m, ClassContext classContext) throws CFGBuilderException, DataflowAnalysisException { ConstantPoolGen cpg = classContext.getConstantPoolGen(); CFG cfg = classContext.getCFG(m); for (Iterator<Location> i = cfg.locationIterator(); i.hasNext(); ) { Location location = i.next(); Instruction inst = location.getHandle().getInstruction(); if (inst instanceof INVOKEINTERFACE) { INVOKEINTERFACE invoke = (INVOKEINTERFACE) inst; String methodName = invoke.getMethodName(cpg); String className = invoke.getClassName(cpg); if (className.equals("javax.servlet.http.HttpServletResponse") && (methodName.equals("addHeader") || methodName.equals("setHeader"))) { LDC ldc = ByteCode.getPrevInstruction(location.getHandle().getPrev(), LDC.class); if (ldc != null) { String headerValue = ByteCode.getConstantLDC(location.getHandle().getPrev(), cpg, String.class); if ("Access-Control-Allow-Origin".equalsIgnoreCase((String)ldc.getValue(cpg)) && (headerValue.contains("*") || "null".equalsIgnoreCase(headerValue))) { JavaClass clz = classContext.getJavaClass(); bugReporter.reportBug(new BugInstance(this, PERMISSIVE_CORS, Priorities.HIGH_PRIORITY) .addClass(clz) .addMethod(clz, m) .addSourceLine(classContext, m, location)); } } } } } }
void generateReadCode(InstructionList il, InstructionFactory factory, ConstantPoolGen cp) { il.append(new LDC(cp.addString(name))); il.append(factory.createInvoke("org.dianahep.root4j.core.RootInput", "readObject", rootObjectType, new Type[] { Type.STRING }, INVOKEINTERFACE)); il.append(factory.createCast(rootObjectType, getJavaType())); }
@Override public void visitLDC(LDC obj) { Type type = obj.getType(getCPG()); if (isString(type)) { Object value = obj.getValue(getCPG()); if (value instanceof String && ((String)value).length() == 0) pushValue( emptyStringTypeInstance); else pushValue( staticStringTypeInstance); } else pushValue(type); }
private boolean isConstantStringLoad(Location location, ConstantPoolGen cpg) { Instruction ins = location.getHandle().getInstruction(); if (ins instanceof LDC) { LDC load = (LDC) ins; Object value = load.getValue(cpg); if (value instanceof String) { return true; } } return false; }
private void registerInstructionSources() throws DataflowAnalysisException { for (Iterator<Location> i = cfg.locationIterator(); i.hasNext();) { Location location = i.next(); Instruction instruction = location.getHandle().getInstruction(); short opcode = instruction.getOpcode(); int produces = instruction.produceStack(cpg); if (instruction instanceof InvokeInstruction) { // Model return value registerReturnValueSource(location); } else if (opcode == Constants.GETFIELD || opcode == Constants.GETSTATIC) { // Model field loads registerFieldLoadSource(location); } else if (instruction instanceof LDC) { // Model constant values registerLDCValueSource(location); } else if (instruction instanceof LDC2_W) { // Model constant values registerLDC2ValueSource(location); } else if (instruction instanceof ConstantPushInstruction) { // Model constant values registerConstantPushSource(location); } else if (instruction instanceof ACONST_NULL) { // Model constant values registerPushNullSource(location); } else if ((produces == 1 || produces == 2) && !(instruction instanceof LocalVariableInstruction) && !(instruction instanceof CHECKCAST)){ // Model other sources registerOtherSource(location); } } }
public void generateGetModel(String modelName, InstructionList il, InstructionFactory ifact, GenScope scope) { generateGetModelManager(il, ifact, scope.getTransformationContext(), scope); il.append( new LDC(ifact.getConstantPool().addString(modelName)) ); il.append(ifact.createInvoke(DefaultTypes.ModelManager.getClassName(), "getNamespace", DefaultTypes.IModel, new Type[] { Type.STRING }, Constants.INVOKEVIRTUAL)); }
/** * <<GET_IMODEL(THIS)>> * ALOAD !!#receptor_variable!! * LDC <<featureName>> * ALOAD !!#value_variable!! * INVOKEINTERFACE setFeature */ @Override public void genSet(Set s, GenScope scope) { InstructionList il = scope.getInstructionList(); InstructionFactory ifact = scope.getInstructionFactory(); ConstantPoolGen cpg = scope.getConstantPool(); Variable realReceptor = scope.getRealVariable(s.getReceptor()); Variable realValue = scope.getRealVariable(s.getValue()); // push IModel (generate model access) scope.generateGetModel(s.getReceptor()); // push receptor scope.loadVariable(realReceptor, il); // push featureName il.append(new LDC(cpg.addString(s.getFeatureName()))); // push value scope.loadVariable(realValue, il); // invoke setFeature il.append(ifact.createInvoke(DefaultTypes.IModel.getClassName(), "setFeature", Type.VOID, new Type[] { Type.OBJECT, Type.STRING, Type.OBJECT }, DefaultTypes.IModelCall)); }
/** * A new IdcMetaclass object is created to wrap de * real metaclass providing additional functionality. * * <pre> * NEW IdcMetaclass * DUP * LDC <<model_name>> * LDC <<class_name>> * INVOKESPECIAL IdcMetaclass.<init> * ASTORE !!#variable!! * </pre> */ @Override public void generate(GenScope scope) { InstructionList il = scope.getInstructionList(); InstructionFactory ifact = scope.getInstructionFactory(); ConstantPoolGen cpg = scope.getConstantPool(); LocalVariableGen lvg = null; if ( getKind() == ReadMetaKind.METACLASS) { lvg = scope.newLocalVariable(this, DefaultTypes.IdcMetaclass); lvg.setStart(il.append(ifact.createNew(DefaultTypes.IdcMetaclass))); il.append(new DUP()); // il.append(new LDC(cpg.addString(getModel().getName()))); scope.generateGetTransformation(); scope.generateGetModel(getModel().getName()); // CommonGen.generateGetModel(getModel().getName(), il, ifact, scope); il.append(new LDC(cpg.addString(getClassName()))); il.append(ifact.createInvoke(DefaultTypes.IdcMetaclass.getClassName(), "<init>", Type.VOID, new Type[] { DefaultTypes.IdcTransformation, DefaultTypes.IModel, Type.STRING }, Constants.INVOKESPECIAL)); } else if ( getKind() == ReadMetaKind.THIS_TRANSFORMATION_OBJECT || getKind() == ReadMetaKind.THIS_TRANSFORMATION_METHOD_HANDLER ) { lvg = scope.newLocalVariable(this, DefaultTypes.IdcTransformation); lvg.setStart(il.append(InstructionConstants.NOP)); scope.generateGetTransformation(); } else if ( getKind() == ReadMetaKind.MODEL ){ lvg = scope.newLocalVariable(this, DefaultTypes.IModel); lvg.setStart(il.append(InstructionConstants.NOP)); scope.generateGetModel(getModel().getName()); } else { throw new IllegalArgumentException(); } il.append(new ASTORE(lvg.getIndex())); }
@Override public void sawOpcode(int seen) { if (seen != Constants.INVOKEVIRTUAL) { return; } String fullClassName = getClassConstantOperand(); String method = getNameConstantOperand(); //The method call is doing XML parsing (see class javadoc) if (fullClassName.equals("javax/xml/stream/XMLInputFactory") && method.equals("createXMLStreamReader")) { ClassContext classCtx = getClassContext(); ConstantPoolGen cpg = classCtx.getConstantPoolGen(); CFG cfg; try { cfg = classCtx.getCFG(getMethod()); } catch (CFGBuilderException e) { AnalysisContext.logError("Cannot get CFG", e); return; } for (Iterator<Location> i = cfg.locationIterator(); i.hasNext();) { Location location = i.next(); Instruction inst = location.getHandle().getInstruction(); //DTD disallow //XMLInputFactory.setProperty if (inst instanceof org.apache.bcel.generic.INVOKEVIRTUAL) { InvokeInstruction invoke = (InvokeInstruction) inst; if ("setProperty".equals(invoke.getMethodName(cpg))) { org.apache.bcel.generic.LDC loadConst = ByteCode.getPrevInstruction(location.getHandle(), LDC.class); if (loadConst != null) { if (PROPERTY_SUPPORT_DTD.equals(loadConst.getValue(cpg)) || PROPERTY_IS_SUPPORTING_EXTERNAL_ENTITIES.equals(loadConst.getValue(cpg))){ InstructionHandle prev1 = location.getHandle().getPrev(); InstructionHandle prev2 = prev1.getPrev(); //Case where the boolean is wrapped like : Boolean.valueOf(true) : 2 instructions if (invokeInstruction().atClass("java.lang.Boolean").atMethod("valueOf").matches(prev1.getInstruction(),cpg)) { if (prev2.getInstruction() instanceof ICONST) { Integer valueWrapped = ByteCode.getConstantInt(prev2); if (valueWrapped != null && valueWrapped.equals(0)) { //Value is false return; //Safe feature is disable } } } //Case where the boolean is declared as : Boolean.FALSE else if (prev1.getInstruction() instanceof org.apache.bcel.generic.GETSTATIC) { org.apache.bcel.generic.GETSTATIC getstatic = (org.apache.bcel.generic.GETSTATIC) prev1.getInstruction(); if (getstatic.getClassType(cpg).getClassName().equals("java.lang.Boolean") && getstatic.getFieldName(cpg).equals("FALSE")) { return; } } } } } } } //Raise a bug bugReporter.reportBug(new BugInstance(this, XXE_XMLSTREAMREADER_TYPE, Priorities.NORMAL_PRIORITY) // .addClass(this).addMethod(this).addSourceLine(this)); } }
@Override public void run() { String args[] = EntryPoint.getArgs(); String inputJarFileName = args[0]; String outputSrgMappingsFileName = args[1]; try ( PrintWriter outputSrgMappingWriter = new PrintWriter(outputSrgMappingsFileName); JarFile inputJarFile = new JarFile(inputJarFileName) ) { for (JarEntry jarEntry : new EnumerationIterator<>(inputJarFile.entries())) { if (jarEntry.isDirectory() || !jarEntry.getName().endsWith(".class")) { continue; } String original = Utils.stripClassEnding(jarEntry.getName()); JavaClass clazz = new ClassParser(inputJarFile.getInputStream(jarEntry), original).parse(); if (clazz.isEnum()) { Method staticInit = getCLInit(clazz); //skip enums with no static init method if (staticInit == null) { continue; } ConstantPoolGen cpGen = new ClassGen(clazz).getConstantPool(); MethodGen methodGen = new MethodGen(staticInit, clazz.getClassName(), cpGen); Iterator<Instruction> instrIter = Arrays.asList(methodGen.getInstructionList().getInstructions()).iterator(); while (instrIter.hasNext()) { //first goes NEW Instruction instr = instrIter.next(); if (!(instr instanceof NEW)) { break; } //but it may actually be another new, so we check if it is for enum constant if (!((NEW) instr).getLoadClassType(cpGen).getClassName().equals(clazz.getClassName())) { break; } //then goes dup, skip it instrIter.next(); //LDC with our real enum name String realName = (String) ((LDC) instrIter.next()).getValue(cpGen); //now skip everything, until we reach invokespecial with <init> for this enum field while (true) { Instruction nextInstr = instrIter.next(); if (nextInstr instanceof INVOKESPECIAL) { INVOKESPECIAL ispecial = ((INVOKESPECIAL) nextInstr); if (ispecial.getMethodName(cpGen).equals("<init>") && (ispecial.getClassName(cpGen).equals(clazz.getClassName()))) { break; } } } //next is putstatic with our obufscated field name PUTSTATIC putstatic = (PUTSTATIC) instrIter.next(); String obfName = putstatic.getFieldName(cpGen); //now print the mapping outputSrgMappingWriter.println(MappingUtils.createSRG(clazz.getClassName(), obfName, realName)); } } } } catch (Throwable t) { t.printStackTrace(); } }
@Override public void visitLDC(LDC obj) { Object value = obj.getValue(getCPG()); Constant c = new Constant(value); getFrame().pushValue(c); }
private void registerLDCValueSource(Location location) throws DataflowAnalysisException { LDC instruction = (LDC) location.getHandle().getInstruction(); Object constantValue = instruction.getValue(cpg); registerConstantSource(location, constantValue); }
@Override public void visitLDC(LDC obj) { produce(IsNullValue.nonNullValue()); }
public void visitLDC( LDC i ) { createConstant(i.getValue(_cp)); }
/** * <<GET_IMODEL(THIS)>> * ALOAD !!#receptor_variable!! * LDC <<featureName>> * INVOKEINTERFACE getFeature */ @Override public void generate(GenScope scope) { InstructionList il = scope.getInstructionList(); InstructionFactory ifact = scope.getInstructionFactory(); ConstantPoolGen cpg = scope.getConstantPool(); Variable realReceptor = scope.getRealVariable(this.receptor); LocalVariableGen lvg = scope.newLocalVariable(this, Type.OBJECT); // generate model access scope.generateGetModel(realReceptor); il.append(new DUP()); // for later calls of get/method calls (problem if I put the generateGetModel directly, not using the dup optimize, why?) // push receptor // push featureName scope.loadVariable(realReceptor, il); lvg.setStart(il.append(new LDC(cpg.addString(featureName)))); if ( kind == GetKind.PLAIN_GET ) { appendGetFeature(il, ifact); il.append(InstructionFactory.SWAP); il.append(InstructionFactory.POP); // I should swap, and then pop... // il.append(new POP()); } else { BranchInstruction branchToCall = InstructionFactory .createBranchInstruction(Constants.IFEQ, null); BranchInstruction branchToEnd = InstructionFactory .createBranchInstruction(Constants.GOTO, null); // hasFeature(f) // ifeq (jump if value == 0) appendHasFeature(il, ifact); lvg.setStart(il.append(branchToCall)); // push receptor // push featureName // get & jump to the end /* scope.loadVariable(realReceptor, il); lvg.setStart(il.append(new LDC(cpg.addString(featureName)))); */ if ( isStreamingMode(scope) ) { appendContinuableGetFeature(scope, realReceptor, il, ifact, cpg); } else { scope.loadVariable(realReceptor, il); il.append(new LDC(cpg.addString(featureName))); appendGetFeature(il, ifact); // branchToEnd.setTarget(appendGetFeature(il, ifact)); } il.append(branchToEnd); // push receptor // push featureName // methodCall branchToCall.setTarget( il.append(InstructionConstants.NOP) ); // label for this part //scope.loadVariable(realReceptor, il); // lvg.setStart(il.append(new LDC(cpg.addString(featureName)))); lvg.setStart(il.append(InstructionConstants.POP)); // remove IModel appendMethodCall(scope, il, ifact); // NOP-end branchToEnd.setTarget( il.append(InstructionConstants.NOP) ); } // store result il.append(new ASTORE( lvg.getIndex() )); }
@Override public void generate(GenScope scope) { InstructionList il = scope.getInstructionList(); InstructionFactory ifact = scope.getInstructionFactory(); ConstantPoolGen cpg = scope.getConstantPool(); LocalVariableGen lvg = scope.newLocalVariable(this, Type.OBJECT); switch (kind.getValue()) { case LiteralKind.BOOLEAN_VALUE: if (getBooleanValue()) { il.append(InstructionConstants.ICONST_1); } else { il.append(InstructionConstants.ICONST_0); } il.append(ifact.createInvoke(Boolean.class.getName(), "valueOf", new ObjectType(Boolean.class.getName()), new Type[] { Type.BOOLEAN }, Constants.INVOKESTATIC)); break; case LiteralKind.STRING_VALUE: lvg.setStart(il.append(new LDC(cpg.addString(getStringValue())))); break; case LiteralKind.NULL_VALUE: lvg.setStart(il.append(InstructionConstants.ACONST_NULL)); break; case LiteralKind.INTEGER_VALUE: //lvg.setStart(il.append(new LDC(cpg.addInteger(intValue)))); //il.append(new LDC(cpg.addInteger(intValue))); il.append(ifact.createConstant(intValue)); il.append(ifact.createInvoke(Integer.class.getName(), "valueOf", new ObjectType(Integer.class.getName()), new Type[] { Type.INT }, Constants.INVOKESTATIC)); break; case LiteralKind.DOUBLE_VALUE: //lvg.setStart(il.append(new LDC(cpg.addDouble(doubleValue)))); lvg.setStart(il.append(ifact.createConstant(doubleValue))); il.append(ifact.createInvoke(Double.class.getName(), "valueOf", new ObjectType(Double.class.getName()), new Type[] { Type.DOUBLE }, Constants.INVOKESTATIC)); break; default: throw new IdcException("Not supported literal"); // break; } il.append(new ASTORE(lvg.getIndex())); }