Example usage for org.apache.commons.httpclient URI URI

List of usage examples for org.apache.commons.httpclient URI URI

Introduction

In this page you can find the example usage for org.apache.commons.httpclient URI URI.

Prototype

public URI(String scheme, String userinfo, String host, int port, String path) throws URIException 

Source Link

Document

Construct a general URI from the given components.

Usage

From source file:net.mojodna.searchable.solr.SolrIndexer.java

private HttpClient getHttpClient() throws URIException {
    final HostConfiguration hostConfig = new HostConfiguration();
    hostConfig.setHost(new URI("http", null, solrHost, solrPort, solrPath));
    httpClient.setHostConfiguration(hostConfig);
    return httpClient;
}

From source file:org.zaproxy.zap.extension.ascanrulesAlpha.AbstractAppFilePlugin.java

@Override
public void scan() {
    // Check if the user stopped things. One request per URL so check before
    // sending the request
    if (isStop()) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Scanner " + getName() + " Stopping.");
        }/*from   w w w  .j a  v a  2 s .  c om*/
        return;
    }

    HttpMessage newRequest = getNewMsg();
    newRequest.getRequestHeader().setMethod(HttpRequestHeader.GET);
    URI baseUri = getBaseMsg().getRequestHeader().getURI();
    URI newUri = null;
    try {
        String baseUriPath = baseUri.getPath() == null ? "" : baseUri.getPath();
        newUri = new URI(baseUri.getScheme(), null, baseUri.getHost(), baseUri.getPort(),
                createTestablePath(baseUriPath));
    } catch (URIException uEx) {
        if (LOG.isDebugEnabled()) {
            LOG.debug(
                    "An error occurred creating a URI for the: " + getName() + " scanner. " + uEx.getMessage(),
                    uEx);
        }
        return;
    }
    try {
        newRequest.getRequestHeader().setURI(newUri);
    } catch (URIException uEx) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("An error occurred setting the URI for a new request used by: " + getName() + " scanner. "
                    + uEx.getMessage(), uEx);
        }
        return;
    }
    // Until https://github.com/zaproxy/zaproxy/issues/3563 is addressed
    // track completed in Kb
    // TODO change this when possible
    synchronized (getKb()) {
        if (getKb().getBoolean(newUri, messagePrefix)) {
            return;
        }
        getKb().add(newUri, messagePrefix, Boolean.TRUE);
    }
    try {
        sendAndReceive(newRequest, false);
    } catch (IOException e) {
        LOG.warn("An error occurred while checking [" + newRequest.getRequestHeader().getMethod() + "] ["
                + newRequest.getRequestHeader().getURI() + "] for " + getName() + " Caught "
                + e.getClass().getName() + " " + e.getMessage());
        return;
    }
    if (isFalsePositive(newRequest)) {
        return;
    }
    int statusCode = newRequest.getResponseHeader().getStatusCode();
    if (statusCode == HttpStatusCode.OK) {
        raiseAlert(newRequest, getRisk(), "");
    } else if (statusCode == HttpStatusCode.UNAUTHORIZED || statusCode == HttpStatusCode.FORBIDDEN) {
        raiseAlert(newRequest, Alert.RISK_INFO, getOtherInfo());
    }
}

From source file:org.zaproxy.zap.extension.ascanrulesAlpha.BackupFileDisclosure.java

/**
 * attempts to find a backup file for the given file
 * @param uri the URI of a file//ww w.  j  a va  2  s  .  co m
 * @return 
 */
private void findBackupFile(HttpMessage originalMessage) throws Exception {

    try {
        boolean gives404s = true;
        boolean parentgives404s = true;
        byte[] nonexistparentmsgdata = null;

        URI originalURI = originalMessage.getRequestHeader().getURI();

        //request a file in the same directory to see how it handles "File not found". Using a 404? Something else?
        String temppath = originalURI.getPath();
        if (temppath == null)
            temppath = "";
        int slashposition = temppath.lastIndexOf("/");
        if (slashposition < 0) {
            //WTF? there was no slash in the path..
            throw new Exception("The message has a path with a malformed path component");
        }
        String filename = originalMessage.getRequestHeader().getURI().getName();

        String randomfilename = RandomStringUtils.random(filename.length(),
                "abcdefghijklmoopqrstuvwxyz9123456789");
        String randomfilepath = temppath.substring(0, slashposition) + "/" + randomfilename;

        if (log.isDebugEnabled())
            log.debug("Trying non-existent file: " + randomfilepath);
        HttpMessage nonexistfilemsg = new HttpMessage(
                new URI(originalURI.getScheme(), originalURI.getAuthority(), randomfilepath, null, null));
        try {
            nonexistfilemsg.setCookieParams(originalMessage.getCookieParams());
        } catch (Exception e) {
            if (log.isDebugEnabled())
                log.debug("Could not set the cookies from the base request:" + e);
        }
        sendAndReceive(nonexistfilemsg, false);
        byte[] nonexistfilemsgdata = nonexistfilemsg.getResponseBody().getBytes();
        //does the server give a 404 for a non-existent file? 
        if (nonexistfilemsg.getResponseHeader().getStatusCode() != HttpStatus.SC_NOT_FOUND) {
            gives404s = false;
            if (log.isDebugEnabled())
                log.debug("The server does not return a 404 status for a non-existent path: "
                        + nonexistfilemsg.getRequestHeader().getURI().getURI());
        } else {
            gives404s = true;
            if (log.isDebugEnabled())
                log.debug("The server gives a 404 status for a non-existent path: "
                        + nonexistfilemsg.getRequestHeader().getURI().getURI());
        }

        //now request a different (and non-existent) parent directory, 
        //to see whether a non-existent parent folder causes a 404 
        String[] pathbreak = temppath.split("/");
        if (pathbreak.length > 2) { //the file has a parent folder that is not the root folder (ie, there is a parent folder to mess with)
            String[] temppathbreak = pathbreak;
            String parentfoldername = pathbreak[pathbreak.length - 2];
            String randomparentfoldername = RandomStringUtils.random(parentfoldername.length(),
                    "abcdefghijklmoopqrstuvwxyz9123456789");

            //replace the parent folder name with the random one, and build it back into a string
            temppathbreak[pathbreak.length - 2] = randomparentfoldername;
            String randomparentpath = StringUtils.join(temppathbreak, "/");

            if (log.isDebugEnabled())
                log.debug("Trying non-existent parent path: " + randomparentpath);
            HttpMessage nonexistparentmsg = new HttpMessage(
                    new URI(originalURI.getScheme(), originalURI.getAuthority(), randomparentpath, null, null));
            try {
                nonexistparentmsg.setCookieParams(originalMessage.getCookieParams());
            } catch (Exception e) {
                if (log.isDebugEnabled())
                    log.debug("Could not set the cookies from the base request:" + e);
            }
            sendAndReceive(nonexistparentmsg, false);
            nonexistparentmsgdata = nonexistparentmsg.getResponseBody().getBytes();
            //does the server give a 404 for a non-existent parent folder? 
            if (nonexistparentmsg.getResponseHeader().getStatusCode() != HttpStatus.SC_NOT_FOUND) {
                parentgives404s = false;
                if (log.isDebugEnabled())
                    log.debug("The server does not return a 404 status for a non-existent parent path: "
                            + nonexistparentmsg.getRequestHeader().getURI().getURI());
            } else {
                parentgives404s = true;
                if (log.isDebugEnabled())
                    log.debug("The server gives a 404 status for a non-existent parent path: "
                            + nonexistparentmsg.getRequestHeader().getURI().getURI());
            }
        }

        String actualfilename = originalURI.getName();
        String actualfileExtension = null;
        String path = originalURI.getPath();
        if (path == null)
            path = "";

        //record the position of the various injection points, always relative to the full path         
        int positionExtensionInjection = 0;
        int positionFileSuffixInjection = 0;
        if (actualfilename.contains(".")) {
            positionExtensionInjection = path.lastIndexOf(".");
            positionFileSuffixInjection = positionExtensionInjection;
            actualfileExtension = actualfilename.substring(actualfilename.lastIndexOf("."));
        } else {
            positionExtensionInjection = path.length();
            positionFileSuffixInjection = path.length();
            actualfileExtension = "";
        }
        int positionFilePrefixInjection = path.lastIndexOf("/") + 1;
        int positionDirectorySuffixInjection = path.lastIndexOf("/");
        int positionDirectoryPrefixInjection = 0;
        if (positionDirectorySuffixInjection >= 0)
            positionDirectoryPrefixInjection = path.substring(0, positionDirectorySuffixInjection)
                    .lastIndexOf("/") + 1;

        //the set of files we will try, in the order of insertion
        Set<URI> candidateBackupFileURIs = new LinkedHashSet<URI>();
        Set<URI> candidateBackupFileChangedFolderURIs = new LinkedHashSet<URI>(); //for a changed parent folder name, which we need to handle separately 

        log.debug("The path is " + path);

        //for each file extension to try (both appending, and replacing)
        int counted = 0;
        for (String fileExtensionToTry : fileExtensions) {
            //to append, inject the file extension at the end of the path  
            String candidateBackupFilePath = path + fileExtensionToTry;
            log.debug("File Extension (append): '" + candidateBackupFilePath + "'");
            candidateBackupFileURIs.add(new URI(originalURI.getScheme(), originalURI.getAuthority(),
                    candidateBackupFilePath, null, null));

            //to replace the extension, append the file extension at positionExtensionInjection
            candidateBackupFilePath = path.substring(0, positionExtensionInjection) + fileExtensionToTry;
            log.debug("File Extension (replace): '" + candidateBackupFilePath + "'");
            candidateBackupFileURIs.add(new URI(originalURI.getScheme(), originalURI.getAuthority(),
                    candidateBackupFilePath, null, null));

            //to switch the extension (if there was one), append the file extension at positionExtensionInjection
            if (!actualfileExtension.equals("") && doSwitchFileExtension) {
                candidateBackupFilePath = path.substring(0, positionExtensionInjection) + fileExtensionToTry
                        + actualfileExtension;
                log.debug("File Extension (switch): '" + candidateBackupFilePath + "'");
                candidateBackupFileURIs.add(new URI(originalURI.getScheme(), originalURI.getAuthority(),
                        candidateBackupFilePath, null, null));
            }
            counted++;
            if (counted > numExtensionsToTry) {
                break; //out of the loop.
            }
        }

        //for each file suffix to try
        counted = 0;
        for (String fileSuffixToTry : fileSuffixes) {
            //inject the file suffix at positionFileSuffixInjection
            String candidateBackupFilePath = path.substring(0, positionFileSuffixInjection) + fileSuffixToTry
                    + (positionFileSuffixInjection >= path.length() ? ""
                            : path.substring(positionFileSuffixInjection));
            log.debug("File Suffix (insert): '" + candidateBackupFilePath + "'");
            candidateBackupFileURIs.add(new URI(originalURI.getScheme(), originalURI.getAuthority(),
                    candidateBackupFilePath, null, null));
            counted++;
            if (counted > numSuffixesToTry) {
                break; //out of the loop.
            }
        }

        //for each file prefix to try
        counted = 0;
        for (String filePrefixToTry : filePrefixes) {
            //inject the file prefix at positionFilePrefixInjection
            String candidateBackupFilePath = path.substring(0, positionFilePrefixInjection) + filePrefixToTry
                    + (positionFilePrefixInjection >= path.length() ? ""
                            : path.substring(positionFilePrefixInjection));
            log.debug("File Prefix (insert): '" + candidateBackupFilePath + "'");
            candidateBackupFileURIs.add(new URI(originalURI.getScheme(), originalURI.getAuthority(),
                    candidateBackupFilePath, null, null));
            counted++;
            if (counted > numPrefixesToTry) {
                break; //out of the loop.
            }
        }

        //for each directory suffix/prefix to try (using the file prefixes/suffixes - or whatever the plural of prefix/suffix is)         
        counted = 0;
        if (pathbreak.length > 2) {
            //if there is a a parent folder to play with 
            for (String fileSuffixToTry : fileSuffixes) {
                //inject the directory suffix at positionDirectorySuffixInjection
                String candidateBackupFilePath = path.substring(0, positionDirectorySuffixInjection)
                        + fileSuffixToTry + (positionDirectorySuffixInjection >= path.length() ? ""
                                : path.substring(positionDirectorySuffixInjection));
                log.debug("Directory Suffix (insert): '" + candidateBackupFilePath + "'");
                candidateBackupFileChangedFolderURIs.add(new URI(originalURI.getScheme(),
                        originalURI.getAuthority(), candidateBackupFilePath, null, null));
                counted++;
                if (counted > numSuffixesToTry) {
                    break; //out of the loop.
                }
            }
            for (String filePrefixToTry : filePrefixes) {
                //inject the directory prefix at positionDirectorySuffixInjection
                String candidateBackupFilePath = path.substring(0, positionDirectoryPrefixInjection)
                        + filePrefixToTry + (positionDirectoryPrefixInjection >= path.length() ? ""
                                : path.substring(positionDirectoryPrefixInjection));
                log.debug("Directory Suffix (insert): '" + candidateBackupFilePath + "'");
                candidateBackupFileChangedFolderURIs.add(new URI(originalURI.getScheme(),
                        originalURI.getAuthority(), candidateBackupFilePath, null, null));
                counted++;
                if (counted > numSuffixesToTry) {
                    break; //out of the loop.
                }
            }
        }

        //now we have a set of candidate URIs appropriate to the attack strength chosen by the user
        //try each candidate URI in turn.
        for (URI candidateBackupFileURI : candidateBackupFileURIs) {
            byte[] disclosedData = {};
            if (log.isDebugEnabled())
                log.debug("Trying possible backup file path: " + candidateBackupFileURI.getURI());
            HttpMessage requestmsg = new HttpMessage(candidateBackupFileURI);
            try {
                requestmsg.setCookieParams(originalMessage.getCookieParams());
            } catch (Exception e) {
                if (log.isDebugEnabled())
                    log.debug("Could not set the cookies from the base request:" + e);
            }
            //Do not follow redirects. They're evil. Yep.
            sendAndReceive(requestmsg, false);
            disclosedData = requestmsg.getResponseBody().getBytes();
            int requestStatusCode = requestmsg.getResponseHeader().getStatusCode();

            //just to complicate things.. I have a test case which for the random file, does NOT give a 404 (so gives404s == false) 
            //but for a "Copy of" file, actually gives a 404 (for some unknown reason). We need to handle this case.
            if ((gives404s && requestStatusCode != HttpStatus.SC_NOT_FOUND)
                    || ((!gives404s) && requestStatusCode != HttpStatus.SC_NOT_FOUND
                            && (!Arrays.equals(disclosedData, nonexistfilemsgdata)))) {
                bingo(Alert.RISK_MEDIUM, Alert.WARNING,
                        Constant.messages.getString("ascanalpha.backupfiledisclosure.name"),
                        Constant.messages.getString("ascanalpha.backupfiledisclosure.desc"),
                        requestmsg.getRequestHeader().getURI().getURI(), // originalMessage.getRequestHeader().getURI().getURI(),
                        null, //parameter being attacked: none.
                        candidateBackupFileURI.getURI(), //attack
                        originalMessage.getRequestHeader().getURI().getURI(), //new String (disclosedData),  //extrainfo
                        Constant.messages.getString("ascanalpha.backupfiledisclosure.soln"),
                        Constant.messages.getString("ascanalpha.backupfiledisclosure.evidence", originalURI,
                                candidateBackupFileURI.getURI()),
                        requestmsg //originalMessage
                );
            }

            if (isStop()) {
                if (log.isDebugEnabled())
                    log.debug("The scanner was stopped in response to a user request");
                return;
            }
        }

        //now try the changed parent folders (if any)
        //the logic here needs to check using the parent 404 logic, and the output for a non-existent parent folder.
        for (URI candidateBackupFileURI : candidateBackupFileChangedFolderURIs) {
            byte[] disclosedData = {};
            if (log.isDebugEnabled())
                log.debug("Trying possible backup file path (with changed parent folder): "
                        + candidateBackupFileURI.getURI());
            HttpMessage requestmsg = new HttpMessage(candidateBackupFileURI);
            try {
                requestmsg.setCookieParams(originalMessage.getCookieParams());
            } catch (Exception e) {
                if (log.isDebugEnabled())
                    log.debug("Could not set the cookies from the base request:" + e);
            }
            //Do not follow redirects. They're evil. Yep.
            sendAndReceive(requestmsg, false);
            disclosedData = requestmsg.getResponseBody().getBytes();
            int requestStatusCode = requestmsg.getResponseHeader().getStatusCode();

            if ((parentgives404s && requestStatusCode != HttpStatus.SC_NOT_FOUND)
                    || ((!parentgives404s) && requestStatusCode != HttpStatus.SC_NOT_FOUND
                            && (!Arrays.equals(disclosedData, nonexistparentmsgdata)))) {
                bingo(Alert.RISK_MEDIUM, Alert.WARNING,
                        Constant.messages.getString("ascanalpha.backupfiledisclosure.name"),
                        Constant.messages.getString("ascanalpha.backupfiledisclosure.desc"),
                        requestmsg.getRequestHeader().getURI().getURI(), //originalMessage.getRequestHeader().getURI().getURI(),
                        null, //parameter being attacked: none.
                        candidateBackupFileURI.getURI(), //attack
                        originalMessage.getRequestHeader().getURI().getURI(), //new String (disclosedData),  //extrainfo
                        Constant.messages.getString("ascanalpha.backupfiledisclosure.soln"),
                        Constant.messages.getString("ascanalpha.backupfiledisclosure.evidence", originalURI,
                                candidateBackupFileURI.getURI()),
                        requestmsg //originalMessage
                );
            }

            if (isStop()) {
                if (log.isDebugEnabled())
                    log.debug("The scanner was stopped in response to a user request");
                return;
            }
        }

    } catch (Exception e) {
        e.printStackTrace();
        log.error("Some error occurred when looking for a backup file for '"
                + originalMessage.getRequestHeader().getURI() + "': " + e);
        return;
    }

}

From source file:org.zaproxy.zap.extension.ascanrulesAlpha.CrossDomainScanner.java

/**
 * scans the node for cross-domain mis-configurations
 *//*from   w  w w  .j  a  va2  s.  c om*/
@Override
public void scan() {

    try {
        //get the network details for the attack
        URI originalURI = this.getBaseMsg().getRequestHeader().getURI();

        //retrieve the Adobe cross domain policy file, and assess it
        HttpMessage crossdomainmessage = new HttpMessage(new URI(originalURI.getScheme(),
                originalURI.getAuthority(), "/" + ADOBE_CROSS_DOMAIN_POLICY_FILE, null, null));
        sendAndReceive(crossdomainmessage, false);
        byte[] crossdomainmessagebytes = crossdomainmessage.getResponseBody().getBytes();

        //parse the file. If it's not parseable, it might have been because of a 404
        DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
        ;
        DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
        ;
        XPath xpath = (XPath) XPathFactory.newInstance().newXPath();

        try {
            //work around the "no protocol" issue by wrapping the content in a ByteArrayInputStream
            Document adobeXmldoc = docBuilder
                    .parse(new InputSource(new ByteArrayInputStream(crossdomainmessagebytes)));

            //check for cross domain read (data load) access
            XPathExpression exprAllowAccessFromDomain = xpath
                    .compile("/cross-domain-policy/allow-access-from/@domain"); //gets the domain attributes
            NodeList exprAllowAccessFromDomainNodes = (NodeList) exprAllowAccessFromDomain.evaluate(adobeXmldoc,
                    XPathConstants.NODESET);
            for (int i = 0; i < exprAllowAccessFromDomainNodes.getLength(); i++) {
                String domain = exprAllowAccessFromDomainNodes.item(i).getNodeValue();
                if (domain.equals("*")) {
                    //oh dear me.
                    if (log.isInfoEnabled())
                        log.info("Bingo!  <allow-access-from domain=\"*\"");
                    bingo(getRisk(), Alert.WARNING,
                            Constant.messages.getString(MESSAGE_PREFIX_ADOBE_READ + "name"),
                            Constant.messages.getString(MESSAGE_PREFIX_ADOBE + "desc"),
                            crossdomainmessage.getRequestHeader().getURI().getURI(), //the url field 
                            "", //parameter being attacked: none.
                            "", //attack
                            Constant.messages.getString(MESSAGE_PREFIX_ADOBE_READ + "extrainfo",
                                    "/" + ADOBE_CROSS_DOMAIN_POLICY_FILE), //extrainfo
                            Constant.messages.getString(MESSAGE_PREFIX_ADOBE_READ + "soln"), //solution
                            "<allow-access-from domain=\"*\"", // evidence
                            crossdomainmessage //the message on which to place the alert
                    );
                }
            }
            //check for cross domain send (upload) access
            XPathExpression exprRequestHeadersFromDomain = xpath
                    .compile("/cross-domain-policy/allow-http-request-headers-from/@domain"); //gets the domain attributes
            NodeList exprRequestHeadersFromDomainNodes = (NodeList) exprRequestHeadersFromDomain
                    .evaluate(adobeXmldoc, XPathConstants.NODESET);
            for (int i = 0; i < exprRequestHeadersFromDomainNodes.getLength(); i++) {
                String domain = exprRequestHeadersFromDomainNodes.item(i).getNodeValue();
                if (domain.equals("*")) {
                    //oh dear, dear me.
                    if (log.isInfoEnabled())
                        log.info("Bingo!  <allow-http-request-headers-from domain=\"*\"");
                    bingo(getRisk(), Alert.WARNING,
                            Constant.messages.getString(MESSAGE_PREFIX_ADOBE_SEND + "name"),
                            Constant.messages.getString(MESSAGE_PREFIX_ADOBE + "desc"),
                            crossdomainmessage.getRequestHeader().getURI().getURI(), //the url field 
                            "", //parameter being attacked: none.
                            "", //attack
                            Constant.messages.getString(MESSAGE_PREFIX_ADOBE_SEND + "extrainfo",
                                    "/" + ADOBE_CROSS_DOMAIN_POLICY_FILE), //extrainfo
                            Constant.messages.getString(MESSAGE_PREFIX_ADOBE_SEND + "soln"), //solution
                            "<allow-http-request-headers-from domain=\"*\"", // evidence
                            crossdomainmessage //the message on which to place the alert
                    );
                }
            }
        } catch (SAXException | IOException e) {
            log.error("An error occurred trying to parse " + ADOBE_CROSS_DOMAIN_POLICY_FILE + " as XML: " + e);
        }

        //retrieve the Silverlight client access policy file, and assess it.
        HttpMessage clientaccesspolicymessage = new HttpMessage(new URI(originalURI.getScheme(),
                originalURI.getAuthority(), "/" + SILVERLIGHT_CROSS_DOMAIN_POLICY_FILE, null, null));
        sendAndReceive(clientaccesspolicymessage, false);
        byte[] clientaccesspolicymessagebytes = clientaccesspolicymessage.getResponseBody().getBytes();

        //parse the file. If it's not parseable, it might have been because of a 404         
        try {
            //work around the "no protocol" issue by wrapping the content in a ByteArrayInputStream
            Document silverlightXmldoc = docBuilder
                    .parse(new InputSource(new ByteArrayInputStream(clientaccesspolicymessagebytes)));
            XPathExpression exprAllowFromUri = xpath
                    .compile("/access-policy/cross-domain-access/policy/allow-from/domain/@uri"); //gets the uri attributes
            //check the "allow-from" policies
            NodeList exprAllowFromUriNodes = (NodeList) exprAllowFromUri.evaluate(silverlightXmldoc,
                    XPathConstants.NODESET);
            for (int i = 0; i < exprAllowFromUriNodes.getLength(); i++) {
                String uri = exprAllowFromUriNodes.item(i).getNodeValue();
                if (uri.equals("*")) {
                    //tut, tut, tut.
                    if (log.isInfoEnabled())
                        log.info("Bingo! " + SILVERLIGHT_CROSS_DOMAIN_POLICY_FILE
                                + ", at /access-policy/cross-domain-access/policy/allow-from/domain/@uri");
                    bingo(getRisk(), Alert.WARNING,
                            Constant.messages.getString(MESSAGE_PREFIX_SILVERLIGHT + "name"),
                            Constant.messages.getString(MESSAGE_PREFIX_SILVERLIGHT + "desc"),
                            clientaccesspolicymessage.getRequestHeader().getURI().getURI(), //the url field 
                            "", //parameter being attacked: none.
                            "", //attack
                            Constant.messages.getString(MESSAGE_PREFIX_SILVERLIGHT + "extrainfo"), //extrainfo
                            Constant.messages.getString(MESSAGE_PREFIX_SILVERLIGHT + "soln"), //solution
                            "<domain uri=\"*\"", // evidence
                            clientaccesspolicymessage //the message on which to place the alert
                    );
                }
            }

        } catch (SAXException | IOException e) {
            log.error("An error occurred trying to parse " + SILVERLIGHT_CROSS_DOMAIN_POLICY_FILE + " as XML: "
                    + e);
        }

    } catch (Exception e) {
        //needed to catch exceptions from the "finally" statement 
        log.error("Error scanning a node for Cross Domain misconfigurations: " + e.getMessage(), e);
    }
}

From source file:org.zaproxy.zap.extension.ascanrulesAlpha.ElmahScanner.java

@Override
public void scan() {

    // Check if the user stopped things. One request per URL so check before
    // sending the request
    if (isStop()) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Scanner " + getName() + " Stopping.");
        }//from w  w  w  . jav  a 2  s .c o m
        return;
    }

    HttpMessage newRequest = getNewMsg();
    newRequest.getRequestHeader().setMethod(HttpRequestHeader.GET);
    URI baseUri = getBaseMsg().getRequestHeader().getURI();
    URI elmahUri = null;
    try {
        elmahUri = new URI(baseUri.getScheme(), null, baseUri.getHost(), baseUri.getPort(), "/elmah.axd");
    } catch (URIException uEx) {
        if (LOG.isDebugEnabled()) {
            LOG.debug(
                    "An error occurred creating a URI for the: " + getName() + " scanner. " + uEx.getMessage(),
                    uEx);
        }
        return;
    }
    try {
        newRequest.getRequestHeader().setURI(elmahUri);
    } catch (URIException uEx) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("An error occurred setting the URI for a new request used by: " + getName() + " scanner. "
                    + uEx.getMessage(), uEx);
        }
        return;
    }
    try {
        sendAndReceive(newRequest, false);
    } catch (IOException e) {
        LOG.warn("An error occurred while checking [" + newRequest.getRequestHeader().getMethod() + "] ["
                + newRequest.getRequestHeader().getURI() + "] for " + getName() + " Caught "
                + e.getClass().getName() + " " + e.getMessage());
        return;
    }
    int statusCode = newRequest.getResponseHeader().getStatusCode();
    if (statusCode == HttpStatusCode.OK) {
        raiseAlert(newRequest, getRisk(), "");
    } else if (statusCode == HttpStatusCode.UNAUTHORIZED || statusCode == HttpStatusCode.FORBIDDEN) {
        raiseAlert(newRequest, Alert.RISK_INFO, getOtherInfo());
    }
}

From source file:org.zaproxy.zap.extension.ascanrulesAlpha.GitMetadata.java

/**
 * get data for a given SHA1 object, using either the loose or packed formats
 *
 * @param basemsg the base message to use when retrieving additional resources
 * @param gitbasepath the Git base path/*from w ww  . j  a  va  2  s. c  o m*/
 * @param filesha1 the SHA1 associated with the file in Git
 * @param trypacked try the packed format, or try the loose format
 * @return the binary data associated with the file in Git, as specified by the filesha1
 *     parameter
 * @throws Exception
 */
public byte[] getObjectData(HttpMessage basemsg, String gitbasepath, String filesha1, boolean trypacked)
        throws Exception {

    URI originaluri = basemsg.getRequestHeader().getURI();
    if (!trypacked) {
        // try the unpacked (loose) format
        URI gitobjecturi = new URI(originaluri.getScheme(), originaluri.getAuthority(),
                gitbasepath + "objects/" + filesha1.substring(0, 2) + "/" + filesha1.substring(2), null, null);

        if (log.isDebugEnabled())
            log.debug("The internal Git (loose) file name is " + gitobjecturi.getURI());
        byte[] data = getURIResponseBody(gitobjecturi, true, basemsg);

        ByteBuffer dataBuffer = ByteBuffer.wrap(data);
        StringBuilder sb = new StringBuilder();
        while (true) {
            byte b = dataBuffer.get();
            if (b == ' ')
                break;
            sb.append((char) b);
        }
        String objecttype = new String(sb);
        if (!objecttype.equals("blob")) {
            throw new Exception(
                    "The Git 'loose' file '" + gitobjecturi + "' is not of type 'blob': '" + objecttype + "'");
        }
        // read the size of data in the file (which appears as ASCII digits in the text), until
        // we get a 0x00
        sb = new StringBuilder();
        while (true) {
            byte b = dataBuffer.get();
            if (b == 0x00)
                break;
            sb.append((char) b);
        }
        int dataSize = Integer.parseInt(new String(sb));

        // now read that number of bytes from the bytebuffer, or at least attempt to..
        byte[] blobDecoded = new byte[dataSize];
        dataBuffer.get(blobDecoded);
        // that's it. we're done. return the decoded data, which will hopefully be source code
        // :)
        return blobDecoded;
    } else {
        // try the packed format

        // With the Git "packed" format, there are Git "pack index" files, and Git "pack" files.
        // They come as a set. You need both to get the contents of the file you're looking for.
        // The name of the Git "pack" files and "pack index" files is based on the SHA1 sum of
        // the SHA1 objects that it contains, and is not guessable.
        // This is an issue if you do not already know what pack files live in the directory
        // (unless you have a directory listing, for instance).
        // Luckily, in practice, in most cases (although not always) the name of the "pack" file
        // is contained in an ".git/objects/info/packs" file in the Git repo metadata.
        // The ".git/objects/info/packs" can also contain the names of multiple pack files,
        // which I have not seen in practice. That scenario is not currently supported here.

        // Both the "pack" and "pack index" files have an associated version number, but not
        // necessarily the same version number as each other.
        // There are constraints and interdependencies on these version numbers, however.

        // The Git "pack index" file currently comes in versions 1,2, and 3 (as of January 30,
        // 2014).

        // version 1 "pack index" files are not seen in the wild, but can be created using later
        // versions of Git, if necessary.  Version 1 is supported here.
        //            (Version 1 "pack index" files are seen in conjunction with Version 2 "pack" files,
        // but there is no reason (that I know of) why they should not also support Version 3 or
        // 4 pack files).
        // version 2 "pack index" files use either a version 2 or version 3 "pack" file. All
        // these versions are supported here.
        //             (Version 1 and 2 "pack index" file formats have structural differences, but not
        // not wildly dis-similar).
        // version 3 "pack index" file cannot yet be created by any currently known version of
        // Git, but the format is documented.
        //            (Version 3 "pack index" files require a version 4 "pack file". Both these versions
        // are tentatively supported here, although this code has never been tested)

        // The Git "pack" file currently comes in versions 1,2,3, and 4 (as of January 30,
        // 2014).
        // Version 1 "pack" files do not appear to be documented. They are not supported here.
        // Version 2 "pack files" are used with version 2 "pack index" files. This is a common
        // scenario in the wild. Both versions are supported here.
        // Version 3 "pack files" are (also) used with version 2 "pack index" files. Both
        // versions are supported here.
        //           (Version 3 "pack files" are identical in format to version 2, with only the
        // version number differing)
        // Version 4 "pack files" are used in conjunction with version 3 "pack index" files.
        // Both these versions are tentatively supported here, although this code has never been
        // tested.

        // There are also separate version numbers in the Git "index file" (unrelated to the
        // "pack index" files mentioned above), which are probably similarly inter-related.
        // I do not have a mapping of the Git version number (1.7.6 / 1.8.5, for instance) to
        // any of the the internal file version numbers that they create (by default) or
        // support. So sue me.

        URI uri = new URI(originaluri.getScheme(), originaluri.getAuthority(),
                gitbasepath + "objects/info/packs", null, null);

        if (log.isDebugEnabled())
            log.debug("The internal Git file containing the name of the pack file is " + uri);

        byte[] packinfofiledata = null;
        try {
            packinfofiledata = getURIResponseBody(uri, false, basemsg);
        } catch (FileNotFoundException e) {
            log.error("We could not read '" + uri
                    + "' to get the name of the pack file containing the content: " + e.getMessage());
            throw e;
        }
        ByteBuffer dataBuffer = ByteBuffer.wrap(packinfofiledata);
        StringBuilder sb = new StringBuilder();
        while (true) {
            byte b = dataBuffer.get();
            if (b == ' ')
                break;
            sb.append((char) b);
        }
        String objecttype = new String(sb);
        if (!objecttype.equals("P")) {
            throw new Exception("The pack info file is not of type 'P': '" + objecttype + "'");
        }

        // the file should  begin with "P ", and everything after that is the pack file name
        // (and exclude the 2 trailing newlines as well)
        // TODO: handle the case where this file contains the name of multiple pack files.
        // Currently, i have no test cases. Maybe in extremely large Git repositories?
        byte[] packfilenamebytes = new byte[packinfofiledata.length - 4];
        dataBuffer.get(packfilenamebytes);
        String packfilename = new String(packfilenamebytes);
        // validate that the file name looks like "pack*.pack"
        Matcher packfilenamematcher = Pattern.compile("^pack-[0-9a-f]{40}\\.pack$").matcher(packfilename);
        if (!packfilenamematcher.find()) {
            throw new Exception(
                    "The pack file name '" + packfilename + "' does not match the expected pattern");
        }

        // Now generate the full name of the pack file, and the pack index.
        URI packuri = new URI(originaluri.getScheme(), originaluri.getAuthority(),
                gitbasepath + "objects/pack/" + packfilename, null, null);
        URI packindexuri = new URI(originaluri.getScheme(), originaluri.getAuthority(),
                gitbasepath + "objects/pack/" + packfilename.substring(0, packfilename.length() - 5) + ".idx",
                null, null);

        // retrieve the content for the "pack index" file!
        byte[] packfileindexdata = null;
        try {
            packfileindexdata = getURIResponseBody(packindexuri, false, basemsg);
        } catch (FileNotFoundException e) {
            System.out.println("We could not read '" + packindexuri
                    + "', which is necessary to get the packed contents of the SHA1 requested: "
                    + e.getMessage());
            throw e;
        }

        // retrieve the content for the "pack" file!
        byte[] packfiledata = null;
        try {
            packfiledata = getURIResponseBody(packuri, false, basemsg);
        } catch (FileNotFoundException e) {
            System.out.println("We could not read '" + packuri
                    + "', which should contain the packed contents of the SHA1 requested: " + e.getMessage());
            throw e;
        }

        // now that we know we have both the "pack index" and the "pack" (data) file, parse the
        // data
        // first parse out some signature data info from the "pack" file
        ByteBuffer packfileheaderBuffer = ByteBuffer.wrap(packfiledata, 0, 12);
        byte[] packfileheaderSignatureArray = new byte[4]; // 4 bytes
        packfileheaderBuffer.get(packfileheaderSignatureArray);
        if (!new String(packfileheaderSignatureArray).equals("PACK")) {
            throw new Exception("The pack file header does not appear to be valid");
        }
        int packFileVersion = packfileheaderBuffer.getInt(); // 4 bytes
        int packEntryCount = packfileheaderBuffer.getInt(); // 4 bytes

        if (packFileVersion != 2 && packFileVersion != 3 && packFileVersion != 4) {
            throw new Exception(
                    "Only Git Pack File versions 2, 3, and 4 are currently supported. Git Pack File Version "
                            + packFileVersion + " was found. Contact the zaproxy (OWASP Zap) dev team");
        }

        // for pack file version 4, read the SHA1 tables from the "pack" file at this point
        // these used to live in the "pack index" file, in earlier versions.
        // Note: since at this point in time, there is no way to generate a v3 pack index file +
        // v4 pack file
        // so this particular block of code remains hypothetical.  it seems to comply with the
        // documented version 4 "pack" file format, however, and it
        // works for version 2 "pack index" and version 2 "pack" files, which appears to be the
        // most common combination seen in the wild.

        int sha1Index = Integer.MAX_VALUE;
        int packEntryOffsetArray[] = null;
        int packEntryOffsetArrayOrdered[] = null;
        int indexEntryCount = 0;

        if (packFileVersion >= 4) {
            sha1Index = Integer.MAX_VALUE;
            // the tables in the V4 tables in the pack file are variable length, so just grab
            // the data after the main header for now
            ByteBuffer packfileTablesBuffer = ByteBuffer.wrap(packfiledata, 12, packfiledata.length - 12);
            // read the series of 20 byte sha1 entries.
            // ours *should* be in here somewhere.. find it
            // make sure to read *all* of the entries from the file (or else seek to the end of
            // the data), so the parsing logic is not broken.
            // TODO: use a binary search to find this in a more efficient manner

            for (int i = 0; i < packEntryCount; i++) {
                byte[] packTableData = new byte[20];
                packfileTablesBuffer.get(packTableData);
                String packTableSha1 = Hex.encodeHexString(packTableData);
                // TODO: use more efficient byte based comparison to find the SHA1 here (and in
                // similar code in pack index version 2 logic, later..
                if (packTableSha1.equals(filesha1)) {
                    if (log.isDebugEnabled())
                        log.debug("FOUND our SHA1 " + packTableSha1 + " at entry " + i
                                + " in the v4 pack tables");
                    sha1Index = i;

                    // we do not need to "read past" all the entries.
                    break;
                }
            }
        }

        // try to parse the "pack index" as a version 1 "pack index" file, which has a different
        // layout to subsequent versions.
        // use a separate ByteBuffer for this, in case things don't work out (because they
        // probably will not work out) :)
        try {
            ByteBuffer packindexfileV1dataBuffer = ByteBuffer.wrap(packfileindexdata);
            byte packEntrySizeArray[] = new byte[256 * 4];
            packindexfileV1dataBuffer.get(packEntrySizeArray);

            if (
            /*packEntrySizeArray[0]== 0xFF && */
            packEntrySizeArray[1] == 't' && packEntrySizeArray[2] == 'O' && packEntrySizeArray[3] == 'c') {
                // the signature is a non-V1 signature.
                throw new NotV1GitPackIndexFileException();
            }
            // get the last 4 bytes as an int, network order.
            indexEntryCount = (packEntrySizeArray[(255 * 4) + 3] << 0);
            indexEntryCount |= (packEntrySizeArray[(255 * 4) + 2] << 8);
            indexEntryCount |= (packEntrySizeArray[(255 * 4) + 1] << 16);
            indexEntryCount |= (packEntrySizeArray[(255 * 4) + 0] << 24);

            // validate that this matches the number of entries in the "pack" file.
            if (indexEntryCount != packEntryCount) {
                throw new Exception("The entry count (" + indexEntryCount
                        + ") from the version 1 pack index file does not match the entry count ("
                        + packEntryCount + ") from the pack file ");
            }
            if (log.isDebugEnabled())
                log.debug("Got a pack index entry count of " + indexEntryCount
                        + " from the version 1 pack index file");

            // read the indexEntryCount * (4+20) byte entries (4 + 20 blackbirds baked in a
            // pie!)
            sha1Index = Integer.MAX_VALUE;
            packEntryOffsetArray = new int[indexEntryCount];
            packEntryOffsetArrayOrdered = new int[indexEntryCount];

            // TODO: use a binary search to find this in a more efficient manner
            for (int i = 0; i < indexEntryCount; i++) {
                // read 4 bytes offset (the offset of the SHA1's data in the "pack" file)
                packEntryOffsetArray[i] = packindexfileV1dataBuffer.getInt();
                packEntryOffsetArrayOrdered[i] = packEntryOffsetArray[i];

                // read 20 bytes SHA1
                byte[] indexEntryIdBuffer = new byte[20];
                packindexfileV1dataBuffer.get(indexEntryIdBuffer);
                String indexEntrySha1 = Hex.encodeHexString(indexEntryIdBuffer);
                if (indexEntrySha1.equals(filesha1)) {
                    if (log.isDebugEnabled())
                        log.debug("FOUND our SHA1 " + indexEntrySha1 + " at entry " + i + " in the SHA1 table");
                    sha1Index = i;
                }
            }
            // final sanity check, if all of the above panned out for version 1 index file.
            // Note: we *think* that that "pack index" file version 1 is compatible with "pack"
            // file version 3 and 4, but really, we don't know for sure.. Again, so sue me.
            int packindexFileVersion = 1;
            if (packFileVersion != 2 && packFileVersion != 3 && packFileVersion != 4) {
                throw new Exception("Pack index file version (" + packindexFileVersion
                        + ") is incompatible with pack file version (" + packFileVersion + ")");
            }

        } catch (NotV1GitPackIndexFileException e) {
            // so it's not a version 1 "pack index" file. Try parsing it as a version 2, 3, 4
            // (or later versions, once there are more versions, and we support them)
            if (log.isDebugEnabled())
                log.debug(
                        "The 'pack index' file looks like a > version 1 'pack index' file. Trying to parse it as later formats instead");

            // Parse the "pack index" file header
            ByteBuffer packindexfiledataBuffer = ByteBuffer.wrap(packfileindexdata);

            byte[] packindexfileheaderSignatureArray = new byte[4];
            packindexfiledataBuffer.get(packindexfileheaderSignatureArray);
            if (
            /*packindexfileheaderSignatureArray[0]!= 0xFF || */
            packindexfileheaderSignatureArray[1] != 't' || packindexfileheaderSignatureArray[2] != 'O'
                    || packindexfileheaderSignatureArray[3] != 'c') {
                throw new Exception(
                        "The pack index file header does not appear to be valid for pack index file version 2, 3, or 4: '"
                                + new String(packindexfileheaderSignatureArray) + "' was found");
            }

            // Note: version 1 is handled separately, so need to check for it here.
            int packindexFileVersion = packindexfiledataBuffer.getInt();
            if (packindexFileVersion != 2 && packindexFileVersion != 3) {
                throw new Exception("Pack index file version(" + packindexFileVersion + ") is not supported");
            }
            if ((packFileVersion == 2 || packFileVersion == 3) && packindexFileVersion != 2) {
                throw new Exception("Pack index file version (" + packindexFileVersion
                        + ") is incompatible with pack file version (" + packFileVersion + ")");
            }
            if (packindexFileVersion == 3 && packFileVersion != 4) {
                throw new Exception("Pack index file version (" + packindexFileVersion
                        + ") is only compatible with pack file version 4. Pack file version (" + packFileVersion
                        + ") was found");
            }

            int packEntrySizeArray[] = new int[256];
            for (int i = 0; i < 256; i++) {
                packEntrySizeArray[i] = packindexfiledataBuffer.getInt();
            }
            // get the total number of entries, as being the number of entries from the final
            // fanout table entry.
            indexEntryCount = packEntrySizeArray[255];
            // validate that this matches the number of entries in the pack file, according to
            // its header.
            if (indexEntryCount != packEntryCount) {
                throw new Exception("The entry count (" + indexEntryCount
                        + ") from the pack index does not match the entry count (" + packEntryCount
                        + ") from the pack file");
            }

            // in version 3 of the pack index file, the SHA1 table moves from the pack index
            // file to the pack file (necessitating a version 4 pack file, as noted earlier)
            // in versions < 3 of the index file, the SHA1 data lives in the index file in some
            // manner (differs between version 1, and versions 2,3).
            if (packindexFileVersion < 3) {
                sha1Index = Integer.MAX_VALUE;
                // read the series of 20 byte sha1 entries.
                // ours *should* be in here somewhere.. find it
                // make sure to read *all* of the entries from the file (or else seek to the end
                // of the data), so the parsing logic is not broken.
                // TODO: use a binary search to find this in a more efficient manner

                for (int i = 0; i < indexEntryCount; i++) {
                    byte[] indexEntryIdBuffer = new byte[20];
                    packindexfiledataBuffer.get(indexEntryIdBuffer);
                    String indexEntrySha1 = Hex.encodeHexString(indexEntryIdBuffer);
                    if (indexEntrySha1.equals(filesha1)) {
                        if (log.isDebugEnabled())
                            log.debug("FOUND our SHA1 " + indexEntrySha1 + " at entry " + i
                                    + " in the SHA11 table");
                        sha1Index = i;
                    }
                }
            }
            // read the CRCs for the various entries (and throw them away, for now)
            byte[] crcs = new byte[indexEntryCount * 4];
            packindexfiledataBuffer.get(crcs);

            // read the offsets for the various entries. We need to know the offset into the
            // pack file of the SHA11 entry we are looking at
            // NB: the various tables in the "pack index" file are sorted by the corresponding
            // SHA1.
            // 2 adjacent entries in the offset table (for consequtive SHA11 entries) could have
            // wildly different offsets into the "pack" file
            // and the offsets in the table are therefore not sorted by offset.
            // In order to calculate the deflated length of an entry in the pack file (which is
            // not stored anywhere),
            // we need to generate an extra offset table, ordered by the offset. We will then
            // look for the next ordered offset, and store it alongside
            // the offset of the SHA1 we're interested in.
            packEntryOffsetArray = new int[indexEntryCount];
            packEntryOffsetArrayOrdered = new int[indexEntryCount];
            for (int i = 0; i < indexEntryCount; i++) {
                packEntryOffsetArray[i] = packindexfiledataBuffer.getInt();
                packEntryOffsetArrayOrdered[i] = packEntryOffsetArray[i];
            }
        }
        // now we're out of the pack index file version 1 or 2/3 specific stuff.. the rest of
        // the logic is fairly common (except for the "pack" file version 4 stuff, of course! :)
        Arrays.sort(packEntryOffsetArrayOrdered);

        // take account of the 20 byte sha1 checksum after all the individual entries
        int nextOffset = packfiledata.length - 20;
        // get the first offset greater than the offset of our sha1. since the table is ordered
        // by offset, these 2 offsets gives us the deflated length of the entry
        for (int i = 0; i < indexEntryCount; i++) {
            if (packEntryOffsetArrayOrdered[i] > packEntryOffsetArray[sha1Index]) {
                nextOffset = packEntryOffsetArrayOrdered[i];
                // if (log.isDebugEnabled()) log.debug("Found the entry with the next offset: "+
                // nextOffset);
                if (nextOffset > (packfiledata.length - 1))
                    throw new Exception("A 'next' offset of " + nextOffset
                            + " is not feasible for a pack file with length " + packfiledata.length);
                break;
            }
        }
        // given the "pack" file offsets, we know the deflated length of the entry in there.
        int entryLength = (nextOffset - packEntryOffsetArray[sha1Index]);
        if (log.isDebugEnabled()) {
            log.debug("Our offset into the pack file is " + packEntryOffsetArray[sha1Index]);
            log.debug("The offset of the next entry into the pack file is " + nextOffset);
            log.debug("The deflated entry length, based on offset differences, is " + entryLength);
        }

        // get the data from the pack file and return it.
        byte[] inflatedData = getPackedObjectData(packfiledata, packEntryOffsetArray[sha1Index], entryLength,
                packFileVersion);
        return inflatedData;
    }
}

From source file:org.zaproxy.zap.extension.ascanrulesAlpha.HttpOnlySite.java

@Override
public void scan() {

    if (getBaseMsg().getRequestHeader().isSecure()) { // Base request is HTTPS
        if (log.isDebugEnabled()) {
            log.debug("The original request was HTTPS, so there is not much point in looking further.");
        }//www .j av a2  s .com
        return;
    }

    HttpMessage newRequest = getNewMsg();
    try {
        String host = newRequest.getRequestHeader().getURI().getHost();
        String path = newRequest.getRequestHeader().getURI().getPath();
        newRequest.getRequestHeader().setURI(new URI("https", null, host, 443, path));
    } catch (URIException e) {
        log.error("Error creating HTTPS URL from HTTP URL:", e);
        return;
    }

    if (isStop()) {
        if (log.isDebugEnabled()) {
            log.debug("Scanner " + getName() + " Stopping.");
        }
        return;
    }

    try {
        int count = 0;
        while (count < REDIR_LIMIT) {
            if (isStop()) {
                if (log.isDebugEnabled()) {
                    log.debug("Scanner " + getName() + " Stopping.");
                }
                return;
            }
            sendAndReceive(newRequest, false);
            int status = newRequest.getResponseHeader().getStatusCode();
            if (!HttpStatusCode.isRedirection(status)) {
                break;
            }
            String redirect = newRequest.getResponseHeader().getHeader(HttpResponseHeader.LOCATION);
            if (redirect == null || redirect.isEmpty()) {
                raiseAlert(newRequest, "noredirection");
                return;
            }
            URI oldURI = newRequest.getRequestHeader().getURI();
            URI newURI = constructURI(redirect, oldURI);
            if (newURI == null) {
                raiseAlert(newRequest, "urinotencoded");
                return;
            }
            newRequest.getRequestHeader().setURI(newURI);
            if (!oldURI.getHost().equals(newURI.getHost())) {
                raiseAlert(newRequest, "differenthosts");
                return;
            }
            if (newRequest.getRequestHeader().isSecure()) {
                count++;
            } else {
                raiseAlert(newRequest, "redirecttohttp");
                return;
            }
        }
        if (count == REDIR_LIMIT) { // When redirection limit is exceeded
            raiseAlert(newRequest, "redirectionlimit");
            return;
        }
    } catch (SocketException | SocketTimeoutException e) {
        raiseAlert(newRequest, "connectionfail");
        return;
    } catch (SSLException e) {
        if (e.getMessage().contains("plaintext")) {
            raiseAlert(newRequest, "nossl");
        }
        return;
    } catch (IOException e) {
        log.error("Request couldn't go through:", e);
        return;
    }
}

From source file:org.zaproxy.zap.extension.ascanrulesAlpha.RelativePathConfusionScanner.java

@Override
public void scan() {

    // get the base message. What else did you think this line of code might do??
    HttpMessage originalMsg = getBaseMsg();

    if (log.isDebugEnabled()) {
        log.debug("Attacking at Attack Strength: " + this.getAttackStrength());
        log.debug("Checking [" + originalMsg.getRequestHeader().getMethod() + "] ["
                + originalMsg.getRequestHeader().getURI() + "], for Relative Path Confusion issues");
    }//from  w  w w. jav  a  2s .  c om

    try {
        URI baseUri = originalMsg.getRequestHeader().getURI();
        String filename = baseUri.getName();
        String fileext = "";

        // is there a file extension at the end of the file name?
        if (filename != null && filename.length() > 0) {
            fileext = FilenameUtils.getExtension(filename);
        }

        // only filenames that have a file extension are potentially vulnerable to Relative Path
        // Confusion
        // (based on the instances of this that I've in seen in the wild, at least)
        if (fileext != null && fileext.length() > 0) {
            if (log.isDebugEnabled())
                log.debug("The file extension of " + baseUri.getURI() + " is " + fileext);

            // 1: First manipulate the URL, using a URL which is ambiguous..
            URI originalURI = originalMsg.getRequestHeader().getURI();
            String path = originalURI.getPath();
            if (path == null)
                path = "";
            String query = originalURI.getQuery();
            if (query == null)
                query = "";

            URI hackedUri = new URI(originalURI.getScheme(), originalURI.getAuthority(),
                    path + RANDOM_ATTACK_PATH + "?" + query, null, null);
            HttpMessage hackedMessage = new HttpMessage(hackedUri);
            try {
                hackedMessage.setCookieParams(originalMsg.getCookieParams());
            } catch (Exception e) {
                log.warn("Could not set the cookies from the base request:" + e);
            }
            try {
                sendAndReceive(hackedMessage, true); // follow redirects
            } catch (CircularRedirectException e) {
                log.warn("Ignoring a CircularRedirectException" + e);
            }

            // get ready to parse the HTML
            Document doc = Jsoup.parse(new String(hackedMessage.getResponseBody().getBytes()));
            String extraInfo = null;

            // 2: check if the response has a "<base>" tag specifying the base location for any
            // relative URLs
            // there can be a max of 1 <base> element in a document, and it must be inside the
            // <head> element
            // Example: <head><base href="http://www.w3schools.com/images/"
            // target="_blank"></head>
            Elements baseHrefInstances = doc.select("html > head > base[href]");
            if (!baseHrefInstances.isEmpty() && baseHrefInstances.size() == 1) {
                // a single base was specified, in line with HTTP spec
                if (log.isDebugEnabled())
                    log.debug(
                            "A base was specified, so there should be no confusion over relative paths (unless the User Agent is completely broken)");
                return;
            } else {
                if (!baseHrefInstances.isEmpty() && baseHrefInstances.size() > 1) {
                    extraInfo = Constant.messages.getString(MESSAGE_PREFIX + "extrainfo.morethanonebasetag");
                    if (log.isDebugEnabled())
                        log.debug("There more than one base (which is not valid HTML) specified for the page");
                } else {
                    if (extraInfo == null)
                        extraInfo = Constant.messages.getString(MESSAGE_PREFIX + "extrainfo.nobasetag");
                    if (log.isDebugEnabled())
                        log.debug("There is no base specified for the page");
                }
            }

            // 3: check if there are any resources that are loaded using relative URLs in the
            // response. (images, CSS, etc)
            boolean relativeReferenceFound = false;
            String relativeReferenceEvidence = "";

            Set<String> loadingHtmlAttributes = RELATIVE_LOADING_ATTRIBUTE_TO_TAGS.keySet();
            Iterator<String> i = loadingHtmlAttributes.iterator();
            for (; i.hasNext() && !relativeReferenceFound;) {
                String loadingHtmlAttribute = i.next();
                String[] loadingHtmlTags = RELATIVE_LOADING_ATTRIBUTE_TO_TAGS.get(loadingHtmlAttribute);

                for (int tagIndex = 0; tagIndex < loadingHtmlTags.length
                        && !relativeReferenceFound; tagIndex++) {
                    String tag = loadingHtmlTags[tagIndex];

                    // get instances of the specified HTML attribute and tag from the original
                    // response
                    // and see if is loading a relative URL.
                    // (ie, could it be confused if the server side can confuse the client side
                    // as to the absolute path to use when loading)
                    String selectStatement = (tag.equals("") ? "" : tag)
                            + (loadingHtmlAttribute.equals("") ? "" : "[" + loadingHtmlAttribute + "]");
                    Elements loadingTagInstances = doc.select(selectStatement);
                    int size = loadingTagInstances.size();

                    for (int index = 0; index < size && !relativeReferenceFound; index++) {
                        Element tagInstance = loadingTagInstances.get(index);

                        // handle style tags differently to other tags (for which we look at an
                        // attribute)
                        if (tag.toUpperCase().equals("STYLE")) {
                            // for the style tag, look at the entire body, not an attribute..
                            String styleBody = tagInstance.data();
                            if (log.isDebugEnabled())
                                log.debug("Got <style> data: " + styleBody);
                            Matcher matcher = STYLE_URL_LOAD.matcher(styleBody);
                            if (matcher.find()) {
                                relativeReferenceFound = true;
                                relativeReferenceEvidence = matcher.group();
                                if (log.isDebugEnabled())
                                    log.debug("Got relative STYLE reference in a style tag. Evidence: "
                                            + relativeReferenceEvidence);
                            }
                        } else {
                            // it's not the style tag, so look at the named attribute.
                            String attributeValue = tagInstance.attr(loadingHtmlAttribute);

                            if (log.isDebugEnabled())
                                log.debug("Got " + attributeValue + " for statement " + selectStatement);

                            // is it a relative reference?
                            String attributeUpper = attributeValue.toUpperCase().trim();
                            // if the reference starts with a scheme, it's absolute
                            // if it starts with "/", it's probably an absolute path (the host
                            // and scheme are inferred)
                            // if it starts with "//, it's a reference to the host and path (but
                            // not the scheme), and it's essentially an absolute reference..
                            if (!loadingHtmlAttribute.equals("style")) {
                                if (!attributeUpper.startsWith("HTTP://")
                                        && !attributeUpper.startsWith("HTTPS://")
                                        && !attributeUpper.startsWith("/")) {
                                    // it's a relative reference..
                                    relativeReferenceFound = true;
                                    // Note: since we parsed the HTML, and are reconstructing
                                    // the tag, this value may not exactly mirror the original
                                    // value in the HTML, but it's better than nothing. Whatcha
                                    // gonna do?
                                    // relativeReferenceEvidence = "<"+ tag + " " +
                                    // loadingHtmlAttribute + "=\"" + attributeValue + "\"";
                                    relativeReferenceEvidence = tagInstance.outerHtml();

                                    if (log.isDebugEnabled())
                                        log.debug("Got relative reference: " + attributeValue
                                                + " for statement " + selectStatement + ". Evidence: "
                                                + relativeReferenceEvidence);
                                }
                            } else {
                                // for the style attribute (on various tags), look for a pattern
                                // like "background: url(image.png)"
                                Matcher matcher = STYLE_URL_LOAD.matcher(attributeUpper);
                                if (matcher.find()) {
                                    relativeReferenceFound = true;
                                    relativeReferenceEvidence = attributeValue; // matcher.group();
                                    if (log.isDebugEnabled())
                                        log.debug("Got relative STYLE reference: " + attributeValue + " for "
                                                + tag + "." + loadingHtmlAttribute + ". Evidence: "
                                                + relativeReferenceEvidence);
                                }
                            }
                        }
                    }
                }
            }
            // TODO: what if the relative reference is occurring in the JavaScript??
            // if there are no relative references in the response, bale out, because there is
            // nothing to worry about
            if (!relativeReferenceFound) {
                if (log.isDebugEnabled())
                    log.debug(
                            "No relative references were found in the original response, so there is no possibility for confusion over relative path references)");
                return;
            }

            // 4: Now check the content type of the response.
            // If no Content Type was specified, happy days, we can move to the next check in
            // the knowledge that the content can
            // be interpreted a non-HTML content type by the web browser, if we can fool the
            // browser into loading the page.
            // If a content type is "Content-Type: text/html", we need to see if there is a way
            // to override the Content Type.
            // Known ways are:
            // a: Get the browser to render in Quirks Mode
            //      Note 1: Quirks mode might have been set in the response, without us having to do
            // anything else.. check!
            //      Note 2: Quirks mode is set if the response does not set a doctype, or uses an
            // old doctype
            //      Note 3: If quirks mode is not enabled, we may be able to enable it by setting it
            // on a framing page (if the page in question allows framing)
            //
            // TODO: Pass in a random filename (something like the
            // aaa/bbb/blah.php/xxx/yyy/zzz?a=1&b=2 request we use here)
            //       that ends in ".css", to see if the web server changes the content type to
            // "text/css" (unlikely!)
            String contentType = hackedMessage.getResponseHeader().getHeader(HttpHeader.CONTENT_TYPE);
            if (contentType != null) {

                if (log.isDebugEnabled())
                    log.debug("Content Type is set, so we need to see if there is a way to bypass it");
                boolean quirksMode = false;
                if (extraInfo == null)
                    extraInfo = Constant.messages.getString(MESSAGE_PREFIX + "extrainfo.contenttypeenabled",
                            contentType);
                else
                    extraInfo += "\n" + Constant.messages
                            .getString(MESSAGE_PREFIX + "extrainfo.contenttypeenabled", contentType);

                // a: Quirks mode!
                // Is it already enabled?
                // In the HEAD.. (Note: X-UA-Compatible trumps the doctype in IE)
                // <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
                // <meta http-equiv="X-UA-Compatible" content="IE=8" />
                // <meta http-equiv="x-ua-compatible" content="IE=9">
                // <meta http-equiv="x-ua-compatible" content="IE=edge" >   sets the page to
                // HTML5 mode, not quirks mode!!!

                // HTML 5: <!doctype html>                           sets the page to HTML5 mode

                Elements httpEquivInstances = doc.select("html > head > meta[http-equiv]");
                int size = httpEquivInstances.size();

                for (int index = 0; index < size; index++) {
                    Element e = httpEquivInstances.get(index);
                    String httpEquivAttributeValue = e.attr("http-equiv");
                    String contentAttributeValue = e.attr("content");

                    if (log.isDebugEnabled())
                        log.debug("Got " + httpEquivAttributeValue + " for html > head > meta[http-equiv]");
                    if (httpEquivAttributeValue.toUpperCase().trim().equals("X-UA-COMPATIBLE")
                            && !contentAttributeValue.toUpperCase().trim().equals("IE=EDGE")) {
                        // Quirks mode is already enabled!
                        // Note: if this is present, it overrides any "<!doctype html>" that
                        // would otherwise set the page to HTML5 mode
                        quirksMode = true;
                        if (log.isDebugEnabled())
                            log.debug(
                                    "Quirks mode is explicitly enabled via <meta http-equiv=\"x-ua-compatible\" (which overrides any \"<!doctype html>\" HTML 5 directive) ... This allows the specified Content Type to be bypassed");
                        if (extraInfo == null)
                            extraInfo = Constant.messages.getString(
                                    MESSAGE_PREFIX + "extrainfo.quirksmodeenabledexplicitly",
                                    httpEquivAttributeValue);
                        else
                            extraInfo += "\n" + Constant.messages.getString(
                                    MESSAGE_PREFIX + "extrainfo.quirksmodeenabledexplicitly",
                                    httpEquivAttributeValue);
                    }
                }
                // is quirks mode implicitly enabled via the absence of a doctype?
                // is quirks mode implicitly enabled via an old doctype?
                if (!quirksMode) {
                    boolean docTypeSpecified = false;
                    List<Node> nodes = doc.childNodes();
                    for (Node node : nodes) {
                        if (node instanceof DocumentType) {
                            docTypeSpecified = true;
                            DocumentType documentType = (DocumentType) node;
                            String docTypePublicId = documentType.attr("publicid");
                            // is the doctype old enough to enable quirks mode?
                            for (String doctypePublicIdTiggerQuirks : DOCTYPE_PUBLIC_IDS_TRIGGERING_QUIRKS_MODE) {
                                if (docTypePublicId.toUpperCase()
                                        .equals(doctypePublicIdTiggerQuirks.toUpperCase())) {
                                    // this doctype is know to trigger quirks mode in some
                                    // browsers..
                                    quirksMode = true;
                                    if (log.isDebugEnabled())
                                        log.debug(
                                                "Quirks mode is implicitly triggered via the use of old doctype "
                                                        + docTypePublicId
                                                        + ". This allows the specified Content Type to be bypassed");
                                    if (extraInfo == null)
                                        extraInfo = Constant.messages.getString(
                                                MESSAGE_PREFIX + "extrainfo.quirksmodeenabledimplicitly",
                                                docTypePublicId);
                                    else
                                        extraInfo += "\n" + Constant.messages.getString(
                                                MESSAGE_PREFIX + "extrainfo.quirksmodeenabledimplicitly",
                                                docTypePublicId);
                                    break;
                                }
                            }
                            if (log.isDebugEnabled())
                                log.debug("DocType public id: " + docTypePublicId + ". Entire thing: "
                                        + documentType);
                        }
                    }
                    if (!docTypeSpecified) {
                        quirksMode = true;
                        if (log.isDebugEnabled())
                            log.debug(
                                    "Quirks mode is implicitly enabled via the absence of a doctype... This allows the specified Content Type to be bypassed");
                        if (extraInfo == null)
                            extraInfo = Constant.messages.getString(
                                    MESSAGE_PREFIX + "extrainfo.quirksmodeenabledimplicitlynodoctype");
                        else
                            extraInfo += "\n" + Constant.messages.getString(
                                    MESSAGE_PREFIX + "extrainfo.quirksmodeenabledimplicitlynodoctype");
                    }
                }

                // if quirksMode is enabled, we do not need to check to see if framing attacks
                // are feasible
                boolean framingAttackPossible = false;
                if (!quirksMode) {
                    // if the framing attack does not work, check for a framing attack
                    String frameHeader = hackedMessage.getResponseHeader().getHeader(HttpHeader.X_FRAME_OPTION);
                    if (frameHeader != null) {
                        if (frameHeader.toUpperCase().equals("DENY")) {
                            // definitely rules out the framing attack (unless the user is using
                            // a dozy web browser that doesn't understand "X-FRAME-OPTIONS:
                            // DENY")
                            framingAttackPossible = false;
                            if (log.isDebugEnabled())
                                log.debug(
                                        "\"X-FRAME-OPTIONS: DENY\" rules out a framing attack, unless a really old browser is used (IE < 8.0, for instance)");
                        } else if (frameHeader.toUpperCase().equals("SAMEORIGIN")) {
                            // let's say this rules it out (unless the attacker has a persistent
                            // XSS, or already owns the site)
                            framingAttackPossible = false;
                            if (log.isDebugEnabled())
                                log.debug(
                                        "\"X-FRAME-OPTIONS: SAMEORIGIN\" rules out a framing attack, unless a really old browser is used (IE < 8.0, for instance)");
                        } else if (frameHeader.toUpperCase().startsWith("ALLOW-FROM")) {
                            // let's say this rules it out (unless the attacker has a persistent
                            // XSS, or already owns the site)
                            framingAttackPossible = false;
                            if (log.isDebugEnabled())
                                log.debug(
                                        "\"X-FRAME-OPTIONS: ALLOW-FROM\" probably rules out a framing attack, unless the attacker owns the website in the ALLOW-FROM, which is generally very unlikely");
                        }
                    } else {
                        // no framing headers were specified, so a framing attack is possible to
                        // force quicks mode, to bypass the Content-Type, which was specified
                        framingAttackPossible = true;
                        if (extraInfo == null)
                            extraInfo = Constant.messages
                                    .getString(MESSAGE_PREFIX + "extrainfo.framingallowed");
                        else
                            extraInfo += "\n"
                                    + Constant.messages.getString(MESSAGE_PREFIX + "extrainfo.framingallowed");
                    }
                }

                // if quirks mode is off, and a framing attack is not possible, we can't "break
                // out" of the content type.. boo hoo..
                if ((!quirksMode) && (!framingAttackPossible)) {
                    if (log.isDebugEnabled())
                        log.debug(
                                "Can't see a way to break out of the Content-Type, since Quirks mode is off (both explicit and implicit), and the page cannot be framed.");
                    return;
                }
            } else {
                // happy days. Content type is not set, so no hacks required to bypass it.
                if (log.isDebugEnabled())
                    log.debug("Content Type is not set, so no hacks are required to bypass it!");
                if (extraInfo == null)
                    extraInfo = Constant.messages.getString(MESSAGE_PREFIX + "extrainfo.nocontenttype");
                else
                    extraInfo += "\n" + Constant.messages.getString(MESSAGE_PREFIX + "extrainfo.nocontenttype");
            }

            // alert it..
            bingo(getRisk(), Alert.CONFIDENCE_MEDIUM, getName(), getDescription(),
                    getBaseMsg().getRequestHeader().getURI().getURI(), null, // parameter being attacked: none.
                    hackedUri.getURI(), // the attack is the URL itself
                    extraInfo, getSolution(), relativeReferenceEvidence, this.getCweId(), this.getWascId(),
                    hackedMessage);

            if (log.isDebugEnabled()) {
                log.debug("A Relative Path Confusion issue exists on "
                        + getBaseMsg().getRequestHeader().getURI().getURI());
            }
            return;

        } else {
            if (log.isDebugEnabled()) {
                log.debug(
                        "The URI has no filename component, so there is unlikely to be any ambiguity over any relative paths");
            }
        }
    } catch (Exception e) {
        log.error("Error scanning a request for Relative Path confusion: " + e.getMessage(), e);
    }
}

From source file:org.zaproxy.zap.extension.ascanrulesAlpha.SourceCodeDisclosureGit.java

/**
 * finds the source code for the given file, using Git metadata on the server (if this is
 * available)/*from   ww  w.j  ava2s. c  o  m*/
 *
 * @param uri the URI of a file, whose source code we want to find
 * @return Did we find the source code?
 */
private boolean findSourceCodeGit(HttpMessage originalMessage) throws Exception {
    byte[] disclosedData = {};
    String gitsha1 = null;
    String gitindexpath = null;
    try {
        URI originalURI = originalMessage.getRequestHeader().getURI();
        // String originalURIWithoutQuery = originalURI.getScheme() + "://" +
        // originalURI.getAuthority() + originalURI.getPath();
        // String canonicalisedOriginalURIStringWithoutQuery =
        // URLCanonicalizer.getCanonicalURL(originalURIWithoutQuery);
        String path = originalURI.getPath();
        if (path == null)
            path = "";
        String filename = originalURI.getName();

        String fileExtension = null;
        if (filename.contains(".")) {
            fileExtension = filename.substring(filename.lastIndexOf(".") + 1);
            fileExtension = fileExtension.toUpperCase();
        }

        URI originalURIWithoutQuery = new URI(originalURI.getScheme(), originalURI.getAuthority(), path, null,
                null);
        GitMetadata git = new GitMetadata(this.getParent(), 4096);
        GitIndexEntryCache gitindexentrycache = GitIndexEntryCache.getSingleton();

        // look for the .git/index file in the directory and parent directories of the file for
        // which we are attempting to get the source code.
        String modifiedpath = path;
        byte[] data = {};
        boolean gitSHA1located = false;
        // work backwards from the original path, stripping off one folder at a time
        // until we find a valid Git index file that contains our file name!
        modifiedpath = modifiedpath.substring(0, modifiedpath.lastIndexOf("/") + 1); // leave the trailing slash on, if there was one
        while ((!modifiedpath.equals("")) && (!gitSHA1located)) {

            if (log.isDebugEnabled())
                log.debug("Path is " + modifiedpath);

            gitindexpath = modifiedpath + ".git/index";

            URI gitindexuri = new URI(originalURI.getScheme(), originalURI.getAuthority(), gitindexpath, null,
                    null);
            try {
                if (log.isDebugEnabled())
                    log.debug("Trying for a Git index file " + gitindexuri.getURI());

                if (!gitindexentrycache.isIndexCached(gitindexuri)) {
                    // The Git index is not cached, so parse it and cache it.
                    if (log.isDebugEnabled())
                        log.debug("Git Index " + gitindexuri.getURI()
                                + " is not cached. We will parse and cache it");

                    data = git.getURIResponseBody(gitindexuri, false, originalMessage);
                    // get the list of relative file paths and Git SHA1s from the file
                    Map<String, String> gitFiles = git.getIndexSha1s(data);
                    if (gitFiles != null) {
                        if (log.isDebugEnabled())
                            log.debug("We found a Git index file at '" + gitindexpath + "'");

                        Set<Entry<String, String>> entrySet = gitFiles.entrySet();
                        Iterator<Entry<String, String>> entryIterator = entrySet.iterator();
                        while (entryIterator.hasNext()) {
                            Entry<String, String> gitIndexEntry = entryIterator.next();

                            // the URIs from the Git index file do not have a query or fragment
                            // component, so no need to strip those off here
                            URI gitIndexEntryUri = new URI(originalURI.getScheme(), originalURI.getAuthority(),
                                    modifiedpath + gitIndexEntry.getKey(), null, null);
                            String gitSHA1Temp = gitIndexEntry.getValue();

                            // cache the entry..
                            if (log.isDebugEnabled())
                                log.debug("Caching Git Index file " + gitindexuri.getURI() + ", Index Entry "
                                        + gitIndexEntryUri.getURI() + ", SHA1 " + gitSHA1Temp);
                            gitindexentrycache.putIndexEntry(gitindexuri, gitIndexEntryUri, gitSHA1Temp);
                        }
                    }
                }
                // at this point, we know the Git index file is cached, one way or another.
                // did we get the Git SHA1 of the file we were interested in, after all that?
                if (gitindexentrycache.isIndexEntryCached(gitindexuri, originalURIWithoutQuery)) {
                    // no need to keep on looping back up, if we found our entry
                    gitSHA1located = true;
                    gitsha1 = gitindexentrycache.getIndexEntry(gitindexuri, originalURIWithoutQuery);
                    log.debug("Git SHA1 '" + gitsha1 + "' was found for Git index file '" + gitindexuri
                            + ", Git index entry file '" + originalURIWithoutQuery + "'");
                    break;
                } else {
                    log.debug("A cache entry was not found for Git index file '" + gitindexuri
                            + ", Git index entry file '" + originalURIWithoutQuery + "'");
                }

            } catch (Exception e) {
                if (log.isDebugEnabled())
                    log.debug("Ignoring an error getting/parsing '" + gitindexpath
                            + "', while trying to find the Git SHA1 value for '" + path + "': " + e);
            } finally {
                // move to the next parent directory, by first stripping off the trailing index,
                // and grabbing up to and including the last index
                modifiedpath = modifiedpath.substring(0, modifiedpath.length() - 1);
                modifiedpath = modifiedpath.substring(0, modifiedpath.lastIndexOf("/") + 1); // leave the trailing slash on, if there was one
            }

            if (isStop()) {
                if (log.isDebugEnabled())
                    log.debug(
                            "Stopped scanner (while trying to find the Git index file), due to a user request");
                return false;
            }
        }

        // do we have a shot at getting the source code using Git?
        if (gitsha1 == null || gitsha1.equals("") || gitindexpath == null || gitindexpath.equals("")) {
            if (log.isDebugEnabled())
                log.debug("A Git SHA1 value or Git index path for '" + path + "' was not found.");
            return false;
        }
        if (!git.validateSHA1(gitsha1)) {
            if (log.isDebugEnabled())
                log.debug("The 'gitsha1' parameter '" + gitsha1
                        + "' does not appear to be a valid format for a Git SHA1 value");
            return false;
        }
        String gitbasepath = git.getBaseFolder(gitindexpath);
        if (gitbasepath == null || gitbasepath.equals("")) {
            if (log.isDebugEnabled())
                log.debug("The 'gitindexpath' parameter '" + gitbasepath + "' does not appear to be valid.");
            return false;
        }
        // get the data from Git, using its SHA1 value.
        disclosedData = git.getObjectData(this.getBaseMsg(), gitbasepath, gitsha1); // look for data for the file's Git SHA1, and inflate it
        String gitURIs = git.getGitURIs();

        // so we have the data from Git for the sha1/file in questions.. does it match the
        // original data?
        // if not (but if it still looks valid), then throw a "source code disclosure" alert
        if (!Arrays.equals(disclosedData, originalMessage.getResponseBody().getBytes())) {

            // check the contents of the output to some degree, if we have a file extension.
            // if not, just try it (could be a false positive, but hey)
            if (dataMatchesExtension(disclosedData, fileExtension)) {
                if (log.isDebugEnabled()) {
                    log.debug("Source code disclosure, using Git metadata leakage!");
                }

                // source file inclusion attack. alert it.
                // Note that, unlike with SVN, the Git data is extracted not from one file, but
                // by parsing a series of files.
                // we cannot meaningfully raise an alert on any one file, except perhaps the
                // file on which the attack was launched.
                // it's the least worst way of doing it, IMHO.
                bingo(Alert.RISK_HIGH, Alert.CONFIDENCE_MEDIUM, getName(), getDescription(),
                        getBaseMsg().getRequestHeader().getURI().getURI(), null, // parameter being attacked: none.
                        null, // attack
                        new String(disclosedData), // Constant.messages.getString("ascanalpha.sourcecodedisclosure.gitbased.extrainfo", filename, StringUtils.join(gitURIs,", ")),     //extraInfo
                        getSolution(), getEvidence(filename, gitURIs), originalMessage);
                return true;
            }
            // does not match the extension
            return false;
        } else {
            if (log.isDebugEnabled())
                log.debug(
                        "The data disclosed via Git meta-data is not source code, since it matches the data served when we requested the file in the normal manner (source code is not served by web apps, and if it is, then you have bigger problems)");
            return false;
        }
    } catch (FileNotFoundException e) {
        if (log.isDebugEnabled())
            log.debug("A file was not found for SHA1 '" + gitsha1 + "'");
        return false;
    } catch (Exception e) {
        log.error("Some other error occurred when reading data for Git SHA1 '" + gitsha1 + "': " + e);
        return false;
    }
}

From source file:org.zaproxy.zap.extension.ascanrulesAlpha.SourceCodeDisclosureSVN.java

/**
 * finds the source code for the given file, using SVN metadata on the server (if this is available)
 * @param uri the URI of a file, whose source code we want to find
 * @return Did we find the source code?//from ww  w.  j a v a  2s.  c o  m
 */
private boolean findSourceCodeSVN(HttpMessage originalMessage) throws Exception {

    URI uri = originalMessage.getRequestHeader().getURI();
    String path = uri.getPath();
    if (path == null)
        path = "";
    //String filename = path.substring( path.lastIndexOf('/')+1, path.length() );
    String filename = uri.getName();

    String fileExtension = null;
    if (filename.contains(".")) {
        fileExtension = filename.substring(filename.lastIndexOf(".") + 1);
        fileExtension = fileExtension.toUpperCase();
    }

    //Look for SVN metadata containing source code
    String pathminusfilename = path.substring(0, path.lastIndexOf(filename));

    HttpMessage svnsourcefileattackmsg = new HttpMessage(new URI(uri.getScheme(), uri.getAuthority(),
            pathminusfilename + ".svn/text-base/" + filename + ".svn-base", null, null));
    svnsourcefileattackmsg.setCookieParams(this.getBaseMsg().getCookieParams());
    //svnsourcefileattackmsg.setRequestHeader(this.getBaseMsg().getRequestHeader());
    sendAndReceive(svnsourcefileattackmsg);

    //if we got a 404 specifically, then this is NOT a match
    //note that since we are simply relying on the file existing or not, we 
    //will not attempt any fuzzy matching. Old school.
    //this check is necessary, otherwise a recursive scan on nodes in the url path cause lots of false positives.
    if (svnsourcefileattackmsg.getResponseHeader().getStatusCode() != HttpStatusCode.NOT_FOUND) {

        if (!Arrays.equals(svnsourcefileattackmsg.getResponseBody().getBytes(),
                originalMessage.getResponseBody().getBytes())) {

            String attackFilename = uri.getScheme() + "://" + uri.getAuthority() + pathminusfilename
                    + ".svn/text-base/" + filename + ".svn-base";

            //check the contents of the output to some degree, if we have a file extension.
            //if not, just try it (could be a false positive, but hey)             
            if (dataMatchesExtension(svnsourcefileattackmsg.getResponseBody().getBytes(), fileExtension)) {
                log.info("Source code disclosure, using SVN metadata leakage!");

                //if we get to here, is is very likely that we have source file inclusion attack. alert it.
                bingo(Alert.RISK_HIGH, Alert.WARNING,
                        Constant.messages.getString("ascanalpha.sourcecodedisclosure.svnbased.name"),
                        Constant.messages.getString("ascanalpha.sourcecodedisclosure.desc"),
                        getBaseMsg().getRequestHeader().getURI().getURI(), null, attackFilename,
                        Constant.messages.getString("ascanalpha.sourcecodedisclosure.svnbased.extrainfo",
                                filename, attackFilename),
                        Constant.messages.getString("ascanalpha.sourcecodedisclosure.svnbased.soln"),
                        Constant.messages.getString("ascanalpha.sourcecodedisclosure.svnbased.evidence"),
                        svnsourcefileattackmsg);
                //if we found one, do not even try the "super" method, which tries each of the parameters,
                //since this is slow, and we already found an instance
                return true;
            } else {
                if (log.isDebugEnabled())
                    log.debug("The HTML output does not look like source code of type " + fileExtension);
            }
        } else {
            if (log.isDebugEnabled())
                log.debug(
                        "The data disclosed via SVN meta-data is not source code, since it matches the data served when we requested the file in the normal manner (source code is not served by web apps, and if it is, then you have bigger problems)");
            return false;
        }
    } else {
        if (log.isDebugEnabled()) {
            log.debug("Got a 404, so the SVN source code file was not found");
        }
    }
    return false;
}