Skip to content

Commit

Permalink
Merge pull request #5536 from psiinon/pscanbeta/polyfill
Browse files Browse the repository at this point in the history
Pscanbeta - add polyfill.io scan rule
  • Loading branch information
psiinon committed Jun 27, 2024
2 parents ef2cb5b + 2a8e92c commit 5e8dcd4
Show file tree
Hide file tree
Showing 5 changed files with 427 additions and 0 deletions.
3 changes: 3 additions & 0 deletions addOns/pscanrulesBeta/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ All notable changes to this add-on will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## Unreleased
### Added
- Polyfill.io script detection

### Changed
- Update minimum ZAP version to 2.15.0.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/*
* Zed Attack Proxy (ZAP) and its related class files.
*
* ZAP is an HTTP/HTTPS proxy for assessing web application security.
*
* Copyright 2024 The ZAP Development Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.zaproxy.zap.extension.pscanrulesBeta;

import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.htmlparser.jericho.Element;
import net.htmlparser.jericho.HTMLElementName;
import net.htmlparser.jericho.Source;
import org.parosproxy.paros.Constant;
import org.parosproxy.paros.core.scanner.Alert;
import org.parosproxy.paros.network.HttpMessage;
import org.zaproxy.addon.commonlib.CommonAlertTag;
import org.zaproxy.zap.extension.pscan.PluginPassiveScanner;

public class PolyfillCdnScriptScanRule extends PluginPassiveScanner
implements CommonPassiveScanRuleInfo {

/** Prefix for internationalised messages used by this rule */
private static final String MESSAGE_PREFIX = "pscanbeta.polyfillcdnscript.";

private static final Map<String, String> ALERT_TAGS =
CommonAlertTag.toMap(
CommonAlertTag.OWASP_2021_A06_VULN_COMP,
CommonAlertTag.OWASP_2017_A09_VULN_COMP);

private static final int PLUGIN_ID = 10115;

private static Pattern POLYFILL_IO =
Pattern.compile("http[s]?://.*polyfill\\.io/.*", Pattern.CASE_INSENSITIVE);

@Override
public void scanHttpResponseReceive(HttpMessage msg, int id, Source source) {
if (msg.getResponseBody().length() > 0 && msg.getResponseHeader().isHtml()) {
List<Element> sourceElements = source.getAllElements(HTMLElementName.SCRIPT);
boolean alertRaised = false;
if (sourceElements != null) {
for (Element sourceElement : sourceElements) {
String src = sourceElement.getAttributeValue("src");
if (src != null && POLYFILL_IO.matcher(src).matches()) {
this.createHighConfidenceAlert(src, sourceElement.toString()).raise();
alertRaised = true;
}
}
if (alertRaised) {
// Definitely an issue, no point checking the script contents
return;
}
// Check the script contents, in case they are loading scripts via JS
for (Element sourceElement : sourceElements) {
String contents = sourceElement.getContent().toString();
Matcher matcher = POLYFILL_IO.matcher(contents);
if (matcher.find()) {
this.createLowConfidenceAlert(null, matcher.group(0)).raise();
break;
}
}
}
}
}

private AlertBuilder createHighConfidenceAlert(String param, String evidence) {
return this.createAlert(
Alert.CONFIDENCE_HIGH,
Constant.messages.getString(MESSAGE_PREFIX + "desc1"),
param,
evidence,
1);
}

private AlertBuilder createLowConfidenceAlert(String param, String evidence) {
return this.createAlert(
Alert.CONFIDENCE_LOW,
Constant.messages.getString(MESSAGE_PREFIX + "desc2"),
param,
evidence,
2);
}

private AlertBuilder createAlert(
int confidence, String description, String param, String evidence, int alertRef) {
return newAlert()
.setRisk(getRisk())
.setConfidence(confidence)
.setDescription(description)
.setParam(param)
.setSolution(Constant.messages.getString(MESSAGE_PREFIX + "soln"))
.setReference(Constant.messages.getString(MESSAGE_PREFIX + "refs"))
.setEvidence(evidence)
.setCweId(829) // CWE Id 829 - Inclusion of Functionality from Untrusted Control
// Sphere)
.setWascId(15) // WASC-15: Application Misconfiguration)
.setAlertRef(PLUGIN_ID + "-" + alertRef);
}

@Override
public List<Alert> getExampleAlerts() {
return List.of(
createHighConfidenceAlert(
"https://cdn.polyfill.io/malicious.js",
"<script type=\"text/javascript\" src=\"https://cdn.polyfill.io/malicious.js\"></script>")
.build(),
createLowConfidenceAlert(
"https://cdn.polyfill.io/malicious.js",
"<script> script = \"https://cdn.polyfill.io/malicious.js\"; </script>")
.build());
}

@Override
public int getPluginId() {
return PLUGIN_ID;
}

public int getRisk() {
return Alert.RISK_HIGH;
}

@Override
public String getName() {
return Constant.messages.getString(MESSAGE_PREFIX + "name");
}

@Override
public Map<String, String> getAlertTags() {
return ALERT_TAGS;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,15 @@ <H2 id="id-10063">Permissions Policy Header Not Set</H2>
Latest code: <a href="https://github.com/zaproxy/zap-extensions/blob/main/addOns/pscanrulesBeta/src/main/java/org/zaproxy/zap/extension/pscanrulesBeta/PermissionsPolicyScanRule.java">PermissionsPolicyScanRule.java</a><br>
Alert ID: <a href="https://www.zaproxy.org/docs/alerts/10063/">10063</a>

<H2 id="id-10115">Script Served From Malicious polyfill.io Domain</H2>
This checks for scripts being served from the polyfill.io domain, which is known to have been compromised.<br>
It will raise an alert with a High confidence if a script is loaded from a polyfill.io domain,
and a Low confidence if it just finds an apparent reference to a polyfill.io domain in the script contents.
<p>
Latest code: <a href="https://github.com/zaproxy/zap-extensions/blob/main/addOns/pscanrulesBeta/src/main/java/org/zaproxy/zap/extension/pscanrulesBeta/PolyfillCdnScriptScanRule.java">PolyfillCdnScriptScanRule.java</a>
<br>
Alert ID: <a href="https://www.zaproxy.org/docs/alerts/10115/">10115</a>.

<H2 id="id-90004">Site Isolation Scan Rule</H2>
Spectre is a side-channel attack allowing an attacker to read data
from memory. One of the counter-measures is to prevent sensitive data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ pscanbeta.permissionspolicymissing.name = Permissions Policy Header Not Set
pscanbeta.permissionspolicymissing.refs = https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy\nhttps://developer.chrome.com/blog/feature-policy/\nhttps://scotthelme.co.uk/a-new-security-header-feature-policy/\nhttps://w3c.github.io/webappsec-feature-policy/\nhttps://www.smashingmagazine.com/2018/12/feature-policy/
pscanbeta.permissionspolicymissing.soln = Ensure that your web server, application server, load balancer, etc. is configured to set the Permissions-Policy header.

pscanbeta.polyfillcdnscript.desc1 = The page includes one or more script files loaded from the polyfill.io domain.\nThis is not associated with the polyfill.js library and is known to serve malicious content.
pscanbeta.polyfillcdnscript.desc2 = The page includes one or more script which appear to include a reference to a polyfill.io domain.\nThis is not associated with the polyfill.js library and is known to serve malicious content.\nYou should check to see if it is a safe reference (for example in a comment) or whether the script is loading content from that domain.
pscanbeta.polyfillcdnscript.name = Script Served From Malicious polyfill.io Domain
pscanbeta.polyfillcdnscript.refs = https://sansec.io/research/polyfill-supply-chain-attack\nhttps://x.com/triblondon/status/1761852117579427975
pscanbeta.polyfillcdnscript.soln = Change all scripts to use a known good source based on their documentation.

pscanbeta.servletparameterpollution.desc = Unspecified form action: HTTP parameter override attack potentially possible. This is a known problem with Java Servlets but other platforms may also be vulnerable.
pscanbeta.servletparameterpollution.name = HTTP Parameter Override
pscanbeta.servletparameterpollution.refs = https://download.oracle.com/javaee-archive/servlet-spec.java.net/jsr340-experts/att-0317/OnParameterPollutionAttacks.pdf
Expand Down
Loading

0 comments on commit 5e8dcd4

Please sign in to comment.