@Test public void abuseWeaknessNoNamespaceIdTest() throws Exception { SoapTestDocument soap = new SoapTestDocument(); Document doc = soap.getDocument(); Element signed = soap.getDummyPayloadBody(); String id = "signed"; Attr idAttr = doc.createAttribute("ID"); idAttr.setTextContent(id); signed.setAttributeNode(idAttr); Element payload = (Element) signed.cloneNode(true); soap.getHeader().appendChild(payload); String xpath = "/soapenv:Envelope//*[@ID='" + id + "']"; log.info("Using XPath: " + xpath); AbsoluteLocationPath abs = new AbsoluteLocationPath(xpath); Step step = abs.getRelativeLocationPaths().get(2); XPathAttributeWeaknessPostProcess aw = new XPathAttributeWeaknessPostProcess(step); assertEquals(3, aw.getNumberOfPossibilities()); Attr sa, pa; aw.abuseWeakness(0, new SignedElement(signed, null), new PayloadElement(payload, null)); log.info("abuseWeakness(0, signed, payload)\n" + domToString(doc, true)); sa = signed.getAttributeNode("ID"); pa = payload.getAttributeNode("ID"); assertNotNull(sa); assertNotNull(pa); assertEquals(sa.getTextContent(), id); assertFalse(pa.getTextContent().isEmpty()); assertFalse(pa.getTextContent().equals(id)); assertFalse(sa.getTextContent().equals(pa.getTextContent())); aw.abuseWeakness(2, new SignedElement(signed, null), new PayloadElement(payload, null)); log.info("abuseWeakness(2, signed, payload)\n" + domToString(doc, true)); sa = signed.getAttributeNode("ID"); pa = payload.getAttributeNode("ID"); assertNotNull(sa); assertNotNull(pa); assertEquals(sa.getTextContent(), id); assertFalse(pa.getTextContent().isEmpty()); assertEquals(sa.getTextContent(), pa.getTextContent()); aw.abuseWeakness(1, new SignedElement(signed, null), new PayloadElement(payload, null)); log.info("abuseWeakness(1, signed, payload)\n" + domToString(doc, true)); sa = signed.getAttributeNode("ID"); pa = payload.getAttributeNode("ID"); assertNotNull(sa); assertNull(pa); assertEquals(sa.getTextContent(), id); }
/** * Validates if the given XPath follows the FastXPath grammar but without prefixes. This is known * to be most secure. * * @return */ public boolean isPrefixfreeTransformedFastXPath() { for (Step step : xpath.getRelativeLocationPaths()) { if (!step.getAxisSpecifier().getAxisName().toFullString().equals("child")) { return false; } if (step.getAxisSpecifier().getNodeName() != null) { return false; } if (step.getAxisSpecifier().getNodeType() == null) { return false; } if (!step.getAxisSpecifier().getNodeType().getNodeTypeName().equals("node")) { return false; } List<Predicate> predicates = step.getPredicates(); if (predicates.isEmpty() || predicates.size() > 3) { return false; } int positions = 0; int attributes = 0; int ln = 0; int uri = 0; for (Predicate pred : step.getPredicates()) { if (pred.getOrExpressions().size() != 1) { return false; } if (pred.getOrExpressions().get(0).getAndExpressions().size() != 1) { List<AndExpression> andExpressions = pred.getOrExpressions().get(0).getAndExpressions(); if (andExpressions.size() > 2 || andExpressions.size() < 1) { return false; } for (AndExpression and : andExpressions) { if (and instanceof LocalNameAndExpression) { ++ln; } else if (and instanceof NamespaceUriAndExpression) { ++uri; } } } else { AndExpression and = pred.getOrExpressions().get(0).getAndExpressions().get(0); if (and instanceof PositionAndExpression) { ++positions; } else if (and instanceof AttributeAndExpression) { ++attributes; } } } if (ln != 1 || uri != 1 || positions > 1 || attributes > 1 || (attributes + positions) == 0) { return false; } } return true; }
/** * Validates if the given XPath follows the FastXPath grammar. These are known to be fast and only * vulnerable to namespace injection. * * @return */ public boolean isFastXPath() { for (Step step : xpath.getRelativeLocationPaths()) { if (!step.getAxisSpecifier().getAxisName().toFullString().equals("child")) { return false; } if (step.getAxisSpecifier().getNodeType() != null) { return false; } if (step.getAxisSpecifier().getNodeName() == null) { return false; } // if (step.getAxisSpecifier().getNodeName().getPrefix().isEmpty()) // return false; if (step.getAxisSpecifier().getNodeName().getNodeName().isEmpty()) { return false; } List<Predicate> predicates = step.getPredicates(); if (predicates.isEmpty() || predicates.size() > 2) { return false; } int positions = 0; int attributes = 0; for (Predicate pred : step.getPredicates()) { if (pred.getOrExpressions().size() != 1) { return false; } if (pred.getOrExpressions().get(0).getAndExpressions().size() != 1) { return false; } AndExpression and = pred.getOrExpressions().get(0).getAndExpressions().get(0); if (and instanceof PositionAndExpression) { ++positions; } else if (and instanceof AttributeAndExpression) { ++attributes; } } if (positions > 1 || attributes > 1 || (attributes + positions) == 0) { return false; } } return true; }