From 0cbbe6297e2f2079fcb33b7b1da23b94c8f83f4f Mon Sep 17 00:00:00 2001 From: zzz <zzz@i2pmail.org> Date: Wed, 18 Jan 2023 12:21:29 -0500 Subject: [PATCH] i2psnark: Rename search param to bypass the XSS filter Fix encode/decode search param Copy CSS to non-default themes, not tweaked yet Add support for shorter nf_ prefix to XSS filter Remove unneeded float_right, reported by drzed --- .../org/klomp/snark/web/I2PSnarkServlet.java | 34 +++++++++++-------- apps/i2psnark/resources/js/initajax.js | 4 +-- apps/i2psnark/resources/themes/dark/snark.css | 21 ++++++++++++ .../i2psnark/resources/themes/light/snark.css | 21 ++++++++++++ .../resources/themes/ubergine/snark.css | 1 - .../resources/themes/vanilla/snark.css | 21 ++++++++++++ .../servlet/filters/XSSRequestWrapper.java | 9 +++-- 7 files changed, 91 insertions(+), 20 deletions(-) diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java index 2bc68376aa..564399957e 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java +++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java @@ -387,13 +387,12 @@ public class I2PSnarkServlet extends BasicServlet { out.write("</div>\n"); if (!isConfigure) { - String search = req.getParameter("s"); + String search = req.getParameter("nf_s"); if (_manager.getTorrents().size() > 1 || (search != null && search.length() > 0)) { out.write("<form class=\"search\" id = \"search\" action=\"" + _contextPath + "\" method=\"GET\">" + - "<input type=\"text\" name=\"s\" size=\"20\" class=\"search\" id=\"searchbox\""); - String s = req.getParameter("s"); - if (s != null) - out.write(" value=\"" + DataHelper.escapeHTML(s) + '"'); + "<input type=\"text\" name=\"nf_s\" size=\"20\" class=\"search\" id=\"searchbox\""); + if (search != null) + out.write(" value=\"" + DataHelper.escapeHTML(search) + '"'); out.write(">" + "<input type=\"reset\" class=\"cancel\" id=\"searchcancel\" value=\"\">" + "</form>\n"); @@ -507,7 +506,7 @@ public class I2PSnarkServlet extends BasicServlet { // search boolean isSearch = false; - String search = req.getParameter("s"); + String search = req.getParameter("nf_s"); if (search != null && search.length() > 0) { List<Snark> matches = search(search, snarks); if (matches != null) { @@ -851,12 +850,17 @@ public class I2PSnarkServlet extends BasicServlet { /** * search torrents for matching terms * - * @param search non-null - * @param snarks unmodified - * @return null if no valid search, or matching torrents in same order + * @param search non-null and %-encoded, will be decoded here + * @param snarks unmodified, order will be honored + * @return null if not a valid search, or matching torrents in same order, possibly empty * @since 0.9.58 */ private static List<Snark> search(String search, Collection<Snark> snarks) { + try { + search = decodePath(search); + } catch (IOException ioe) { + return null; + } List<String> searchList = null; String[] terms = DataHelper.split(search, " "); for (int i = 0; i < terms.length; i++) { @@ -927,7 +931,7 @@ public class I2PSnarkServlet extends BasicServlet { .append(action).append("\" >\n"); } else { // for buttons, keep the search term - String sParam = req.getParameter("s"); + String sParam = req.getParameter("nf_s"); if (sParam != null) { buf.append("<input type=\"hidden\" name=\"s\" value=\"") .append(DataHelper.escapeHTML(sParam)).append("\" >\n"); @@ -987,15 +991,15 @@ public class I2PSnarkServlet extends BasicServlet { buf.append(st); } if (s == null) { - s = req.getParameter("s"); + s = req.getParameter("nf_s"); if (s != null) s = DataHelper.escapeHTML(s); } if (s != null && !s.equals("")) { if (buf.length() <= 0) - buf.append("?s="); + buf.append("?nf_s="); else - buf.append("&s="); + buf.append("&nf_s="); buf.append(s); } return buf.toString(); @@ -1555,7 +1559,7 @@ public class I2PSnarkServlet extends BasicServlet { _manager.addMessage(_t("Error creating torrent - you must enter a file or directory")); } } else if ("StopAll".equals(action)) { - String search = req.getParameter("s"); + String search = req.getParameter("nf_s"); if (search != null && search.length() > 0) { List<Snark> matches = search(search, _manager.getTorrents()); if (matches != null) { @@ -1567,7 +1571,7 @@ public class I2PSnarkServlet extends BasicServlet { } _manager.stopAllTorrents(false); } else if ("StartAll".equals(action)) { - String search = req.getParameter("s"); + String search = req.getParameter("nf_s"); if (search != null && search.length() > 0) { List<Snark> matches = search(search, _manager.getTorrents()); if (matches != null) { diff --git a/apps/i2psnark/resources/js/initajax.js b/apps/i2psnark/resources/js/initajax.js index 87de15cd36..7697b0086e 100644 --- a/apps/i2psnark/resources/js/initajax.js +++ b/apps/i2psnark/resources/js/initajax.js @@ -29,12 +29,12 @@ function requestAjax2(refreshtime) { query = ""; } var q = new URLSearchParams(query); - q.set("s", search); + q.set("nf_s", encodeURIComponent(search)); query = "?" + q.toString(); } else { if (query != null) { var q = new URLSearchParams(query); - q.delete("s"); + q.delete("nf_s"); var newq = q.toString(); if (newq != null && newq.length > 0) { query = "?" + newq; diff --git a/apps/i2psnark/resources/themes/dark/snark.css b/apps/i2psnark/resources/themes/dark/snark.css index ff10571f7f..f392273d97 100644 --- a/apps/i2psnark/resources/themes/dark/snark.css +++ b/apps/i2psnark/resources/themes/dark/snark.css @@ -224,6 +224,27 @@ _:-ms-lang(x), .snarknavbar { margin-top: 0 !important; } +#search { + display: inline-block; + position: absolute; + top: 6px; + right: 3px; +} + +#searchbox { + background: #f60 url(/themes/console/images/buttons/search.png) 7px center no-repeat !important; + margin: 2px 4px 2px 24px !important; + padding: 4px 32px 4px 32px !important; + color: black; +} + +#searchcancel { + background: url(images/cancel.png); + margin: 2px 4px 2px -28px; + color: transparent; + border: none; +} + /* end topnav */ /* screenlog */ diff --git a/apps/i2psnark/resources/themes/light/snark.css b/apps/i2psnark/resources/themes/light/snark.css index c3e3391f06..18134c4146 100644 --- a/apps/i2psnark/resources/themes/light/snark.css +++ b/apps/i2psnark/resources/themes/light/snark.css @@ -229,6 +229,27 @@ button::-moz-focus-inner, input::-moz-focus-inner { background: #f60 url(images/button_tracker_active.png) 8px center no-repeat; } +#search { + display: inline-block; + position: absolute; + top: 6px; + right: 3px; +} + +#searchbox { + background: #f60 url(/themes/console/images/buttons/search.png) 7px center no-repeat !important; + margin: 2px 4px 2px 24px !important; + padding: 4px 32px 4px 32px !important; + color: black; +} + +#searchcancel { + background: url(images/cancel.png); + margin: 2px 4px 2px -28px; + color: transparent; + border: none; +} + /* end top nav */ /* screenlog */ diff --git a/apps/i2psnark/resources/themes/ubergine/snark.css b/apps/i2psnark/resources/themes/ubergine/snark.css index 6394cecea2..e3afeb55d5 100644 --- a/apps/i2psnark/resources/themes/ubergine/snark.css +++ b/apps/i2psnark/resources/themes/ubergine/snark.css @@ -231,7 +231,6 @@ _:-ms-lang(x), .snarkNav:last-child[href="/i2psnark/"] { #search { display: inline-block; - float: right; position: absolute; top: 6px; right: 3px; diff --git a/apps/i2psnark/resources/themes/vanilla/snark.css b/apps/i2psnark/resources/themes/vanilla/snark.css index a119bc1001..1a70c5cac7 100644 --- a/apps/i2psnark/resources/themes/vanilla/snark.css +++ b/apps/i2psnark/resources/themes/vanilla/snark.css @@ -272,6 +272,27 @@ _:-ms-lang(x), .snarkNav:link, .snarkNav:visited { transition: ease box-shadow 0.1s; } +#search { + display: inline-block; + position: absolute; + top: 6px; + right: 3px; +} + +#searchbox { + background: #f60 url(/themes/console/images/buttons/search.png) 7px center no-repeat !important; + margin: 2px 4px 2px 24px !important; + padding: 4px 32px 4px 32px !important; + color: black; +} + +#searchcancel { + background: url(images/cancel.png); + margin: 2px 4px 2px -28px; + color: transparent; + border: none; +} + /* end topnav */ /* screenlog */ diff --git a/apps/jetty/java/src/net/i2p/servlet/filters/XSSRequestWrapper.java b/apps/jetty/java/src/net/i2p/servlet/filters/XSSRequestWrapper.java index b24c3d324f..163505906c 100644 --- a/apps/jetty/java/src/net/i2p/servlet/filters/XSSRequestWrapper.java +++ b/apps/jetty/java/src/net/i2p/servlet/filters/XSSRequestWrapper.java @@ -26,6 +26,8 @@ public class XSSRequestWrapper extends HttpServletRequestWrapper { private static final Pattern parameterValuePattern = Pattern.compile(SystemVersion.isWindows() ? WIN_PATTERN : NON_WIN_PATTERN); private static final Pattern headerValuePattern = Pattern.compile("^[a-zA-Z0-9()\\-=\\*\\.\\?;,+\\/:&_ \"]*$"); private static final String NOFILTER = "nofilter_"; + // shorter flavor + private static final String NOFILTER2 = "nf_"; public XSSRequestWrapper(HttpServletRequest servletRequest) { super(servletRequest); @@ -33,11 +35,12 @@ public class XSSRequestWrapper extends HttpServletRequestWrapper { /** * Parameter names starting with "nofilter_" will not be filtered. + * As of 0.9.58, names starting with "nf_" will not be filtered. */ @Override public String[] getParameterValues(String parameter) { String[] values = super.getParameterValues(parameter); - if (parameter.startsWith(NOFILTER)) + if (parameter.startsWith(NOFILTER) || parameter.startsWith(NOFILTER2)) return values; if (values == null) { @@ -70,11 +73,12 @@ public class XSSRequestWrapper extends HttpServletRequestWrapper { /** * Parameter names starting with "nofilter_" will not be filtered. + * As of 0.9.58, names starting with "nf_" will not be filtered. */ @Override public String getParameter(String parameter) { String value = super.getParameter(parameter); - if (parameter.startsWith(NOFILTER)) + if (parameter.startsWith(NOFILTER) || parameter.startsWith(NOFILTER2)) return value; String rv = stripXSS(value, parameterValuePattern); if (value != null && rv == null) { @@ -86,6 +90,7 @@ public class XSSRequestWrapper extends HttpServletRequestWrapper { /** * Parameter names starting with "nofilter_" will not be filtered. + * As of 0.9.58, names starting with "nf_" will not be filtered. */ @Override public Map<String, String[]> getParameterMap() { -- GitLab