jspwiki-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ajaqu...@apache.org
Subject svn commit: r755089 - /incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/SpamProtectTag.java
Date Tue, 17 Mar 2009 02:31:35 GMT
Author: ajaquith
Date: Tue Mar 17 02:31:35 2009
New Revision: 755089

URL: http://svn.apache.org/viewvc?rev=755089&view=rev
Log:
Many changes to EditActionBean and JSPs. Initial checkin of SpamProtect annotation and matching
JSP tag. This will be refined in future checkins. NO unit tests yet.

Added:
    incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/SpamProtectTag.java

Added: incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/SpamProtectTag.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/SpamProtectTag.java?rev=755089&view=auto
==============================================================================
--- incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/SpamProtectTag.java (added)
+++ incubator/jspwiki/trunk/src/java/org/apache/wiki/tags/SpamProtectTag.java Tue Mar 17 02:31:35
2009
@@ -0,0 +1,121 @@
+package org.apache.wiki.tags;
+
+import java.io.IOException;
+import java.util.Random;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.JspWriter;
+import javax.servlet.jsp.tagext.TagSupport;
+
+import net.sourceforge.stripes.util.CryptoUtil;
+
+import org.apache.wiki.filters.SpamFilter;
+import org.apache.wiki.filters.SpamInterceptor;
+
+/**
+ * <p>
+ * Tag that injects hidden {@link SpamFilter}-related parameters into the
+ * current form, which will be parsed and verified by {@link SpamInterceptor}
+ * whenever the input is processed by an ActionBean event handler method
+ * annotated with the {@link org.apache.wiki.filters.SpamProtect} annotation.
+ * </p>
+ * <p>
+ * This tag will inject the following parameters:
+ * </p>
+ * <ol>
+ * <li><b>An UTF-8 detector parameter called <code>encodingcheck</code>.</b>
+ * This parameter contains a single non-Latin1. SpamInterceptor verifies that
+ * the non-Latin1 character has not been mangled by a badly behaving robot or
+ * user client. Many bots assume a form is Latin1. This also prevents the "hey,
+ * my edit destroyed all UTF-8 characters" problem.</li>
+ * <li><b>A token field </b>, which has a random name and fixed value</b>
+ * This means that a bot will need to actually GET the form first and parse it
+ * out before it can send syntactically correct POSTs. This is a LOT more effort
+ * than just simply looking at the fields once and crafting your auto-poster to
+ * conform. </li>
+ * <li><b>An empty, input field hidden with CSS</b>. This parameter is
meant
+ * to catch bots which do a GET and then randomly fill all fields with garbage.
+ * This field <em>must</em>be empty when SpamFilter examines the contents of
+ * the POST. Since it's hidden with the use of CSS, the bot would need to
+ * understand CSS to bypass this check. Because the parameter is also
+ * randomized, it prevents bot authors from hard-coding the fact that it needs
+ * to be empty.</li>
+ * </li>
+ * <li><b>An an encrypted parameter</b> called
+ * {@link SpamInterceptor#REQ_SPAM_PARAM}, whose contents are the names of
+ * parameters 2 and 3, separated by a carriage return character. These contents
+ * are then encrypted.</li>
+ * </ol>
+ * <p>
+ * The idea between 2 & 3 is that SpamInterceptor expects two fields with random
+ * names, one of which needs to be empty, and one of which needs to be filled
+ * with pre-determined data. This is quite hard for most bots to catch, unless
+ * they are specifically crafted for JSPWiki and contain some amount of logic to
+ * figure out the scheme.
+ * </p>
+ */
+public class SpamProtectTag extends WikiTagBase
+{
+
+    @Override
+    public int doWikiStartTag() throws Exception
+    {
+        return TagSupport.SKIP_BODY;
+    }
+
+    private void writeSpamParams() throws IOException
+    {
+        JspWriter out = pageContext.getOut();
+        HttpServletRequest request = (HttpServletRequest) this.pageContext.getRequest();
+
+        // Inject honey-trap param (should always be submitted with no value)
+        String trapParam = getUniqueID();
+        out.write( "<div style=\"display: none;\">" );
+        out.write( "<input type=\"hidden\" name=\"" );
+        out.write( trapParam );
+        out.write( "\" value=\"\" /></div>\n" );
+        
+        // Inject token field
+        String tokenParam = getUniqueID();
+        String tokenValue = request.getSession().getId();
+        out.write( "<input name=\"" + tokenParam + "\" type=\"hidden\" value=\"" + tokenValue
+ "\" />\n" );
+
+        // Inject UTF-8 detector
+        out.write( "<input name=\""+ SpamInterceptor.REQ_ENCODING_CHECK + "\" type=\"hidden\"
value=\"\u3041\" />\n" );
+
+        // Add encrypted parameter indicating the names of the trap and token fields
+        String encryptedParam = CryptoUtil.encrypt( trapParam + "\n" + tokenParam );
+        out.write( "<input name=\""+ SpamInterceptor.REQ_SPAM_PARAM+"\" type=\"hidden\"
value=\""+encryptedParam+"\" />\n" );
+    }
+
+    private static String getUniqueID()
+    {
+        StringBuilder sb = new StringBuilder();
+        Random rand = new Random();
+
+        for( int i = 0; i < 6; i++ )
+        {
+            char x = (char) ('A' + rand.nextInt( 26 ));
+
+            sb.append( x );
+        }
+
+        return sb.toString();
+    }
+
+    @Override
+    public int doEndTag() throws JspException
+    {
+        try
+        {
+            writeSpamParams();
+        }
+        catch( IOException e )
+        {
+            throw new JspException(e);
+        }
+        return super.doEndTag();
+    }
+
+}



Mime
View raw message