<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
    <channel>
        <title>Security - Blogs at Near Infinity</title>


        <link>http://www.nearinfinity.com/blogs/</link>
        <description>Employee Blogs</description>
        <language>en</language>
        <copyright>Copyright 2012</copyright>
        <lastBuildDate>Tue, 14 Dec 2010 08:31:55 -0500</lastBuildDate>
        <generator>http://www.sixapart.com/movabletype/</generator>
        <docs>http://www.rssboard.org/rss-specification</docs>
        
        <item>
            <title>Lessons Learned Building an HTTPS Everywhere Safari Extension Clone</title>
            <description><![CDATA[<p>Ever since hearing about <a href="http://codebutler.com/firesheep">Firesheep</a> I've wanted a Safari extension similar to the <a href="https://www.eff.org/https-everywhere">HTTPS Everywhere</a> extension for Firefox. Frankly, I was puzzled that one didn't already exist, so I set out to write it. The result is <a href="http://www.nearinfinity.com/home/opensource/ssl-everywhere.html">SSL Everywhere</a>. The journey is this blog post.</p>

<p>I started the project as an effort to protect myself and others from Firesheep when using Safari on an open public wireless network, much like those found in coffee shops, hotels, and airports everywhere. Firesheep works by <a href="https://secure.wikimedia.org/wikipedia/en/wiki/Session_hijacking">hijacking your session</a>, which is basically a way of stealing your active login without needing your username or password. </p>

<p>My goal with SSL Everywhere was to protect someone from a session hijacking attack by ensuring all requests to the originating website were tunneled through SSL. This seemed trivial until I thought about the various kinds of requests that would need to be secured.</p>

<ul>
<li>the original HTML page</li>
<li>images</li>
<li>external JavaScript files</li>
<li>external CSS files</li>
<li>inline frames (iframes)</li>
<li>object or embed tags for things like videos or applets</li>
<li>Ajax requests</li>
<li>requests for the favicon</li>
</ul>

<p>It wasn't until I started to tackle each of the list items that I realized just how limited Safari's extension API is, and ultimately that <strong>one could never build a foolproof extension to protect Safari users from session hijacking attacks</strong>.</p>

<h1>Lessons Learned</h1>

<p>If you've spent any significant time writing Safari extensions, you may already be aware of the many restrictions and challenges I wrestled with for hours. Much of what I learned was trial and error, despite <a href="http://developer.apple.com/library/safari/#documentation/Tools/Conceptual/SafariExtensionGuide/Introduction/Introduction.html">well written documentation from Apple</a>. While the documentation does a fair job of describing many of the things you can do with an extension, it doesn't provide as much detail on what you <em>can't</em> do. That's what you'll find below.</p>

<h2>No Access to Raw Cookies</h2>

<p>The key to avoiding a session hijacking attempt is making sure the attacker can't access the session cookie, or cookies, your browser sends on each request. This can obviously be done by making sure all requests take place over an SSL connection. Unfortunately, you can't guarantee this won't happen since Safari extensions have no opportunity to intercept webpage requests before they occur. A user could easily type http://twitter.com into their address bar and SSL Everywhere couldn't stop the request.</p>

<p>The other option I pursued was having SSL Everywhere attempt to mark session cookies as secure since the browser will not send cookies marked as secure over a non-SSL connection. However, a Safari extension has no additional ability to manipulate cookies than normal JavaScript running on a page, meaning there is no way to read a cookie's path or expiration date for example. So, there's no way for the SSL Everywhere extension to simply mark a cookie as secure without having to guess at, or omit, other cookie information which may be important to the operation of the website.</p>

<h2>No beforeload for favicons, Ajax Calls, or Stylesheet References</h2>

<p>Apple was responsible for adding the beforeload event to Webkit. This gives scripts (and extensions) the ability to decide whether an external resource should be loaded or not. As stated in the Safari Extensions Development Guide, </p>

<blockquote>
  <p>Safari 5.0 and later (and other Webkit-based browsers) generates a "beforeload" event before loading each sub-resource belonging to a webpage. The "beforeload" event is generated before loading every script, iframe, image, or style sheet specified in the webpage, for example.</p>
</blockquote>

<p>I was thrilled after reading those two sentences because it was exactly what I needed. That is, until I discovered there's no beforeload event fired when the browser requests a website's favicon, makes an Ajax request, or loads an image reference defined in a stylesheet. This leaves a loophole where I can't stop a non-secure favicon reference, Ajax call, or CSS image reference from exposing the session cookies I can't properly mark as secure.</p>

<h2>src Attribute Can Not be Changed in beforeload Event Handlers</h2>

<p>I ultimately wanted to have a beforeload event listener that would </p>

<ol>
<li>inspect the source URL being requested</li>
<li>rewrite the source URL to a secure https: version if necessary</li>
<li>replace the resource's insecure reference with the secure https: URL</li>
<li>allow the loading of the resource to proceed with the new, secure URL</li>
</ol>

<p>Following the above procedure results in the resource being requested with the SSL-secured URL as desired, but will not stop the original load with the original, insecure, URL. You just end up making two requests for the same resource; one over SSL, the other not. Again, another point of exposure for the cookies.</p>

<h2>beforeload != before request</h2>

<p>It turns out that all the effort described above to leverage the beforeload event was futile. Preventing a resource from loading, as described in Apple's example of <a href="http://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/MessagesandProxies/MessagesandProxies.html#//apple_ref/doc/uid/TP40009977-CH14-SW9">blocking unwanted content</a>, stops it from being inserted into the DOM, but does not prevent it from being requested by the browser anyway.</p>

<p>Apple's example documentation states</p>

<blockquote>
  <p>If your script responds to a "beforeload" event by calling event.preventDefault(), the pending sub-resource is not loaded. This is a useful technique for blocking ads...</p>
</blockquote>

<p>Should I have really expected that "the pending sub-resource is not loaded" doesn't imply that it's not requested? Perhaps I wasn't sharp enough to catch that nuance, but once again the cookies are exposed.</p>

<h2>Host Page Prototypes Can Not be Changed</h2>

<p>When I discovered the beforeload event doesn't fire on Ajax requests, I decided to try to override the XMLHttpRequest <code>open</code> method and rewrite any insecure URLs to a secure version before yielding to the original <code>open</code> implementation. What I found was that you can't modify the prototypes of the page your start or end scripts are being injected into.</p>

<p>I suspect this has something to do with start and end scripts being secluded in their own separate, and randomly named, namespace. Changing around object prototypes never resulted in any errors, it just didn't change the prototypes of the host page and therefore couldn't change the XMLHttpRequest object. Again, another point of exposure for the precious cookies.</p>

<h1>Status of SSL Everywhere</h1>

<p>If you've read this far it should be obvious that SSL Everywhere cannot guarantee protection against session hijacking attacks, including those from Firesheep. However, it does enhance security by automatically redirecting you to secure versions of many websites and rewriting insecure links to their SSL-encrypted equivalents. If you must use Safari to access popular websites when connected to an open WiFi network, you're probably better off doing it with SSL Everywhere.</p>

<p>We don't offer a pre-built version of the extension for easy installation into Safari because we don't want people to casually install it and forget that it's not completely secure for all sites. If people find it valuable nonetheless, then we may consider creating the extension bundle in the future.</p>

<h1>Try It!</h1>

<p>If you'd like to try SSL Everywhere you can find the <a href="https://github.com/nearinfinity/ssl-everywhere.safariextension">source code on Github</a>. It's open source software licensed under the GPL version 2 license, primarily because it borrows code from <a href="https://www.eff.org/https-everywhere">HTTPS Everywhere</a>. If you can come up with solutions to any of the problems I encountered, please let me know!</p>
]]></description>
            <link>http://www.nearinfinity.com/blogs/jeff_kunkle/lessons_learned_building_an_ht.html</link>
            <guid>http://www.nearinfinity.com/blogs/jeff_kunkle/lessons_learned_building_an_ht.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">JavaScript</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Mac OS X</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Security</category>
            
            
            <pubDate>Tue, 14 Dec 2010 08:31:55 -0500</pubDate>
        </item>
        
        <item>
            <title>Clearance Track feelin&apos; the love in San Antonio</title>
            <description><![CDATA[<p>I'm writing today from the DSSS (Defense Special Security Systems) Conference in San Antonio. We're here showing Clearance Track, our product for security officers that helps organize and automate the clearance processes associated with getting and keeping your employees' clearances.</p>

<p>I was actually a little bit intimidated when we arrived and started setting up our booth yesterday -- our co-exhibitors rolled into the conference with crates taller than me full of degaussers (I had to google degausser), security doors, liquid scanners, extra large safes, alarm systems, and miscellaneous oversized, super-heavy equipment looking like it was taken from the set of a 1970s spy thriller.  </p>

<p>The truth is, we don't have 2,000 pounds of awesomeness at our booth. Not even if you throw in our pop-up display and our booth babes. Our product is software, so our coolest item is a 30" Apple monitor that we borrowed from our CEO's desk on which we display the software. But we're holding our own. We have a product that people <em>want</em>. One of our first visitors took one look at Clearance Track and said to my co-worker, "you're my new best friend."</p>

<p><img alt="CT-booth-babes.jpg" src="http://www.nearinfinity.com/blogs/CT-booth-babes.jpg" width="360" height="268" class="mt-image-left" style="float: left; margin: 0 20px 20px 0;" /></p>

<p>We thought we would come here and meet lots of security officers from small consulting companies like Near Infinity whose security officers were overwhelmed with processing clearances. But in talking to the attendees, we're finding more government folks charged with managing the clearance data for thousands of military or other government personnel. They use JPAS, but find it insufficient to report on and manage the details of their employees' clearances. They're getting by now with Excel spreadsheets, outdated Access databases, filing cabinets, and whatever info they can remember in their heads.</p>

<p>Clearance Track is a great solution for them. It provides a single, organized place to store all of their clearance data. It makes it easy to report on their secure personnel, easy to find documents related to that person's clearance, easy to pass off responsibilities from one security officer to another, easy to remember to renew a badge, easy to run tedious government reports, easy to auto-generate documents... Who doesn't need easy?</p>

<p>So far, the reaction has been great. Lots of people are raving about how helpful Clearance Track would be in their jobs, how user friendly it is, and how much time it would save them. With a day and a half left to go, we're not missing the heavy equipment too much.</p>

<p>And now, if you'll excuse me, I'd better get back to our booth visitors! </p>

<p><em>Clearance Track is a fast, secure way to manage your clearances. By providing a single place to track your investigations, crossovers, badge renewals, briefings, and certs, Clearance Track significantly streamlines the security officer's job and provides a collaborative environment to organize and store employee data. Use it for 4311s, 4414s, 312s, SF-86s, visit certs, annual security refresher briefings, and key government reports.</em></p>
]]></description>
            <link>http://www.nearinfinity.com/blogs/caroline_wizeman/clearance_track_feelin_the_lov.html</link>
            <guid>http://www.nearinfinity.com/blogs/caroline_wizeman/clearance_track_feelin_the_lov.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">General</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Security</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">Clearance Track</category>
            
            <pubDate>Tue, 30 Nov 2010 17:02:33 -0500</pubDate>
        </item>
        
        <item>
            <title>Protect your Rails Model Objects with Grant</title>
            <description><![CDATA[<p>Near Infinity recently announced the release of <a href="http://github.com/nearinfinity/grant">Grant</a>, a Ruby on Rails plugin for securing and auditing access to your Rails model objects, and I'm here to tell you a little bit about it. There are two primary pieces of Grant, model security and model audit. I'll be focusing on model security for this post and will address model audit in a later entry.</p>

<p>Grant's model security is deliberately designed to force the developer to make conscious security decisions about what CRUD operations a user should be allowed to perform on your model objects. It doesn't care how you choose to authenticate and authorize your users to perform a CRUD operation, it only cares that you actually do it.</p>

<p>Rather than specify which operations are restricted, Grant restricts all CRUD operations unless they're explicitly granted to the user. It also restricts adding or removing items from <em>has_many</em> and <em>has_and_belongs_to_many</em> associations. Only allowing operations explicitly granted forces you to make conscious security decisions. While it obviously can't ensure you make the correct decisions, it should help ease the latent fear that you've inadvertently forgotten to secure something.</p>

<p>Enough talk, let me show you an example of how you might use it. To enable model security you simply include the Grant::ModelSecurity module in your model class. In this example you see three grant statements. The first grants find (aka read) permission to everyone. The second example grants create, update, and destroy permission when the passed block evaluates to true, which in this case happens when the model is editable by the current user. You can put any code you want in that block as long as it returns a boolean value. Similarly, the third grant statement permits additions and removals from the tags association when it's block evaluates to true. A Grant::ModelSecurityError is raised if any grant block evaluates to false or nil.</p>

<pre class="prettyprint">
class EditablePage < ActiveRecord::Base
  include Grant::ModelSecurity
  has_many :tags

  grant(:find) { true }
  grant(:create, :update, :destroy) do |user, model| 
    model.editable_by_user? user 
  end
  grant(:add => :tags, :remove => :tags) do |user, model, associated_model| 
    model.editable_by_user? user 
  end

  def editable_by_user? user
    user.administrator?
  end
end
</pre>

<p>There's a lot more to the grant statement than shown in the above example. For instance, you can have multiple grant statements for the same action. Ultimate permission to perform the action will not be granted unless all grant blocks evaluate to true.</p>

<p>As you can see, Grant is pretty simple to use, but it's not going to do the dirty work for you. It's up to you to make the proper security decisions. Grant's just there to make sure you don't forget. </p>
]]></description>
            <link>http://www.nearinfinity.com/blogs/jeff_kunkle/protect_your_rails_model_objec.html</link>
            <guid>http://www.nearinfinity.com/blogs/jeff_kunkle/protect_your_rails_model_objec.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Ruby</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Security</category>
            
            
            <pubDate>Wed, 18 Nov 2009 14:00:00 -0500</pubDate>
        </item>
        
        <item>
            <title>How to implement row level access control in Lucene</title>
            <description><![CDATA[Below I have written some fully functionally code that shows how you could implement row level access control in Lucene (2.3.2).  Basically you have to index enough information to be able to search (in a single query) and find all documents that a given user has access to read.<br /><br />

In the below example there are two fields:<br /><br />

DATA: Which contains any data that you want your users to be able to search.  NOTE: You can have as many data fields as you like.<br /><br />

ACL_FIELD: The field used to determine what users have access to this document.  Note: You can have as many access control fields as you like.<br /><br />

All you have to do is built the access control query for each user and submit your user's query unchanged.<br /><br />

<pre class="prettyprint">public class TestIndexerSearcher {

   public static void main(String[] args) throws Exception {
      Directory directory = new RAMDirectory();
      IndexWriter indexWriter = new IndexWriter(directory, new StandardAnalyzer());
      indexWriter.addDocument(buildDocument("DATA:sametoken","ACL_FIELD:access"));
      indexWriter.addDocument(buildDocument("DATA:sametoken","ACL_FIELD:noaccess"));
      indexWriter.optimize();
      indexWriter.close();

      IndexSearcher indexSearcher = new IndexSearcher(directory);

      QueryParser parser = new QueryParser("DATA", new StandardAnalyzer());
      Query query = parser.parse("sametoken");
		
      //This is all you have to add to your existing code.
      Filter aclFilter = applyAccessControl(new TermQuery(
         new Term("ACL_FIELD","access")));

      Hits hits = indexSearcher.search(query, aclFilter);
      System.out.println("Hits[" + hits.length() + "]");
      for (int i = 0; i &lt; hits.length(); i++) {
         Document doc = hits.doc(i);
         System.out.println("DATA [" + doc.get("DATA") + 
            "] ACL_FIELD [" + doc.get("ACL_FIELD") + "]");
      }
      indexSearcher.close();	
   }

   private static Filter applyAccessControl(Query aclQuery) {
      return new CachedQueryFilter(aclQuery.toString(), 
         new QueryWrapperFilter(aclQuery));
   }

   private static Document buildDocument(String... fieldInfo) {
      Document document = new Document();
      for (int i = 0; i &lt; fieldInfo.length; i++) {
         String[] split = fieldInfo[i].split(":");
         String fieldName = split[0];
         String fieldValue = split[1];
         document.add(new Field(fieldName,fieldValue,
            Field.Store.YES,Field.Index.TOKENIZED));
      }
      return document;
   }	
}

</pre>

<br />After you run this code, you will get a single hit, not the two that you would normally get if the access control filter wasn't in place.<br /><br />

<pre class="prettyprint">public class CachedQueryFilter extends Filter {
   private static final long serialVersionUID = 6797293376134753695L;
   private Filter filter;
   private String key;
   private static transient Map&lt;String, BitSetCache&gt; filterCache = 
      new ConcurrentHashMap&lt;String, BitSetCache&gt;();

   public CachedQueryFilter(String key, Filter filter) {
      this.filter = filter;
      this.key = key;
   }

   public BitSet bits(IndexReader reader) throws IOException {
      BitSetCache cachedBitSet = (BitSetCache) filterCache.get(key);
      if (cachedBitSet != null) {
         BitSet bitSet = cachedBitSet.bitSet.get();
         if (bitSet != null &amp;&amp; cachedBitSet.indexReaderVersion == reader.getVersion()) {
            return bitSet;
         }
      }
      BitSet bits = filter.bits(reader);
      BitSetCache bitSetCache = new BitSetCache();
      bitSetCache.indexReaderVersion = reader.getVersion();
      bitSetCache.bitSet = new SoftReference&lt;BitSet&gt;(bits);
      filterCache.put(key, bitSetCache);
      return bits;
   }
	
   private class BitSetCache {
      long indexReaderVersion;
      SoftReference&lt;BitSet&gt; bitSet;
   }
}
</pre>


There are two additional features that this query filter doesn't implements that you may want to consider.<br /><br />

1st - Provide per query locking around the bitset creation code.  This would allow multiple bitset creation calls to occur at once, but the same access control query would block.  Therefore we would only have to build it once, even if multiple user queries with the same access control hit the query filter at once.<br /><br />

2nd - Persist the bitsets.  In the past I have used the same directory as the index, but you may want to use a database, or something else.<br /><br />]]></description>
            <link>http://www.nearinfinity.com/blogs/aaron_mccurry/how_to_implement_row_level.html</link>
            <guid>http://www.nearinfinity.com/blogs/aaron_mccurry/how_to_implement_row_level.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Java</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Lucene</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Security</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">Big Data</category>
            
            <pubDate>Sat, 27 Sep 2008 21:08:42 -0500</pubDate>
        </item>
        
        <item>
            <title>What Happens To Lucene When You Go Big...  Part 1</title>
            <description><![CDATA[<p style="margin-bottom: 0in;">My current project has some unique
searching requirements.</p>
<p style="margin-bottom: 0in;">
</p>
<h2>Requirements</h2>
<ul>
	<li><p style="margin-bottom: 0in;">Fuzzy searching is a must
	(Soundex, Levenshtein, etc.)</p>
	</li><li><p style="margin-bottom: 0in;">Has to be fast, a must with any
	searching solution</p>
	</li><li><p style="margin-bottom: 0in;">Has to provide access control</p>
	</li><li><p style="margin-bottom: 0in;">Full data load indexing needs to
	be completed in a reasonable amount of time</p>
	</li><li><p style="margin-bottom: 0in;">Scoring needs to be a custom
	implementation</p>
	</li><li><p style="margin-bottom: 0in;">Needs to run on a predetermined
	environment, meaning that new hardware purchases are not going to
	happen any time soon</p>
	</li><li><p style="margin-bottom: 0in;">And last but not least is ability
	do all these things on a dataset that exceeds a billion records</p>
</li></ul>
<p style="margin-bottom: 0in;">
</p>
<p style="margin-bottom: 0in;">So we have had a lot of constraints to
deal with, the hardest one by far is the last one.</p>
<p style="margin-bottom: 0in;">
</p>
<h2>The Data</h2>
<p style="margin-bottom: 0in;">
</p>
<ul>
	<li><p style="margin-bottom: 0in;">1 billion
	plus records</p>
	</li><li><p style="margin-bottom: 0in;">Over 30
	million unique terms</p>
</li></ul>
<p style="margin-bottom: 0in;">
</p>
<h2>Indexing and Searching Server Specs</h2>
<p style="margin-bottom: 0in;">
</p>
<ul>
	<li><p style="margin-bottom: 0in;">20 CPUs</p>
	</li><li><p style="margin-bottom: 0in;">32 Gig of ram</p>
	</li><li><p style="margin-bottom: 0in;">Dedicated SAN
	storage</p>
</li></ul>
<p style="margin-bottom: 0in;">
</p>
<h2>First Searching Experiences</h2>
<p style="margin-bottom: 0in;">
</p>
<p style="margin-bottom: 0in;">After getting the
index built in multiple partitions, I fired up a simple Lucene
console to do some simple searches with a Lucene multi searcher.  Ran
out of memory with 2 Gig heap, tried the maximum heap size for the 32
bit JVM we were using, 3.3 Gig, and that ran out of memory as well. 
So, initial tries to just run one search were unsuccessful.</p>
<p style="margin-bottom: 0in;">
</p>
<p style="margin-bottom: 0in;">Then we installed
a 64-bit JVM and tried an 8 Gig heap, and it worked!  I could run
searches and after the first couple of warm up searches it was
getting 20 - 80 ms responses on single term searches.  Great,
but then we tried a Fuzzy search, which uses a Levenshtein algorithm
to calculate matches, 2 minutes 45 seconds, this was unacceptable.</p>
<p style="margin-bottom: 0in;">
</p>
<p style="margin-bottom: 0in;">Next we wrote our
own Levenshtein Lucene query and got the 2 minutes plus search down
to about one second.  We found that the built in Lucene Fuzzy query
was taking 85-95% of the time to find the terms to search.  Then
after those terms were found the actual search with those expanded
terms only took a second to two depending on how many terms were
found.  So we replaced the built in Fuzzy query with a custom one
that gets near instantaneous results on Levenshtein fuzzy matches. 
Problem solved.</p>
<p style="margin-bottom: 0in;">
</p>
<h2>Indexing Time</h2>
<p style="margin-bottom: 0in;">
</p>
<p style="margin-bottom: 0in;">After our initial
proof of concept was complete, we needed to improve the indexing time
down to something more reasonable.  The index creation from scratch
was taking 36 - 48 hours to build with 20 CPUs running at 100%
utilization.  Which means that the machine was indexing about 9,000
records a second.  Not bad for Lucene 2.2, but not that great.</p>
<p style="margin-bottom: 0in;">
</p>
<p style="margin-bottom: 0in;">First we stopped
merging the indexes after we created them, that by itself was taking
about 12 hours.  At this point we also started searching these
multiple indexes in parallel, and we are seeing modest increases in
query performance.</p>
<p style="margin-bottom: 0in;">
</p>
<p style="margin-bottom: 0in;">Second, we
upgraded to Lucene 2.3, this provided a huge increase in indexing
speed.  Our index creation time went from 36 - 48 hours
(depending on if we merged indexes or not) down to 3-4 hours.  The
indexing process is now indexing around 125,000+ records a second. 
Huge improvement, if you haven't upgraded to 2.3, you should!</p>
<p style="margin-bottom: 0in;">
</p>
<h2>Current Development</h2>
<p style="margin-bottom: 0in;">
</p>
<p style="margin-bottom: 0in;">We are in the
process of adding access control to Lucene as well as adding new
custom queries and scoring.  So far Lucene has performed better than
any of the competition that it has come up against, and with it's
price point it seems to have won acceptance on our project.</p>
<p style="margin-bottom: 0in;">
</p>
<p style="margin-bottom: 0in;">In upcoming parts
I will go into more details about the technical solutions that we
have developed to solve these problems, as well others that I haven't
mentioned yet.</p>
<p style="margin-bottom: 0in;">
</p>]]></description>
            <link>http://www.nearinfinity.com/blogs/aaron_mccurry/what_happens_to_lucene_when.html</link>
            <guid>http://www.nearinfinity.com/blogs/aaron_mccurry/what_happens_to_lucene_when.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Java</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Lucene</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Security</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">Big Data</category>
            
            <pubDate>Wed, 30 Apr 2008 13:30:00 -0500</pubDate>
        </item>
        
        <item>
            <title>What Not To Show a User</title>
            <description><![CDATA[<p>Quick rule of thumb: Don't show users cryptic error messages. This one was an error I recently received at a major airline's web site while checking in online for a flight:</p>

<pre>Internal Session Id 1207429769869209087112251146956
User Session Id H3qJ4YGjTnTH1Sv0d4nVMBNhr2vdn77m4MKGQ3MT0SVVhQQvsQBk!1447771105!1207429769869
telprdB UserIntB12 java.lang.NullPointerException
</pre>

<p>That's a lot more information than should be given out to anyone, and is certainly not "user friendly." Do you think they are using Java? That NPE didn't give it away did it? Then again you can pretty much figure that out from the ".do" on the end of the URLs they use, which is one reason why web frameworks these days allow you to map things in a more REST-friendly and technology-agnostic manner using *.html or something like <code>/my/site/person/1</code>. Another rule of thumb: design URLs to be technology agnostic and generic, so that just from a URL it cannot be determined what technology you are using and in case you need or want to switch to a different technology you could theoretically use the same routing scheme in your URLs, which would allow bookmarks to keep working.</p>]]></description>
            <link>http://www.nearinfinity.com/blogs/scott_leberknight/what_not_to_show_a.html</link>
            <guid>http://www.nearinfinity.com/blogs/scott_leberknight/what_not_to_show_a.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">General</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Security</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">security error</category>
            
            <pubDate>Sat, 12 Apr 2008 16:00:48 -0500</pubDate>
        </item>
        
        <item>
            <title>Filtering JavaScript From HTML Content in Java (Sanitizing user input)</title>
            <description><![CDATA[<p>I gave a <a href="http://www.nearinfinity.com/blogs/page/jharwig?entry=javascript_security_slides_from_no">JavaScript security</a> talk last month, and one of the topics was HTML filtering.  I gave examples of how MySpace tried to filter executable code, while still allowing HTML tags for formatting.  MySpace, of course, failed to foresee every attack vector, and the <a href="http://namb.la/popular/tech.html">Samy worm</a> was born.</p>

<p>HTML filtering was never recommended because it was so difficult to get right, and with no proven libraries, trying to build a solution would almost certainly contain security holes. Thanks to Arshan Dabirsiaghi we finally have something to use. He has created the <a href="http://www.owasp.org/index.php/Category:OWASP_AntiSamy_Project">OWASP AntiSamy</a> project to easily sanitize HTML input.  AntiSamy is currently implemented as a Java 1.5 compatible library, but there are plans to support other platforms.</p>

Here's a sample usage <br />
<code class="prettyprint">
AntiSamy sanitizer = new AntiSamy();
CleanResults results = sanitizer.scan(request.getParameter("html"));
String html = results.getCleanHTML();
if (!results.getErrorMessages().isEmpty()) {
    log.warn("Input contains errors");
}
</code>]]></description>
            <link>http://www.nearinfinity.com/blogs/jason_harwig/filtering_scripts_from_html_content.html</link>
            <guid>http://www.nearinfinity.com/blogs/jason_harwig/filtering_scripts_from_html_content.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Java</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Security</category>
            
            
            <pubDate>Sat, 01 Dec 2007 15:56:33 -0500</pubDate>
        </item>
        
        <item>
            <title>Application Versus Database Security</title>
            <description><![CDATA[<p>
The merits of placing security in the application layer versus the database is a debate I seem to find myself in regularly. As an application developer, I've historically argued for application-level security. It was something I understood well and felt like I had some control over. Over time, I've come to understand the debate from many perspectives and have adjusted my convictions accordingly.
</p>
<p>
For the record, I don't believe there is any absolutely correct answer. There are valid arguments for each side of the debate. My perspective has mostly been shaped through experience developing custom software for clients. I have little experience developing commercial software and surmise that your thoughts on the subject may differ if that's your day job.
</p>
<p>
In my experience, most customers view their data as the most important aspect of any system, not the application. They want to be sure their data is safe at all times. What if someone accesses the database through a different application, a third-party data broker or directly via a SQL client? How do you protect the data in those situations if all the restrictions are resident in the application? I hear these questions all the time.
</p>
<p>
The rebuttal to this argument that I hear most often is that nobody will ever access the data outside of the application. This seems like an obviously shortsighted statement to me and I don't think anyone actually believes it. It's more of a synonym for saying that you'd rather not worry about security at the database layer because it's out of your control, too hard, etc. Pick your favorite excuse. I've probably used them all myself.
</p>
<p>
What it all boils down to is that the database is very likely to outlive your application. In fact, it'll probably outlive your application and several subsequent ones. Why would a customer want to pay someone to rebuild the security logic each time? It's tedious, expensive, and error prone. Additionally, you're application may not be the only one accessing the database. What are the odds that two development teams implement security constraints the same exact way in each application? Not good, I promise.
</p>
<p>
As I stated in the beginning, I've definitely changed my perspectives on application versus database-level security. I was certainly an application-level security bigot before, but I find it difficult to continue my unwavering ways when looking at the problem more critically. I just hope my fellow colleagues don't renounce me for siding with the DBAs on this one.
</p>]]></description>
            <link>http://www.nearinfinity.com/blogs/jeff_kunkle/application_versus_database_security.html</link>
            <guid>http://www.nearinfinity.com/blogs/jeff_kunkle/application_versus_database_security.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Security</category>
            
            
            <pubDate>Mon, 26 Nov 2007 07:30:00 -0500</pubDate>
        </item>
        
        <item>
            <title>JavaScript Security Slides from No Fluff Just Stuff</title>
            <description><![CDATA[<p>I spoke at the Reston, VA <a href="http://www.nofluffjuststuff.com">No Fluff Just Stuff</a> conference again this past weekend.  The talk was on JavaScript security covering topics including:
</p><ul>
<li>Cross-site scripting (XSS)</li>
<li>Cross-site-request forgery (CSRF)</li>
<li>JSON Hi-jacking</li>
<li>JavaScript portscanning</li>
<li>JavaScript and CSS History "Go Fish"</li>
</ul>]]></description>
            <link>http://www.nearinfinity.com/blogs/jason_harwig/javascript_security_slides_from_no.html</link>
            <guid>http://www.nearinfinity.com/blogs/jason_harwig/javascript_security_slides_from_no.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">JavaScript</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Security</category>
            
            
            <pubDate>Thu, 08 Nov 2007 19:38:27 -0500</pubDate>
        </item>
        
        <item>
            <title>Solid State Encrypted Drives - The next big thing?</title>
            <description><![CDATA[<p>I've noticed two topics generating a lot of buzz in the storage world lately.</p>

<ol>
<li>Hardware-Encrypted Disk Drives</li>
<li>Solid State Disk Drives</li>
</ol>

<p>I believe the first topic is a direct result of the disclosure of scores of high-profile data breaches resulting from stolen computers. The highest profile instance occurred in May of 2006 when a U.S. Department of Veteran's Affairs laptop containing the names, social security numbers, dates of birth, phone numbers, and addresses of 26.5 million American veterans was stolen. Unauthorized information disclosure has unfortunately become an all too common occurrence in today's world.</p>

<p>In response, vendors such as Seagate have introduced <a href="http://www.eweek.com/article2/0,1759,1825740,00.asp">hardware-encrypted notebook hard drives</a> to counter the unintended loss of sensitive information when a computer is stolen. The idea is that data stored on the hard drive is encrypted at all times, rendering the information practically useless to thieves. The encryption is done in specialized hardware to reduce the performance impact associated with the extra computation. </p>

<p>The second topic is the result of a continued increase in flash-based memory capacity to the point where it can now be considered as an alternative to traditional hard drives. Both Samsung and Sandisk have <a href="http://www.eweek.com/article2/0,1759,2108422,00.asp">recently announced</a> 64GB (Samsung) and 32GB (Sandisk) products targeted for laptop usage. Since there are no moving parts, flash-based memory consumes much less power than the spinning platters of a traditional hard disk, which is obviously a big benefit for laptop users. As a side benefit, these flash-based memory "drives" are rumored to be anywhere from 4-10x faster than a traditional hard drive, which brings me to the main point of this post.</p>

<p>How long will it be until we see solid-state "drives" such as the ones from Samsung and Sandisk coupled with dedicated hardware-based encryption as demonstrated on the new Seagate drive? A considerable downside to full-disk encryption of traditional drives is the performance impact. Since the new flash-based drives are several times faster, why not bake in full-drive encryption now when nobody will notice it. What you'd end up with are flash-based drives that provide full-disk encryption and still outperform traditional drives. Waiting to add full-disk encryption to later versions of flash-based drives will only introduce the performance debate that faces today's traditional drives, making the purchasing decision all that much more difficult. Why not avoid the confusion and help customers better secure their data in the process?</p>]]></description>
            <link>http://www.nearinfinity.com/blogs/jeff_kunkle/solid_state_encrypted_drives_the.html</link>
            <guid>http://www.nearinfinity.com/blogs/jeff_kunkle/solid_state_encrypted_drives_the.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Security</category>
            
            
            <pubDate>Sun, 15 Apr 2007 21:10:11 -0500</pubDate>
        </item>
        
        <item>
            <title>XSS Vulnerabilities of JSP 2.0 Expressions</title>
            <description><![CDATA[<p>JSP 2.0 introduced a handy new capability allowing you to use JSP Expressions directly within the template text (i.e. outside of tag libraries or tag files) of a web page. This allows developers to easily expose data and objects stored in application, session, request, or page scope using a simple Ant-style syntax. It allows you to replace this</p>

<pre class="prettyprint">
&lt;table&gt;
&lt;c:forEach var="book" items="${books}"&gt;
&lt;tr&gt;
&lt;td&gt;&lt;c:out value="${book.title}"/&gt;&lt;/td&gt;
&lt;td&gt;&lt;c:out value="${book.author}"/&gt;&lt;/td&gt;
&lt;td&gt;&lt;c:out value="${book.isbn}"/&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/c:forEach&gt;
&lt;/table&gt;
</pre>

<p>with this</p>

<pre class="prettyprint">
&lt;table&gt;
&lt;c:forEach var="book" items="${books}"&gt;
&lt;tr&gt;
&lt;td&gt;${book.title}&lt;/td&gt;
&lt;td&gt;${book.author}&lt;/td&gt;
&lt;td&gt;${book.isbn}&lt;/td&gt;
&lt;/tr&gt;
&lt;/c:forEach&gt;
&lt;/table&gt;
</pre>

<p>As you can see, the syntax in the second example is much cleaner. But, &#8220;with great power comes great responsibility.&#8221; The chink in the armor that every tutorial I&#8217;ve read (including <a href="http://java.sun.com/javaee/5/docs/tutorial/doc/index.html">Sun&#8217;s Java EE 5 Tutorial</a> fails to mention is that the expression syntax does not escape HTML characters. Therefore, <em>any web application using JSP Expressions to output unsanitized, user-entered data will be vulnerable to Cross Site Scripting (XSS) attacks.</em></p>

<p>Unfortunately, the cure for this XSS vulnerability leads us right back to our first example. As section 2.2.2 of the <a href="http://jcp.org/aboutJava/communityprocess/final/jsr152">JSP 2.0 Specification</a> reads, &#8220;In cases where escaping is desired (for example, to help prevent cross-site scripting attacks), the JSTL core tag c:out can be used.&#8221; </p>

<p>My advice is to use JSP Expressions only as tag library attribute values and stick to using JSTL&#8217;s c:out tag for writing text to a page. Deciding which instances of template text expression usage are safe and which are not is simply too error prone and the consequences of a mistake too dangerous.</p>
]]></description>
            <link>http://www.nearinfinity.com/blogs/jeff_kunkle/beware_of_xss_when_using.html</link>
            <guid>http://www.nearinfinity.com/blogs/jeff_kunkle/beware_of_xss_when_using.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Security</category>
            
            
            <pubDate>Sun, 25 Jun 2006 15:46:48 -0500</pubDate>
        </item>
        
    </channel>
</rss>

