use of org.zaproxy.zap.model.StructuralNode in project zaproxy by zaproxy.
the class HostProcess method processPlugin.
private void processPlugin(final Plugin plugin) {
synchronized (mapPluginStats) {
mapPluginStats.put(plugin.getId(), new PluginStats());
}
if (!plugin.targets(techSet)) {
pluginSkipped(plugin, Constant.messages.getString("ascan.progress.label.skipped.reason.techs"));
pluginCompleted(plugin);
return;
}
log.info("start host " + hostAndPort + " | " + plugin.getCodeName() + " strength " + plugin.getAttackStrength() + " threshold " + plugin.getAlertThreshold());
for (StructuralNode startNode : startNodes) {
if (plugin instanceof AbstractHostPlugin) {
if (!scanSingleNode(plugin, startNode)) {
// Mark the plugin as as completed if it was not run so the scan process can continue as expected.
// The plugin might not be run if the startNode: is not in scope, is explicitly excluded, ...
pluginCompleted(plugin);
}
} else if (plugin instanceof AbstractAppPlugin) {
try {
traverse(startNode, true, new TraverseAction() {
@Override
public void apply(StructuralNode node) {
log.debug("traverse: plugin=" + plugin.getName() + " url=" + node.getName());
scanSingleNode(plugin, node);
}
@Override
public boolean isStopTraversing() {
return isSkipped(plugin);
}
});
threadPool.waitAllThreadComplete(600000);
} finally {
pluginCompleted(plugin);
}
}
}
}
use of org.zaproxy.zap.model.StructuralNode in project zaproxy by zaproxy.
the class Scanner method scan.
public void scan(Target target) {
Thread thread = null;
this.setScanChildren(target.isRecurse());
this.setJustScanInScope(target.isInScopeOnly());
if (target.getStartNodes() != null) {
HostProcess hostProcess = null;
List<StructuralNode> nodes = target.getStartNodes();
if (nodes.size() == 1 && nodes.get(0).isRoot()) {
Iterator<StructuralNode> iter = nodes.get(0).getChildIterator();
while (iter.hasNext()) {
StructuralNode child = iter.next();
String hostAndPort = getHostAndPort(child);
hostProcess = new HostProcess(hostAndPort, this, scannerParam, connectionParam, scanPolicy, ruleConfigParam);
hostProcess.setStartNode(child);
hostProcess.setUser(this.user);
hostProcess.setTechSet(this.techSet);
this.hostProcesses.add(hostProcess);
do {
thread = pool.getFreeThreadAndRun(hostProcess);
if (thread == null)
Util.sleep(500);
} while (thread == null && !isStop());
if (thread != null) {
notifyHostNewScan(hostAndPort, hostProcess);
}
}
} else {
Map<String, HostProcess> processMap = new HashMap<String, HostProcess>();
for (StructuralNode node : nodes) {
// Loop through the nodes creating new HostProcesss's as required
String hostAndPort = getHostAndPort(node);
hostProcess = processMap.get(hostAndPort);
if (hostProcess == null) {
hostProcess = new HostProcess(hostAndPort, this, scannerParam, connectionParam, scanPolicy, ruleConfigParam);
hostProcess.setStartNode(node);
hostProcess.setUser(this.user);
hostProcess.setTechSet(this.techSet);
processMap.put(hostAndPort, hostProcess);
} else {
hostProcess.addStartNode(node);
}
}
// Now start them all off
for (Entry<String, HostProcess> pmSet : processMap.entrySet()) {
this.hostProcesses.add(pmSet.getValue());
thread = pool.getFreeThreadAndRun(pmSet.getValue());
notifyHostNewScan(pmSet.getKey(), pmSet.getValue());
}
}
} else if (target.getContext() != null) {
// TODO need to change for lowmem
if (Constant.isLowMemoryOptionSet()) {
throw new InvalidParameterException("Not yet supported for the low memory option :(");
}
List<SiteNode> nodes = target.getContext().getTopNodesInContextFromSiteTree();
for (SiteNode node : nodes) {
HostProcess hostProcess = null;
String hostAndPort = getHostAndPort(node);
hostProcess = new HostProcess(hostAndPort, this, scannerParam, connectionParam, scanPolicy, ruleConfigParam);
hostProcess.setStartNode(new StructuralSiteNode(node));
hostProcess.setUser(this.user);
hostProcess.setTechSet(this.techSet);
this.hostProcesses.add(hostProcess);
do {
thread = pool.getFreeThreadAndRun(hostProcess);
if (thread == null)
Util.sleep(500);
} while (thread == null && !isStop());
if (thread != null) {
notifyHostNewScan(hostAndPort, hostProcess);
}
}
} else if (target.isInScopeOnly()) {
// TODO need to change for lowmem
if (Constant.isLowMemoryOptionSet()) {
throw new InvalidParameterException("Not yet supported for the low memory option :(");
}
this.justScanInScope = true;
List<SiteNode> nodes = Model.getSingleton().getSession().getTopNodesInScopeFromSiteTree();
for (SiteNode node : nodes) {
HostProcess hostProcess = null;
String hostAndPort = getHostAndPort(node);
hostProcess = new HostProcess(hostAndPort, this, scannerParam, connectionParam, scanPolicy, ruleConfigParam);
hostProcess.setStartNode(new StructuralSiteNode(node));
hostProcess.setUser(this.user);
hostProcess.setTechSet(this.techSet);
this.hostProcesses.add(hostProcess);
do {
thread = pool.getFreeThreadAndRun(hostProcess);
if (thread == null)
Util.sleep(500);
} while (thread == null && !isStop());
if (thread != null) {
notifyHostNewScan(hostAndPort, hostProcess);
}
}
}
}
use of org.zaproxy.zap.model.StructuralNode in project zaproxy by zaproxy.
the class SpiderAPI method scanURL.
/**
* Starts a spider scan at the given {@code url} and, optionally, with the perspective of the given {@code user}.
*
* @param url the url to start the spider scan
* @param user the user to scan as, or null if the scan is done without the perspective of any user
* @param maxChildren Max number of children to scan
* @param recurse Whether or not to scan recursively
* @param context the context that will be used during spider process, might be {@code null}
* @param subtreeOnly if the scan should be done only under a site's subtree
* @return the ID of the newly started scan
* @throws ApiException if the {@code url} is not valid
*/
private int scanURL(String url, User user, int maxChildren, boolean recurse, Context context, boolean subtreeOnly) throws ApiException {
log.debug("API Spider scanning url: " + url);
boolean useUrl = true;
if (url == null || url.isEmpty()) {
if (context == null || !context.hasNodesInContextFromSiteTree()) {
throw new ApiException(Type.MISSING_PARAMETER, PARAM_URL);
}
useUrl = false;
} else if (context != null && !context.isInContext(url)) {
throw new ApiException(Type.URL_NOT_IN_CONTEXT, PARAM_URL);
}
StructuralNode node = null;
URI startURI = null;
if (useUrl) {
try {
// Try to build uri
startURI = new URI(url, true);
} catch (URIException e) {
throw new ApiException(ApiException.Type.ILLEGAL_PARAMETER, PARAM_URL);
}
String scheme = startURI.getScheme();
if (scheme == null || (!scheme.equalsIgnoreCase("http") && !scheme.equalsIgnoreCase("https"))) {
throw new ApiException(ApiException.Type.ILLEGAL_PARAMETER, PARAM_URL);
}
try {
node = SessionStructure.find(Model.getSingleton().getSession().getSessionId(), new URI(url, false), "GET", "");
} catch (Exception e) {
throw new ApiException(ApiException.Type.INTERNAL_ERROR);
}
}
Target target;
if (useUrl) {
target = new Target(node);
target.setContext(context);
} else {
target = new Target(context);
}
target.setRecurse(recurse);
switch(Control.getSingleton().getMode()) {
case safe:
throw new ApiException(ApiException.Type.MODE_VIOLATION);
case protect:
if ((useUrl && !Model.getSingleton().getSession().isInScope(url)) || (context != null && !context.isInScope())) {
throw new ApiException(ApiException.Type.MODE_VIOLATION);
}
// No problem
break;
case standard:
// No problem
break;
case attack:
// No problem
break;
}
List<Object> objs = new ArrayList<>(4);
if (startURI != null) {
objs.add(startURI);
if (subtreeOnly) {
objs.add(new HttpPrefixFetchFilter(startURI));
}
}
if (maxChildren > 0) {
// Add the filters to filter on maximum number of children
MaxChildrenFetchFilter maxChildrenFetchFilter = new MaxChildrenFetchFilter();
maxChildrenFetchFilter.setMaxChildren(maxChildren);
maxChildrenFetchFilter.setModel(extension.getModel());
MaxChildrenParseFilter maxChildrenParseFilter = new MaxChildrenParseFilter();
maxChildrenParseFilter.setMaxChildren(maxChildren);
maxChildrenParseFilter.setModel(extension.getModel());
objs.add(maxChildrenFetchFilter);
objs.add(maxChildrenParseFilter);
}
return extension.startScan(target, user, objs.toArray(new Object[objs.size()]));
}
use of org.zaproxy.zap.model.StructuralNode in project zaproxy by zaproxy.
the class SpiderDialog method save.
@Override
public void save() {
List<Object> contextSpecificObjects = new ArrayList<>();
URI startUri = null;
try {
// Always include the startUri, this has the side effect
// of handling URLs that have not been accessed
startUri = new URI(this.getStringValue(FIELD_START), true);
} catch (Exception e1) {
// Ignore - will have been checked in validateParams
}
if (this.getBoolValue(FIELD_ADVANCED)) {
// Set the advanced options
spiderParam.setMaxDepth(this.getIntValue(FIELD_MAX_DEPTH));
spiderParam.setMaxDuration(this.getIntValue(FIELD_MAX_DURATION));
spiderParam.setMaxChildren(this.getIntValue(FIELD_MAX_CHILDREN));
spiderParam.setSendRefererHeader(this.getBoolValue(FIELD_SEND_REFERER));
spiderParam.setProcessForm(this.getBoolValue(FIELD_PROCESS_FORMS));
spiderParam.setPostForm(this.getBoolValue(FIELD_POST_FORMS));
spiderParam.setParseComments(this.getBoolValue(FIELD_PARSE_COMMENTS));
spiderParam.setParseRobotsTxt(this.getBoolValue(FIELD_PARSE_ROBOTS));
spiderParam.setParseSitemapXml(this.getBoolValue(FIELD_PARSE_SITEMAP));
spiderParam.setParseSVNEntries(this.getBoolValue(FIELD_PARSE_SVN));
spiderParam.setParseGit(this.getBoolValue(FIELD_PARSE_GIT));
spiderParam.setHandleODataParametersVisited(this.getBoolValue(FIELD_HANDLE_ODATA));
spiderParam.setThreadCount(extension.getSpiderParam().getThreadCount());
contextSpecificObjects.add(spiderParam);
}
if (startUri != null) {
contextSpecificObjects.add(startUri);
if (getBoolValue(FIELD_SUBTREE_ONLY)) {
contextSpecificObjects.add(new HttpPrefixFetchFilter(startUri));
}
}
if (target == null || !this.getStringValue(FIELD_START).equals(getTargetText(target))) {
// Clear the target as it doesnt match the value entered manually
target = new Target((StructuralNode) null);
}
// Save the adv option permanently for next time
extension.getSpiderParam().setShowAdvancedDialog(this.getBoolValue(FIELD_ADVANCED));
target.setRecurse(this.getBoolValue(FIELD_RECURSE));
if (target.getContext() == null && getSelectedContext() != null) {
target.setContext(getSelectedContext());
}
subtreeOnlyPreviousCheckedState = getBoolValue(FIELD_SUBTREE_ONLY);
this.extension.startScan(target, getSelectedUser(), contextSpecificObjects.toArray());
}
use of org.zaproxy.zap.model.StructuralNode in project zaproxy by zaproxy.
the class SpiderDialog method validateFields.
@Override
public String validateFields() {
if (Control.Mode.safe == Control.getSingleton().getMode()) {
// The dialogue shouldn't be shown when in safe mode but if it is warn.
return Constant.messages.getString("spider.custom.notSafe.error");
}
if (this.isEmptyField(FIELD_START)) {
return Constant.messages.getString("spider.custom.nostart.error");
}
boolean noStartUri = true;
if (!getStringValue(FIELD_START).equals(getTargetText(target))) {
String url = this.getStringValue(FIELD_START);
try {
// Need both constructors as they catch slightly different issues ;)
new URI(url, true);
new URL(url);
} catch (Exception e) {
return Constant.messages.getString("spider.custom.nostart.error");
}
if (Control.getSingleton().getMode() == Control.Mode.protect) {
if (!extension.isTargetUriInScope(url)) {
return Constant.messages.getString("spider.custom.targetNotInScope.error", url);
}
}
noStartUri = false;
}
if (this.target != null) {
if (!this.target.isValid()) {
return Constant.messages.getString("spider.custom.nostart.error");
}
if (Control.getSingleton().getMode() == Control.Mode.protect) {
String uri = extension.getTargetUriOutOfScope(target);
if (uri != null) {
return Constant.messages.getString("spider.custom.targetNotInScope.error", uri);
}
}
List<StructuralNode> nodes = target.getStartNodes();
if (nodes != null) {
for (StructuralNode node : nodes) {
if (node instanceof StructuralSiteNode) {
noStartUri = false;
break;
}
}
}
}
if (getBoolValue(FIELD_SUBTREE_ONLY) && noStartUri) {
return Constant.messages.getString("spider.custom.noStartSubtreeOnly.error");
}
return null;
}
Aggregations