<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Devon Hillard&#039;s Digital Sanctuary &#187; Security</title>
	<atom:link href="http://www.digitalsanctuary.com/tech-blog/tag/security/feed" rel="self" type="application/rss+xml" />
	<link>http://www.digitalsanctuary.com/tech-blog</link>
	<description>Java, ATG, Seam, and related Technologies</description>
	<lastBuildDate>Mon, 30 Jan 2012 23:04:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Seam Identity Management</title>
		<link>http://www.digitalsanctuary.com/tech-blog/java/jboss/seam/seam-identity-management.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/java/jboss/seam/seam-identity-management.html#comments</comments>
		<pubDate>Mon, 11 Jul 2011 15:34:32 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[Seam]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=761</guid>
		<description><![CDATA[During a recent coding getaway to Maine (see my post on the 2011 HackFestaThon) I decided to write a basic Seam project as a starting point for my future Seam based web applications.  The idea is to provide common features &#8230; <a href="http://www.digitalsanctuary.com/tech-blog/java/jboss/seam/seam-identity-management.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>During a recent coding getaway to Maine (see my post on the <a title="Coding Weekend in Maine 2011" href="http://www.digitalsanctuary.com/blog/uncategorized/weekend-in-maine.html" target="_blank">2011 HackFestaThon</a>) I decided to write a basic Seam project as a starting point for my future Seam based web applications.  The idea is to provide common features such as Login, Logout, Registration, Forgot Password, User Management, Audit Logging, Image Upload Handling, Video Upload Handling, etc&#8230; so next time I have an idea that I want to hack together I won&#8217;t have to re-write or copy-paste in basic functionality like that.</p>
<p>I spent about a day working on things before I discovered that I really should be using the <a title="Seam 2.2 Identity Management" href="http://docs.jboss.org/seam/2.2.2.Final/reference/en-US/html/security.html#d0e9101" target="_blank">Seam framework&#8217;s Identity Management</a> feature.  So I threw out everything I&#8217;d done, and started by re-reading the docs, and went from there.  Seam&#8217;s Identity Management framework is VERY powerful, but is also a little complicated to get going and in many cases it seems like it would easier to just write stuff from scratch.  I&#8217;m banking on the powerful stuff being worth the initial learning curve and a little extra pain.</p>
<p>When I get the starter project in a more complete state I will be open sourcing the whole thing to help others along, but I wanted to share a few things I&#8217;ve learned so far:</p>
<p>In order to use the Email address as the login instead of a username, you need to remove the username property from your UserAccount entity and annotate the Email address property like so:</p>
<pre class="brush: java; title: ; notranslate">
@NotNull
@UserPrincipal
@Email
public String getEmail() {
    return email;
}
</pre>
<p>Actions like Registration need a RunAsOperation inner class to handle the fine grained security controls that the Identity Management framework enforces:</p>
<pre class="brush: java; title: ; notranslate">
    public void register() {
	verified = (confirm != null &amp;&amp; confirm.equals(password));

	if (!verified) {
	    FacesMessages.instance().addToControl(&quot;confirmPassword&quot;, &quot;Passwords do not match&quot;);
	}
	new RunAsOperation() {
	    public void execute() {
		try {
		    // Check if email address has already been used
		    if (identityManager.userExists(getEmail())) {
			FacesMessages.instance().addToControl(&quot;email&quot;, &quot;Email has already been used.&quot;);
			return;
		    }
		    identityManager.createUser(email, password, mFirstName, mLastName);
		} catch (IdentityManagementException e) {
		    // TODO Auto-generated catch block
		    e.printStackTrace();
		}
		identityManager.grantRole(email, &quot;member&quot;);
	    }
	}.addRole(&quot;admin&quot;).run();

	// Login the user
	identity.getCredentials().setUsername(email);
	identity.getCredentials().setPassword(password);
	identity.login();
    }
</pre>
<p>Populating custom properties on the User during things like registration requires observing events:</p>
<pre class="brush: java; title: ; notranslate">
    @Observer(JpaIdentityStore.EVENT_PRE_PERSIST_USER)
    public void prePersistUser(UserAccount pNewUser) {
	// Setup additional UserAccount properties before the user is created
	pNewUser.setRegistrationDate(new Date());
	pNewUser.setOptIn(isOptIn());
    }
</pre>
<p>You can log audit events with the user&#8217;s IP address by doing things like this:</p>
<pre class="brush: java; title: ; notranslate">
@Scope(ScopeType.EVENT)
@Name(&quot;userEvents&quot;)
public class UserEvents {
    @Logger
    private Log mLog;

    @Observer(JpaIdentityStore.EVENT_USER_AUTHENTICATED)
    public void loginSuccessful(UserAccount pUser) {
	mLog.info(&quot;User logged in with email: #0&quot;, pUser.getEmail());
	pUser.setLastLoginDate(new Date());
	Contexts.getSessionContext().set(&quot;currentUser&quot;, pUser);
	AuditEvent loginEvent = new AuditEvent(((ServletRequest) FacesContext.getCurrentInstance().getExternalContext()
		.getRequest()).getRemoteAddr(), pUser.getId(), &quot;Login Success&quot;, null);
	Events.instance().raiseEvent(&quot;auditEvent&quot;, loginEvent);
    }
}
</pre>
<p>Hopefully I&#8217;ll have the starter project ready soon and will share it with you all.  In the meantime, happy hacking!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/java/jboss/seam/seam-identity-management.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Spark::red is PCI Level 1 Certified!</title>
		<link>http://www.digitalsanctuary.com/tech-blog/java/atg/sparkred-is-pci-level-1-certified.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/java/atg/sparkred-is-pci-level-1-certified.html#comments</comments>
		<pubDate>Thu, 07 Jul 2011 13:45:33 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[ATG]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Spark::red]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=750</guid>
		<description><![CDATA[I&#8217;m happy to announce that Spark::red ATG Hosting has received our PCI DSS 1.2 Level 1 Certification as an eCommerce MSP.  We have been Level 2 certified for a while, but completing our Level 1 certification with TrustWave as our &#8230; <a href="http://www.digitalsanctuary.com/tech-blog/java/atg/sparkred-is-pci-level-1-certified.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div id="attachment_751" class="wp-caption alignright" style="width: 310px"><img class="size-full wp-image-751 " title="Security Image" src="http://www.digitalsanctuary.com/tech-blog/wp-content/uploads/2011/07/2907496392_410f480f6b.jpg" alt="" width="300" height="192" /><p class="wp-caption-text">image from Purpleslog</p></div>
<p>I&#8217;m happy to announce that <a title="Sparkred ATG Managed Hosting" href="https://www.sparkred.com" target="_blank">Spark::red ATG Hosting</a> has received our PCI DSS 1.2 Level 1 Certification as an eCommerce MSP.  We have been Level 2 certified for a while, but completing our Level 1 certification with <a title="TrustWave Security" href="https://www.trustwave.com/" target="_blank">TrustWave</a> as our third-party auditor is a huge milestone for us.</p>
<p>PCI DSS is the <a title="PCI Security Standards" href="https://www.pcisecuritystandards.org/" target="_blank">Payment Card Industry&#8217;s Data Security Standard</a>.  It is a set of requirements and guidelines designed to ensure merchants who handle or process credit cards, do so securely.  There are different levels based on transaction volume and <a title="PCI Levels" href="http://www.pcicomplianceguide.org/pcifaqs.php#5" target="_blank">Level 1</a> is the highest level, required for the largest volume merchants.  Level 1 is also the most difficult certification to gain, requiring the strictest security protections, the strongest policies, and a very in depth audit by a certified auditing company, such as TrustWave.  Our certification process has taken many months and the completion of our Level 1 Report of Compliance (RoC) is a testament to our dedication to providing the highest level of secure environments to our clients and safeguarding their systems and information, as well as the information of all our clients&#8217; customers.</p>
<p>At Spark::red we focus strongly on Security and Performance beyond the core ATG hosting services.  We handle more PCI DSS requirements than any other ATG Hosting provider out there.  If you are looking for an ATG Hosting provider to help manage your ATG web application, we can offer PCI Level 1 compliant hosting and handle many of your security needs.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/java/atg/sparkred-is-pci-level-1-certified.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>DDOS Against 10MinuteMail</title>
		<link>http://www.digitalsanctuary.com/tech-blog/security/ddos-against-10minutemail.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/security/ddos-against-10minutemail.html#comments</comments>
		<pubDate>Mon, 22 Feb 2010 01:29:13 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[10MinuteMail]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[CSF]]></category>
		<category><![CDATA[DDOS]]></category>
		<category><![CDATA[Firewall]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=590</guid>
		<description><![CDATA[You may have noticed 10MinuteMail was unavailable for a few minutes over the last couple of days. 10MinuteMail recently came under a DDOS attack which locked up the site a few times. Most of the malicious traffic came from the &#8230; <a href="http://www.digitalsanctuary.com/tech-blog/security/ddos-against-10minutemail.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>You may have noticed <a href="http://10minutemail.com">10MinuteMail</a> was unavailable for a few minutes over the last couple of days.  10MinuteMail recently came under a DDOS attack which locked up the site a few times.  Most of the malicious traffic came from the Netherlands, Germany, and to a lesser extend other European countries and the USA.  Initially I dealt with it by generating a list of the malicious IPs and adding them to my block list.  However, the DDOS kept spreading (botnet?) so I finally did what I should have done ages ago, and tuned my CSF/IPTables firewall to block DDOS patterns.  So far so good:)</p>
<p>I have NO IDEA why anyone would be attacking 10MinuteMail.  It&#8217;s very odd.  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/security/ddos-against-10minutemail.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Automated ClamAV Virus Scanning</title>
		<link>http://www.digitalsanctuary.com/tech-blog/debian/automated-clamav-virus-scanning.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/debian/automated-clamav-virus-scanning.html#comments</comments>
		<pubDate>Wed, 27 Jan 2010 00:07:57 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[RedHat]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=531</guid>
		<description><![CDATA[Automating Linux Anti-Virus Using ClamAV and Cron Thankfully Linux isn&#8217;t a platform which has a significant problem with Viruses, however it is always better to be safe than sorry. Luckily ClamAV is an excellent free anti-virus solution for Linux servers. &#8230; <a href="http://www.digitalsanctuary.com/tech-blog/debian/automated-clamav-virus-scanning.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h1>Automating Linux Anti-Virus Using ClamAV and Cron</h1>
<p>Thankfully Linux isn&#8217;t a platform which has a significant problem with Viruses, however it is always better to be safe than sorry.  Luckily ClamAV is an excellent free anti-virus solution for Linux servers.  However, at least on RedHat Enterprise 5 (RHEL5) the default install doesn&#8217;t offer any automated scanning and alerting.  So here is what I&#8217;ve done:</p>
<p>The following steps assume you are using RHEL5, but should apply to other Linux distributions as well.</p>
<h2>First, you&#8217;ll want to install ClamAV:</h2>
<pre class="brush: bash; light: true; title: ; notranslate">
yum install clamav clamav-db clamd
/etc/init.d/clamd start
</pre>
<p>On RHEL5 at least this automatically sets up a daily cron job that uses freshclam to update the virus definitions, so that&#8217;s good.</p>
<p>Next I recommend removing the test virus files, although you can save this until after you test the rest of the setup:</p>
<pre class="brush: bash; light: true; title: ; notranslate">
rm -rf /usr/share/doc/clamav-0.95.3/test/
</pre>
<p>Now we want to setup our automation.  I have a daily cron job that scans the entire server which can take several minutes, and then an hourly cron job that only scans files which were created or modified within the last hour.  This should provide rapid notification of any infection without bogging your server down for 5 minutes every hour.  The hourly scans run in a couple of seconds.</p>
<p>Each scanning script then checks the scan logs to see if there were any infected files found, and if so immediately sends you a notification e-mail (you could set this address to your mobile phone&#8217;s SMS account if you wanted).</p>
<h2>The Daily Scan:</h2>
<pre class="brush: bash; light: true; title: ; notranslate">
emacs /etc/cron.daily/clamscan_daily
</pre>
<p>Paste in:</p>
<pre class="brush: bash; title: ; notranslate">
#!/bin/bash

# email subject
SUBJECT=&quot;VIRUS DETECTED ON `hostname`!!!&quot;
# Email To ?
EMAIL=&quot;me@domain.com&quot;
# Log location
LOG=/var/log/clamav/scan.log

check_scan () {

	# Check the last set of results. If there are any &quot;Infected&quot; counts that aren't zero, we have a problem.
	if [ `tail -n 12 ${LOG}  | grep Infected | grep -v 0 | wc -l` != 0 ]
	then
		EMAILMESSAGE=`mktemp /tmp/virus-alert.XXXXX`
		echo &quot;To: ${EMAIL}&quot; &gt;&gt;  ${EMAILMESSAGE}
		echo &quot;From: alert@domain.com&quot; &gt;&gt;  ${EMAILMESSAGE}
		echo &quot;Subject: ${SUBJECT}&quot; &gt;&gt;  ${EMAILMESSAGE}
		echo &quot;Importance: High&quot; &gt;&gt; ${EMAILMESSAGE}
		echo &quot;X-Priority: 1&quot; &gt;&gt; ${EMAILMESSAGE}
		echo &quot;`tail -n 50 ${LOG}`&quot; &gt;&gt; ${EMAILMESSAGE}
		sendmail -t &lt; ${EMAILMESSAGE}
	fi

}

clamscan -r / --exclude-dir=/sys/ --quiet --infected --log=${LOG}

check_scan
</pre>
<pre class="brush: bash; light: true; title: ; notranslate">
chmod +x /etc/cron.daily/clamscan_daily
</pre>
<h2>The Hourly Scan:</h2>
<pre class="brush: bash; light: true; title: ; notranslate">
emacs /etc/cron.hourly/clamscan_hourly
</pre>
<p>Paste in:</p>
<pre class="brush: bash; title: ; notranslate">
#!/bin/bash

# email subject
SUBJECT=&quot;VIRUS DETECTED ON `hostname`!!!&quot;
# Email To ?
EMAIL=&quot;me@domain.com&quot;
# Log location
LOG=/var/log/clamav/scan.log

check_scan () {

	# Check the last set of results. If there are any &quot;Infected&quot; counts that aren't zero, we have a problem.
	if [ `tail -n 12 ${LOG}  | grep Infected | grep -v 0 | wc -l` != 0 ]
	then
		EMAILMESSAGE=`mktemp /tmp/virus-alert.XXXXX`
		echo &quot;To: ${EMAIL}&quot; &gt;&gt;  ${EMAILMESSAGE}
		echo &quot;From: alert@domain.com&quot; &gt;&gt;  ${EMAILMESSAGE}
		echo &quot;Subject: ${SUBJECT}&quot; &gt;&gt;  ${EMAILMESSAGE}
		echo &quot;Importance: High&quot; &gt;&gt; ${EMAILMESSAGE}
		echo &quot;X-Priority: 1&quot; &gt;&gt; ${EMAILMESSAGE}
		echo &quot;`tail -n 50 ${LOG}`&quot; &gt;&gt; ${EMAILMESSAGE}
		sendmail -t &lt; ${EMAILMESSAGE}
	fi

}

find / -not -wholename '/sys/*' -and -not -wholename '/proc/*' -mmin -61 -type f -print0 | xargs -0 -r clamscan --exclude-dir=/proc/ --exclude-dir=/sys/ --quiet --infected --log=${LOG}
check_scan

find / -not -wholename '/sys/*' -and -not -wholename '/proc/*' -cmin -61 -type f -print0 | xargs -0 -r clamscan --exclude-dir=/proc/ --exclude-dir=/sys/ --quiet --infected --log=${LOG}
check_scan
</pre>
<pre class="brush: bash; light: true; title: ; notranslate">
chmod +x /etc/cron.hourly/clamscan_hourly
</pre>
<h2>Protected System</h2>
<p>You should now have a well protected system with low impact to system performance and rapid alerting.  Anti-Virus is only one piece of protecting a server, but hopefully this makes it easy to implement for everyone.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/debian/automated-clamav-virus-scanning.html/feed</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Monster.com Security Breach</title>
		<link>http://www.digitalsanctuary.com/tech-blog/java/atg/monstercom-security-breach.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/java/atg/monstercom-security-breach.html#comments</comments>
		<pubDate>Sat, 24 Jan 2009 04:59:10 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[ATG]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[hackers]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=239</guid>
		<description><![CDATA[The Monster.com job board database was illegally accessed and large amounts of user data were stolen. As is the case with many companies that maintain large databases of information, Monster is the target of illegal attempts to access and extract &#8230; <a href="http://www.digitalsanctuary.com/tech-blog/java/atg/monstercom-security-breach.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://monster.com">Monster.com</a> job board database was <a href="http://help.monster.com/besafe/jobseeker/index.asp">illegally accessed and large amounts of user data were stolen</a>.</p>
<p><a href="http://www.digitalsanctuary.com/tech-blog/wp-content/uploads/2009/01/2746775792_12b9a7bed9.jpg"><img src="http://www.digitalsanctuary.com/tech-blog/wp-content/uploads/2009/01/2746775792_12b9a7bed9.jpg" alt="Monster" title="Monster" width="300" height="400" class="alignright size-full wp-image-241" /></a></p>
<blockquote><p>As is the case with many companies that maintain large databases of information, Monster is the target of illegal attempts to access and extract information from its database. We recently learned our database was illegally accessed and certain contact and account data were taken, including Monster user IDs and passwords, email addresses, names, phone numbers, and some basic demographic data. The information accessed does not include resumes. Monster does not generally collect – and the accessed information does not include &#8211; sensitive data such as social security numbers or personal financial data.</p></blockquote>
<p>The fact that the database was accessed illegally (no word on if it was an internal or external access) is a huge deal.  However the fact that they stored passwords in either plaintext, or in a weak enough hash that they feel all the user passwords are compromised, is the most disturbing part of this news in my opinion.  </p>
<p>
<div class="alignright"><font size="-4">Photo by <a href="http://www.flickr.com/photos/dave-rogers/">Dave</a></font></div>
<p>There is no excuse for either of those security failures.  Especially after the <a href="http://www.msnbc.msn.com/id/20534586/">highly public loss of 1.3 million users&#8217; data in 2007</a>.</p>
<p>Assume that your database will be accessed at some point by someone with nefarious intent.  If it can happen to Monster.com it can happen to you.  Therefore you should not store passwords in plaintext or weakly hashed.  </p>
<p>Use a salted SHA-256 or bcrypt hashing algorithm to protect your users&#8217; accounts.  </p>
<p>If you use ATG please check out the open source <a href="http://developer.sparkred.com/confluence/display/ATGDC/DigitalSanctuary+Modules">SecurePassword ATG module</a>.  It replaces the default insecure password hashing algorithm with a salted SHA-256 hashing mechanism.  (as a side note I will develop a bcrypt version shortly, but SSHA-256 is very secure).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/java/atg/monstercom-security-breach.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>AT&amp;T DNS Cache Poisoning</title>
		<link>http://www.digitalsanctuary.com/tech-blog/security/att-dns-cache-poisoning.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/security/att-dns-cache-poisoning.html#comments</comments>
		<pubDate>Fri, 01 Aug 2008 01:19:47 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[Security]]></category>
		<category><![CDATA[dns]]></category>
		<category><![CDATA[phishing]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=140</guid>
		<description><![CDATA[Recently there has been a lot of press about AT&#038;T DNS servers being hit with a DNS Cache Poisoning attack. Some new easier exploits were recently published, and many DNS servers are still vulnerable. And up until the new exploits &#8230; <a href="http://www.digitalsanctuary.com/tech-blog/security/att-dns-cache-poisoning.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Recently there has been a lot of press about <a href="http://www.google.com/search?q=AT%26T%20DNS%20poisoning" target="_new">AT&#038;T DNS servers being hit with a DNS Cache Poisoning</a> attack.  </p>
<p>Some new easier exploits were recently published, and many DNS servers are still vulnerable.  And up until the new exploits were published publicly, the majority of DNS servers were vulnerable.  This situation is worse once you realize that &#8220;safe&#8221; DNS servers can be poisoned second hand by transitive trust relationships, allowing one compromised DNS server to effectually poison the caches of other un-compromised DNS servers.</p>
<p>DNS Cache Poisoning has been a serious issue for years.  The recent flurry of press regarding the compromised AT&#038;T DNS servers is just the tip of the iceberg.  It is only reasonable to assume that over the past several years a large number of DNS server have been serving compromised results at some point, either by direct poisoning or indirect poisoning.  It is also reasonable to assume that this will continue for the foreseeable future.  </p>
<p>In light of this, please re-read my post on <a href="http://www.digitalsanctuary.com/tech-blog/security/lions-and-tigers-and-third-party-javascript.html" target="_new">3rd party Javascript</a>.</p>
<p>If I were a malicious hacker, let&#8217;s say working for the Russian Mob, or for myself, here is the easiest way to make some money:</p>
<p>1. Create javascript files designed to mask Google Adwords, Google Analytics, Doubleclick Ads, Overture Ads, and maybe a couple others.  These scripts would have their cache related response headers set to be cached on the browser for 1 year.  These scripts would call back to the real versions of themselves (so that ads show up, etc&#8230;).  They would also intercept any form submission events and would look for form fields with names like &#8220;creditcard&#8221; or &#8220;ssn&#8221; or &#8220;password&#8221; or &#8220;accountnumber&#8221;, etc&#8230;  If any are found, it would essentially clone the form and send the form data, the site hostname and page, the client&#8217;s IP address and cookies, etc&#8230; to a server I control.</p>
<p>2. Start cache poisoning as many DNS servers as I could find that are vulnerable to point the REAL domains for those scripts to my malicious copies.  </p>
<p>3. Sit back and watch the Credit Card numbers roll in.</p>
<p>The best part is that by getting the browser to cache the script locally, I only have to have a computer hit the poisoned cache once to control it for a whole year.  On most IE6 installations it&#8217;s also easy to actually install a javascript application on the user&#8217;s computer.</p>
<p>Personally I use Google javascripts on my site.  However I don&#8217;t capture credit card numbers here, so the risk is low.  If you run an e-commerce site, please do not underestimate the risks involved here.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/security/att-dns-cache-poisoning.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using IPTables to Prevent SSH Brute Force Attacks</title>
		<link>http://www.digitalsanctuary.com/tech-blog/debian/using-iptables-to-prevent-ssh-brute-force-attacks.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/debian/using-iptables-to-prevent-ssh-brute-force-attacks.html#comments</comments>
		<pubDate>Sun, 25 May 2008 06:11:28 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[iptables]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[ssh]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=119</guid>
		<description><![CDATA[If you have a server with a world facing ssh server, you&#8217;ve probably seen brute force attacks in your logs. Some machine starts hammering your ssh server, trying all sorts of logins (staff, root, a, admin, etc&#8230;) over and over &#8230; <a href="http://www.digitalsanctuary.com/tech-blog/debian/using-iptables-to-prevent-ssh-brute-force-attacks.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>If you have a server with a world facing ssh server, you&#8217;ve probably seen brute force attacks in your logs.  Some machine starts hammering your ssh server, trying all sorts of logins (staff, root, a, admin, etc&#8230;) over and over and over again.</p>
<p>This is bad on a lot of fronts.</p>
<p>I use two simple iptables rules to block any IP address who has made more than 3 ssh connections or attempted connections within the past 3 minutes.  So your would-be brute force attacker, gets three tries, and then is locked out for a minimum of three minutes.  However, since 99% of the attacks are run by an automated bot, it will either: give up after the connection is refused multiple times, or it will keep hammering away on the closed door, which keeps the running count of attempted connections in the past 3 minutes over 3, keeping the door closed.</p>
<p>First:</p>
<p><code>iptables -I INPUT -i eth1 -p tcp -m tcp --dport 22 -m state --state NEW -m recent --set --name DEFAULT --rsource</code></p>
<p>Then run:</p>
<p><code>iptables -I INPUT -i eth1 -p tcp -m tcp --dport 22 -m state --state NEW -m recent --update --seconds 180 --hitcount 4 --name DEFAULT --rsource -j DROP</code></p>
<p>I&#8217;d also recommend using the script in my post on <a href="http://www.digitalsanctuary.com/tech-blog/debian/how-to-block-an-ip-in-linux.html" target="_new">blocking IP addresses using iptables </a>to deal with any persistent folks, or people poking too hard on your web site, or other services.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/debian/using-iptables-to-prevent-ssh-brute-force-attacks.html/feed</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>Getting the Real IP Address from a Proxied Request in ATG</title>
		<link>http://www.digitalsanctuary.com/tech-blog/java/atg/getting-the-real-ip-address-from-a-proxied-request-in-atg.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/java/atg/getting-the-real-ip-address-from-a-proxied-request-in-atg.html#comments</comments>
		<pubDate>Wed, 09 Apr 2008 00:32:41 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[ATG]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[proxy]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=89</guid>
		<description><![CDATA[Many things can obscure the real IP address of the end user when they visit your site: a load balancer in front of your ATG cluster, Akamai, the user&#8217;s ISP or office network, and more. This makes correlating logging events, &#8230; <a href="http://www.digitalsanctuary.com/tech-blog/java/atg/getting-the-real-ip-address-from-a-proxied-request-in-atg.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Many things can obscure the real IP address of the end user when they visit your site: a load balancer in front of your ATG cluster, Akamai, the user&#8217;s ISP or office network, and more.  This makes correlating logging events, or using the ATG session IP validation security option, and more, very difficult.  In light of that challange I&#8217;ve added a new mini-module to my <a href="http://www.digitalsanctuary.com/atg-dynamo-technologies.html" target="_new">Open Source ATG Modules</a> called the ProxyIPFixer.  It uses a simple ATG pipeline Servlet to examine the X-FORWARDED-FOR request header, and if it finds one, parse through the IP addresses to find the originating IP address of the user, and puts that value into the ATG Request object&#8217;s remoteAddr property.</p>
<p>This allows downstream pipeline servlets, code, and pages to see the real user&#8217;s IP address.  </p>
<p>The caveat is that the header can be faked, and that some ISPs/companies, such as AOL, do not set the true end point of the user, and you can only see back to their outgoing proxy server.  In AOL&#8217;s case in particular, they can also route subsequent requests by the same AOL user through different AOL proxy points, which will make it appear that someone is hijacking a session (if you&#8217;re using the ATG session security mechanism).  So be aware of the limitations.  However it can be very useful.</p>
<p>For those who don&#8217;t want to download the whole module package, I have attached the Java source and the ATG properties file to this post.</p>
<p>Enjoy!  (and as always feel free to contact me with questions, issues, improvements, etc&#8230;)</p>
<p><a href='http://www.digitalsanctuary.com/tech-blog/wp-content/uploads/2008/04/proxyipfixerservlet.java' target="_new">ProxyIPFixerServlet Java Source</a></p>
<p><a href='http://www.digitalsanctuary.com/tech-blog/wp-content/uploads/2008/04/proxyipfixer.properties' target="_new">ProxyIPFixer ATG Properties File</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/java/atg/getting-the-real-ip-address-from-a-proxied-request-in-atg.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>login-required=&#8221;true&#8221; Will End Your Conversation</title>
		<link>http://www.digitalsanctuary.com/tech-blog/java/jboss/seam/login-requiredtrue-will-end-your-conversation.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/java/jboss/seam/login-requiredtrue-will-end-your-conversation.html#comments</comments>
		<pubDate>Tue, 11 Mar 2008 06:04:03 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[Seam]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[conversations]]></category>
		<category><![CDATA[identity]]></category>
		<category><![CDATA[jsf]]></category>
		<category><![CDATA[login]]></category>
		<category><![CDATA[login-required]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/java/jboss/seam/login-requiredtrue-will-end-your-conversation.html</guid>
		<description><![CDATA[In Seam, in the pages.xml or mypage.page.xml files, you note that a given page requires the user to be logged in to view the page. It is a very easy way of handling simple security. What happens is if a &#8230; <a href="http://www.digitalsanctuary.com/tech-blog/java/jboss/seam/login-requiredtrue-will-end-your-conversation.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In Seam, in the pages.xml or mypage.page.xml files, you note that a given page requires the user to be logged in to view the page.  It is a very easy way of handling simple security.  What happens is if a user attempts to access a page with the <code>login-required="true"</code> attribute and they are not logged in, they are automatically redirected to your login page (as defined in your pages.xml).  Once they login, they are automatically redirected back to the page they had attempted to access initially.  Very elegant, and much easier than writing all that yourself.</p>
<p>There is however a &#8220;gotcha&#8221; you should be aware of in this flow.  If you use the login page, or logic, to start a long running conversation (I do this because my User entity object has some large binary properties which I want lazily loaded), the post-login redirection will kill that conversation.  In my case this led to lazy loading exceptions down the road.  </p>
<p>It took me a while to figure out the cause, as it only happened much later in the application, and most of the time it worked (when I logged in purposefully from the main page), but sometimes would break (when I&#8217;d had an expired session and gone through the login auto-redirection flow).  Eventually though I was able to track it down to those two scenarios.</p>
<p>What is happening is this: before the first redirection happens (to the login page), the Seam Redirect classes <code>captureCurrentView</code> method is called.  This basically saves the information about the page you were trying to view (it&#8217;s a little more complex than that- being all Faces like and whatnot, but that&#8217;s the gist of it).  This method creates a long running conversation in order to hold this state across the multiple pages.  If there was no previous long running conversation to join, and it had to create a new conversation, it stores a <code>conversationBegun</code> flag of <code>true</code>.</p>
<p>Then you hit the login page, where the page (or code) would <code>Begin</code> a long running conversation, except you almost certainly have <code>join=true</code>, so it joins the existing long running conversation, which was created by the <code>captureCurrentView</code> method.  This is the conversation your User entity was loaded up in.</p>
<p>After your login was successful, the Redirect classes <code>returnToCapturedView</code> method is called to send you back to where you&#8217;d tried to go initially.</p>
<p>This method has the following block:</p>
<pre lang="java">
if (conversationBegun) {
       Conversation.instance().end();
}
</pre>
<p>This ends the conversation you had loaded your User entity within, and when you hit your destination page, there is no long running conversation at all.  Then, a few minutes later, it&#8217;s lazy loading exception time.</p>
<p>The downside is there isn&#8217;t a really clean fix that I am aware of  yet.</p>
<p>The upside is there is a pretty simple hack: just add a <code>&lt;begin-conversation join="true" /&gt;</code> to all of your pages which have the <code>login-required="true"</code> attribute.  This creates a new long running conversation before the Redirect does it&#8217;s work, so it in turn joins that conversation instead of creating a new one, the <code>conversationBegun</code> flag is false, and the <code>returnToCapturedView</code> method doesn&#8217;t end your conversation.  It&#8217;s a hack, and you have to remember to add it to every page which requires a logged in state, but it does work.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/java/jboss/seam/login-requiredtrue-will-end-your-conversation.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Don&#8217;t like people leeching your wireless?</title>
		<link>http://www.digitalsanctuary.com/tech-blog/security/dont-like-people-leeching-your-wireless.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/security/dont-like-people-leeching-your-wireless.html#comments</comments>
		<pubDate>Sat, 01 Dec 2007 06:00:01 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/security/dont-like-people-leeching-your-wireless.html</guid>
		<description><![CDATA[Don&#8217;t just block them, get a little more creative&#8230;. http://www.ex-parrot.com/~pete/upside-down-ternet.html Enjoy:)]]></description>
			<content:encoded><![CDATA[<p>Don&#8217;t just block them, get a little more creative&#8230;.</p>
<p><a href="http://www.ex-parrot.com/~pete/upside-down-ternet.html" target="_new">http://www.ex-parrot.com/~pete/upside-down-ternet.html</a></p>
<p>Enjoy:)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/security/dont-like-people-leeching-your-wireless.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Database Caching 1/55 queries in 0.013 seconds using disk: basic
Object Caching 772/916 objects using disk: basic

Served from: www.digitalsanctuary.com @ 2012-02-07 00:08:58 -->
