<?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>The Forgettable Mister Ruthsarian &#187; Uncategorized</title>
	<atom:link href="http://weblog.bridgew.edu/ruthsarian/category/uncategorized/feed/" rel="self" type="application/rss+xml" />
	<link>http://weblog.bridgew.edu/ruthsarian</link>
	<description>All manner of web development issues discussed, but with a heavy focus on CSS.</description>
	<lastBuildDate>Mon, 26 Oct 2009 20:13:54 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Washing Client Certs in ColdFusion with SOAP &#8211; Part 3</title>
		<link>http://weblog.bridgew.edu/ruthsarian/2009/10/26/washing-client-certs-in-coldfusion-with-soap-part-3/</link>
		<comments>http://weblog.bridgew.edu/ruthsarian/2009/10/26/washing-client-certs-in-coldfusion-with-soap-part-3/#comments</comments>
		<pubDate>Mon, 26 Oct 2009 20:13:54 +0000</pubDate>
		<dc:creator>Ruthsarian</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://weblog.bridgew.edu/ruthsarian/?p=267</guid>
		<description><![CDATA[Continuing from part 2, I&#8217;ve got my SOAP request working, but the solution is limited to the OS platform and I don&#8217;t like the security implications. What I would really like is a solution that works without the need of a custom tag that is OS dependent. If only CFHTTP wasn&#8217;t broken.
I decided to look [...]]]></description>
			<content:encoded><![CDATA[<p>Continuing from <a href="http://weblog.bridgew.edu/ruthsarian/2009/10/26/washing-client-certs-in-coldfusion-with-soap-part-2/">part 2</a>, I&#8217;ve got my SOAP request working, but the solution is limited to the OS platform and I don&#8217;t like the security implications. What I would really like is a solution that works without the need of a custom tag that is OS dependent. If only <strong>CFHTTP</strong> wasn&#8217;t broken.</p>
<p>I decided to look at what I already had available; namely Java. ColdFusion runs on top of Java and it&#8217;s possible to create Java objects from within ColdFusion.</p>
<p>I&#8217;ll spare you the grueling details, but I did get caught up at one point playing around with the Java keystore and importing my client certificate into that keystore. Using things like keytool and OpenSSL I tore apart and reconstructed my client certificate and my Java keystore. Ultimately I didn&#8217;t need to do any of that and should have just left the keystore alone.</p>
<p>The path to enlightenment began when I found an example of Java socket operations using  the <em>javax.net.ssl.SSLContext</em> object. The example code I was looking at used this object to create regular sockets, not SSL-enabled sockets. I looked into this object and found a few more examples using it to create SSL connections. A bit of back and forth between these examples and the <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/net/ssl/SSLContext.html">online Java API spec</a> resulted in the discovery that I could load a PKCS12 file as a keystore and pass that to the SSLContext object then create sockets from that SSLContext. This looked promising.</p>
<p>After a bit of trial and error I finally had something that worked!</p>
<p>Here&#8217;s the relevant portion of code. I&#8217;ll go line-by-line afterwards.</p>
<pre>&lt;cfscript&gt;
  // 01: create input file stream from certificate
  variables.ksf = CreateObject( "java", "java.io.FileInputStream" ).init( variables.cert_file );

  // 02: create keystore object from certificate
  variables.ks = CreateObject( "java", "java.security.KeyStore" ).getInstance( "PKCS12" );
  variables.ks.load( variables.ksf, JavaCast( "String", variables.cert_password ).toCharArray() );

  // 03: create key manager factory out of keystore
  variables.kmf = CreateObject( "java", "javax.net.ssl.KeyManagerFactory" ).getInstance( "SunX509" );
  variables.kmf.init( variables.ks, JavaCast( "String", variables.cert_password ).toCharArray() );

  // 04: create SSL context object using key manager factory
  variables.sslc = CreateObject( "java", "javax.net.ssl.SSLContext" ).getInstance( "TLS" );
  variables.sslc.init( kmf.getKeyManagers(), JavaCast( "null", "" ), JavaCast( "null", "" ) );

  // 05: get SSL socket from SSL context
  variables.factory = sslc.getSocketFactory();

  // 06: connect to the server via SSL
  variables.sock = variables.factory.createSocket( variables.server_address, variables.server_port);
  variables.sock.startHandshake();

  // 07: create input and output streams to read from and write to the socket
  variables.sout = variables.sock.getOutputStream();
  variables.out = createObject( "java", "java.io.PrintWriter" ).init( variables.sout );
  variables.sinput = variables.sock.getInputStream();
  variables.inputStreamReader = createObject( "java", "java.io.InputStreamReader" ).init( variables.sinput );
  variables.input = createObject( "java", "java.io.BufferedReader" ).init( variables.InputStreamReader );

  // 08: send the HTTP request over the socket
  variables.out.println( Trim( variables.request_header ) );
  variables.out.println();
  variables.out.println( Trim( variables.soap_envelope ) );
  variables.out.println();
  variables.out.flush();

  // 09: read the response from the server
  variables.result = "";
  do {
    variables.line = input.readLine();
    variables.lineCheck = IsDefined( "variables.line" );
    if ( variables.lineCheck ) {
      variables.result = variables.result &amp; variables.line &amp; Chr(13) &amp; Chr(10);
    }
  } while ( variables.lineCheck );

  // 10: close the connection
  variables.sock.close();
&lt;/cfscript&gt;</pre>
<p>So let&#8217;s work through this.</p>
<p><strong>01:</strong> The variable <strong>variables.cert_file</strong> contains the full path to the client certificate. This line opens that file for reading.</p>
<p><strong>02:</strong> This creats a <em>java.security.KeyStore</em> object that expects a PKCS12 format and then loads the client certificate into the keystore. Note that the second parameter of the <strong>KeyStore.load()</strong> method is the password of the PKCS12 file. You must pass this as a character array and not as a string, which is why the password must be cast as a <em>String</em> object whose <strong>toCharArray()</strong> method is called to obtain that character array.</p>
<p><strong>03:</strong> This creates a <em>javax.net.ssl.KeyMangerFactory</em> object which is used by the SSLContext object to deal with the certificates in the keystore. Note that the second parameter of the <strong>init()</strong> is the password to the certificate in character array format. You must provide the password twice, once when creating the keystore, and then again creating the key manager factory.</p>
<p><strong>04:</strong> Here we create the <em>javax.net.ssl.SSLContext</em> object. The <strong>getInstance()</strong> call tells what protocol to use with this object, in this case &#8220;<em>TLS</em>&#8220;. (Note: &#8220;<em>SSLv3</em>&#8221; also works. No idea which one I should be using. If one fails, try the other.) Once the object is instantiated we initialize it with a key manager from the key manager factory. The second and third parameters of the <strong>init()</strong> method could point to a trust manager and a source of randomness. It doesn&#8217;t appear that either is needed (this is what I saw in other examples) so I pass null values. Note that you have to use <strong>JavaCast()</strong> to pass a null.</p>
<p><strong>05:</strong> Get a socket factory object from the SSLContext object. This factory will be used to create individual sockets using the parameters established with the SSLContext object.</p>
<p><strong>06:</strong> Create a single socket from the socket factory by passing the server address (<strong>variables.server_address</strong>) and port (<strong>variables.server_port</strong>) we want to connect to. Then call <strong>startHandshake()</strong> which will create the connection to the server using SSL.</p>
<p><strong>07:</strong> Create objects needed to read from and write to the socket we&#8217;ve created.</p>
<p><strong>08:</strong> Here we send our SOAP envelope to the server. Note that since we&#8217;re doing everything by hand we also have to send the proper HTTP headers. Both the <strong>variables.request_header</strong> and <strong>variables. soap_envelope</strong> variables were created using the <strong>CFSAVEDCONTENT</strong> tag as shown in <a href="http://weblog.bridgew.edu/ruthsarian/2009/10/26/washing-client-certs-in-coldfusion-with-soap-part-1/">part 1</a>. You want to create the envelope first so you know the correct <strong>content-length</strong> value for the HTTP header. Since I decided to stick with <em>SOAP 1.1</em> the header also contains the<strong> SOAPAction</strong> field and the <strong>content-type</strong> is set to <em>text/xml</em>.</p>
<p>Here is an example of how I created the headers:</p>
<pre>&lt;cfsavecontent variable="variables.request_header"&gt;
POST &lt;cfoutput&gt;#variables.server_request_path#&lt;/cfoutput&gt; HTTP/1.0
Host: &lt;cfoutput&gt;#variables.server_address#&lt;/cfoutput&gt;
User-Agent: SOAP Washer/1.0
SOAPAction: "&lt;cfoutput&gt;#variables.soap_action#&lt;/cfoutput&gt;"
Content-Type: text/xml
Content-Length: &lt;cfoutput&gt;#Len( Trim( variables.soap_envelope ))#&lt;/cfoutput&gt;
&lt;/cfsavecontent&gt;</pre>
<p>Standard HTTP/1.0 headers. You can make the User-Agent field just about whatever you want.</p>
<p>Also worth mentioning is that I didn&#8217;t try to combine the two (HTTP headers and envelope) into a single variable. This is because how <strong>CFSAVEDCONTENT</strong> handles newline characters is different between ColdFusion 8 and ColdFusion 9. By keeping them separate this code is able to operate under either version.</p>
<p>The empty <strong>println()</strong> commands are there to send a newline. And the <strong>flush()</strong> call simply sends anything left in the buffers, thus completing the sending of our request.</p>
<p><strong>09:</strong> This is where we read the response from the server. The response can only be read one line at a time, so we need a loop to keep reading one line at a time and appending it to the variable where we&#8217;ll store the entire response (<strong>variables.result</strong>).</p>
<p>A tricky thing working between ColdFusion and Java objects is that if you assign the return value of a Java object method to a ColdFusion variable and that return value is <em>null</em> then the ColdFusion variable is unset or deleted. Since the <strong>readLine()</strong> method returns null when there&#8217;s nothing more to read, the only way to know we&#8217;ve completed reading the response is to test if <strong>variables.line</strong>, where we store the return value of <strong>readLine()</strong>, still exists. If it doesn&#8217;t, we&#8217;ve reached the end of the response.</p>
<p><strong>10:</strong> Close the connection</p>
<p>The ColdFusion variable <strong>variables.result</strong> will contain the entire response from the server, <em>including</em> the response HTTP headers. Meaning if you want to get a proper XML object from <strong>xmlParse()</strong> you&#8217;re going to need to first strip away those headers.</p>
<pre>&lt;cfset variables.temp = REFindNoCase( "content-length: ([0-9]+)", variables.result, 1, "True" )&gt;
 &lt;cfif variables.temp.len[1] GT 0&gt;
  &lt;cfset variables.length = Val( Mid( variables.result, variables.temp.pos[2], variables.temp.len[2] ))&gt;
  &lt;cfset variables.xmlResult = Trim( Right( RTrim( variables.result ), variables.length ))&gt;
&lt;/cfif&gt;</pre>
<p>This should do the trick. Although you may want to throw in some code to strip out the status code to ensure a good transaction.</p>
<p>And there you have it. Handling transactions with a third-party web site using client certificates under ColdFusion using only native ColdFusion objects.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.bridgew.edu/ruthsarian/2009/10/26/washing-client-certs-in-coldfusion-with-soap-part-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Acrobat Open Parameters</title>
		<link>http://weblog.bridgew.edu/ruthsarian/2009/09/09/acrobat-open-parameters/</link>
		<comments>http://weblog.bridgew.edu/ruthsarian/2009/09/09/acrobat-open-parameters/#comments</comments>
		<pubDate>Wed, 09 Sep 2009 16:38:44 +0000</pubDate>
		<dc:creator>Ruthsarian</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://weblog.bridgew.edu/ruthsarian/?p=252</guid>
		<description><![CDATA[Recently I was tasked with updating the college catalog. Not the content, that was already generated for us and delivered in PDF format by the publisher. I needed to update the web site and the links into the PDFs. Most of the links went to just the PDF itself, but a few pointed to named [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I was tasked with updating the <a href="http://www.bridgew.edu/catalog/">college catalog</a>. Not the content, that was already generated for us and delivered in PDF format by the publisher. I needed to update the web site and the links into the PDFs. Most of the links went to just the PDF itself, but a few pointed to named destinations inside the PDF. These bookmarks don&#8217;t exist in the documents we receive from the publisher &#8212; we have to create them ourselves.</p>
<p>But I don&#8217;t have Acrobat Pro installed on my computer. If the college orders me a copy today we&#8217;ll probably have the install DVD  next week, but I don&#8217;t want to wait that long.</p>
<p>So what options are at my disposal? Is it possible to link to a specific location inside a PDF without having to create bookmarks inside the PDF?</p>
<p>After scouring the interwebs a bit I find <a href="http://partners.adobe.com/public/developer/en/acrobat/PDFOpenParameters.pdf">this document on Acrobat Open Parameters</a>.</p>
<p>I can link to a specific page by simply appending to the PDF&#8217;s url <code>#page=2</code> and, magically, Acrobat Reader will load the PDF starting on page 2.</p>
<p>Cool.</p>
<p>But some of the items I&#8217;m linking to inside the PDF start halfway down the page. A user clicking on the link might not see the section they&#8217;re being linked to within the top area of the page that is visible on their screen and immediately assume they&#8217;ve clicked on the wrong thing.</p>
<p>So can we do something more with these URL parameters?</p>
<p>Yes!</p>
<p>The <code>VIEW</code> parameter allows you to define how the PDF is scaled in the browser (fit to window, fit horizontally to window, fit vertically to window, etc.) as well as where on the page to start based on a x,y coordinate system.</p>
<p>In this case I want to set <code>VIEW</code> to <code>FitH</code> (Fit Horizontally) meaning the PDF will size itself so the width of the document is the same as the width of the browser&#8217;s viewport. This also allows us to specify a Y component as to the position of the page displayed when the PDF is loaded. Combine this with the <code>PAGE</code> parameter and you can define where in a given page the PDF will start when loaded.</p>
<p>So a link like <code>document.pdf?page=7&amp;view=FitH,300</code> will load the PDF on page 3 at 300 units down the page.</p>
<p>Now what unit are we talking about? And is 300 units on my screen the same as 300 units on someone else&#8217;s screen? I have no idea. The document is light on details, but I believe the coordinate system is based on the parameters of the PDF itself and not the end-user&#8217;s screen. So with a little bit of trial-and-error I find just the right number to use with the FitH view and voilà!</p>
<p>I can now link to the <a href="http://www.bridgew.edu/catalog/seced.pdf#page=4&amp;view=FitH,500">Masters of Arts in Teaching</a> program within the Secondary Education section of the catalog. And I did it without having to pay for some bloated Adobe software.</p>
<p>Granted, with named destinations updating the catalog next year wouldn&#8217;t require that I touch those links (just the PDFs we get from the publisher) and maybe it&#8217;s better from a semantics standpoint, but this was quick and easy.</p>
<p>Will it work with PDF readers other than Acrobat? I don&#8217;t know. If you&#8217;ve got one installed try it out and let me know. The fact that these &#8220;open parameters&#8221; have been around since at least Acrobat 6 it&#8217;s possible other PDF viewers have incorporated this feature into their application.</p>
<p>But, hey, it works with the most popular and free PDF reader and it didn&#8217;t require expensive software to accomplish. That&#8217;s good enough for me.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.bridgew.edu/ruthsarian/2009/09/09/acrobat-open-parameters/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Password Masking</title>
		<link>http://weblog.bridgew.edu/ruthsarian/2009/08/19/password-masking/</link>
		<comments>http://weblog.bridgew.edu/ruthsarian/2009/08/19/password-masking/#comments</comments>
		<pubDate>Wed, 19 Aug 2009 15:39:59 +0000</pubDate>
		<dc:creator>Ruthsarian</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[css password masking]]></category>

		<guid isPermaLink="false">http://weblog.bridgew.edu/ruthsarian/?p=250</guid>
		<description><![CDATA[I&#8217;ve written up a little page on password masking to read at your convenience.
This was born out of an article written by Jakob Nielsen titled &#8220;Stop Password Masking&#8220;. In it he argues that masking passwords does little to really prevent password theft, but does quite a lot of harm in the form of user errors [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve written up a little page on <a href="http://webhost.bridgew.edu/etribou/layouts/exp/password_masking.htm">password masking</a> to read at your convenience.</p>
<p>This was born out of an article written by Jakob Nielsen titled &#8220;<a href="http://www.useit.com/alertbox/passwords.html">Stop Password Masking</a>&#8220;. In it he argues that masking passwords does little to really prevent password theft, but does quite a lot of harm in the form of user errors as they are unable to tell if they&#8217;ve made a mistake in typing their password. Security pro <a href="http://www.schneier.com/blog/archives/2009/06/the_problem_wit_2.html">Bruce Schneier weighed in</a> as well, initially agreeing with Nielsen, then <a href="http://www.schneier.com/blog/archives/2009/07/the_pros_and_co.html">rethinking his ideas a bit</a>.</p>
<p>I decided to see what we, on the web side of things, might be able to do to make it a little easier on users, but still stay secure.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.bridgew.edu/ruthsarian/2009/08/19/password-masking/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New Gargoyles Comic</title>
		<link>http://weblog.bridgew.edu/ruthsarian/2009/08/14/new-gargoyles-comic-2/</link>
		<comments>http://weblog.bridgew.edu/ruthsarian/2009/08/14/new-gargoyles-comic-2/#comments</comments>
		<pubDate>Fri, 14 Aug 2009 15:56:54 +0000</pubDate>
		<dc:creator>Ruthsarian</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://weblog.bridgew.edu/ruthsarian/?p=248</guid>
		<description><![CDATA[A shameless plug for Gargoyles: Clan Building Vol. 2, which contains issues 6-12 of the Gargoyles comic. The comic is written by series co-creator Greg Weisman and it continues where the TV series left off after season two. It&#8217;s an awesome book. Very rich. Very dense. This is not just for kids, it appeals to [...]]]></description>
			<content:encoded><![CDATA[<p>A shameless plug for <a href="http://www.slgcomic.com/Gargoyles-Clan-Building-Volume-Two_p_1249.html">Gargoyles: Clan Building Vol. 2</a>, which contains issues 6-12 of the <a href="http://en.wikipedia.org/wiki/Gargoyles_%28SLG_comic%29">Gargoyles comic</a>. The comic is written by series co-creator Greg Weisman and it continues where the TV series left off after season two. It&#8217;s an awesome book. Very rich. Very dense. This is not just for kids, it appeals to adults as well. It&#8217;s well worth your time to check it out.</p>
<p>Sadly this will probably be the last Gargoyles story told in an official capacity. The book&#8217;s publisher, SLG, were not able to renew their license with Disney after Disney increased the license fee on Gargoyles. Some rumors are afoot that say if the book sells really well then SLG might decide to take a chance at renewing the license (and risk considerable money if the book doesn&#8217;t sell).</p>
<p>But I&#8217;ve got a feeling this is going the way of the DVDs, which ended after the first half of season 2 was released 4 years ago and fans were left without the second (and concluding!) half of season 2.</p>
<p>Although it seems Disney is quite good at screwing up quality products other than Gargoyles. For example they&#8217;ve <a href="http://www.animationmagazine.net/article/10429">yet to green-light</a> a third season of <a href="http://en.wikipedia.org/wiki/The_Spectacular_Spider-Man_%28TV_series%29">Spectacular Spider-Man</a>. A complete no-brainer and also a show produced by Greg Weisman. Makes me wonder if there&#8217;s some sort of bad relationship between Weisman and Disney.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.bridgew.edu/ruthsarian/2009/08/14/new-gargoyles-comic-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wordpress Exploit &#8211; PHP Programming</title>
		<link>http://weblog.bridgew.edu/ruthsarian/2009/08/11/wordpress-exploit-php-programming/</link>
		<comments>http://weblog.bridgew.edu/ruthsarian/2009/08/11/wordpress-exploit-php-programming/#comments</comments>
		<pubDate>Tue, 11 Aug 2009 15:03:58 +0000</pubDate>
		<dc:creator>Ruthsarian</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://weblog.bridgew.edu/ruthsarian/?p=244</guid>
		<description><![CDATA[A recent exploit was discovered for all versions of Wordpress prior to and including 2.8.3. The vulnerability is in how variables are checked while processing a password reset request. The offending code is quite simple and by itself looks very innocent:
if ( empty( $key ) )
If the $key variable is empty, an error is generated. [...]]]></description>
			<content:encoded><![CDATA[<p>A recent <a href="http://www.milw0rm.com/exploits/9410">exploit</a> was discovered for all versions of Wordpress prior to and including 2.8.3. The vulnerability is in how variables are checked while processing a password reset request. The offending code is quite simple and by itself looks very innocent:</p>
<p><code>if ( empty( $key ) )</code></p>
<p>If the $key variable is empty, an error is generated. If $key is not empty it&#8217;s passed to a SQL query that looks up the user whose key is being reset. Seems innocent enough, right?</p>
<p>The variable $key is a sanitized copy of $_GET['key']. And what happens if the value passed on the url for key is an array?</p>
<p>Well the sanitization step is a simple preg_replace, like so:</p>
<p><code>$key = preg_replace('/[^a-z0-9]/i', '', $key);</code></p>
<p>The <a href="http://us3.php.net/preg_replace">PHP documentation</a> states that if the subject ($key) is an array, the return value will be an array as well. It also states that if no matches are found, the original subject is returned. Since $key is empty to begin with, thus no matches will be found, a copy of $key is returned. Essentially $key remains unchanged. So what happens when you pass an empty array to PHP&#8217;s empty() function? Well the <a href="http://us3.php.net/manual/en/function.empty.php">documentation</a> says it should return FALSE. So what&#8217;s the problem?</p>
<p>The problem is the array isn&#8217;t really empty. It contains a single node which contains an empty string. So the empty() call returns FALSE, thus no error is generated for an empty $key.</p>
<p>Surely the SQL check will return no entries since there is no key to search for, right?</p>
<p>Wrong. Here&#8217;s the code:</p>
<p><code>$user = $wpdb-&gt;get_row($wpdb-&gt;prepare("SELECT * FROM $wpdb-&gt;users WHERE user_activation_key = %s", $key));</code></p>
<p>The $wpdb-&gt;prepare()  is used to insert values into SQL statements. $key is treated like an empty string. Therefore the SQL that is generated looks like:</p>
<p><code>SELECT * FROM wp_users WHERE user_activation_key = ''</code></p>
<p>And that query will return every user who has an empty activation key &#8212; that&#8217;s everyone not currently trying to reset their password. Since the first row returned is the record that gets reset, you will almost always be resetting the admin account. If you keep making the same request over and over you will eventually wind up resetting the password of every user in the system!</p>
<p>Reset passwords are auto-generated and then e-mailed out to the users. This sort of attack could be used as a weak style of denial-of-service (or pain-in-the-ass attack as I prefer to call it) or an attacker who has access to a victim&#8217;s e-mail account (or can packet sniff their e-mail downloading)  could take control of the blog.</p>
<p>A fix is already on the way as you can see by viewing <a href="http://core.trac.wordpress.org/browser/trunk/wp-login.php">wp-login.php in Wordpress&#8217; CVS</a>. The fix seems simple enough:</p>
<p><code>if ( empty( $key ) || !is_string( $key ) )</code></p>
<p>So $key must be a string and it must be empty. Seems very straightforward. Although I would prefer they went the added step of simply modifying the SQL query to check against only those user_activation_code fields that are not empty strings. In other words add something like</p>
<p><code>$user = $wpdb-&gt;get_row($wpdb-&gt;prepare("SELECT * FROM $wpdb-&gt;users WHERE user_activation_key = %s AND user_activaction_key &lt;&gt; ''", $key));</code></p>
<p>That would more correctly fix the issue, as it would protect against even those attacks that are somehow able to bypass the initial empty() check.</p>
<p>Wordpress appears to also be adding a username to the password reset request so that simply passing an empty key on the URL and hitting reload a bunch of times won&#8217;t result in everyone having their password reset &#8212; probably something they should have done in the first place.</p>
<p>So there it is. Patch your Wordpresses, either by manually editing wp-login.php or waiting for the official patch to come out sometime later this week.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.bridgew.edu/ruthsarian/2009/08/11/wordpress-exploit-php-programming/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Contuing To Prove My Now 5+ Year Old Argument</title>
		<link>http://weblog.bridgew.edu/ruthsarian/2009/07/28/contuing-to-prove-my-now-5-year-old-argument/</link>
		<comments>http://weblog.bridgew.edu/ruthsarian/2009/07/28/contuing-to-prove-my-now-5-year-old-argument/#comments</comments>
		<pubDate>Tue, 28 Jul 2009 16:06:14 +0000</pubDate>
		<dc:creator>Ruthsarian</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://weblog.bridgew.edu/ruthsarian/?p=242</guid>
		<description><![CDATA[Flash (and JavaScript) should be used as tools to enhance an existing web site, not replace it. If your web site is not accessible to a user who has neither Flash or JavaScript support then you are doing something very wrong.
It appears that there is a new Flash vulnerability that can take over your computer. [...]]]></description>
			<content:encoded><![CDATA[<p>Flash (and JavaScript) should be used as tools to enhance an existing web site, not replace it. If your web site is not accessible to a user who has neither Flash or JavaScript support then you are doing something very wrong.</p>
<p>It appears that there is a <a href="http://it.slashdot.org/story/09/07/28/1412255/92-of-Windows-PCs-Vulnerable-To-Zero-Day-Attacks-On-Flash">new Flash vulnerability</a> that can take over your computer. Awesome.</p>
<p>So how does one protect themselves from such a thing? Well, you could install <a href="http://noscript.net/">noscript</a>. It&#8217;s a plugin that will disable JavaScript, Flash and other embedded objects from web sites until you explicitly set permissions to enable them for that web site. Noscript won&#8217;t save you from web sites that you&#8217;ve already set permissions for &#8212; so it&#8217;s not a catch-all, but it will save you from links to web sites you&#8217;re unsure about. And it has the nice side-effect of disabling any JavaScript-powered advertisements.</p>
<p>What this means for you, the web developer, is that it&#8217;s time to start assuming the first time people access your web site they will have Flash, JavaScript, etc. disabled. This means you need to make sure your site is still accessible even under those conditions. Otherwise the user will have no reason to trust your web site if he or she can&#8217;t access it in the first place. If they don&#8217;t trust it they&#8217;ll never (well, they SHOULD never) enable script and emedded objects to run from your domain. Thus you will lose customers.</p>
<p>HTML, CSS and text. That should be the core of every web site. Flash and embedded objects to enhance the site, but not to provide the only means to access your content.</p>
<p>That is unless you&#8217;re one of a few embedded object kind of web site, like YouTube. But for the majority of us, that won&#8217;t be the case. And even so, you can always provide download links to the videos if the user doesn&#8217;t have Flash enabled to view them from within your web page.</p>
<p>&lt;strong&gt;TL;DR: Web sites should be accessible even without JavaScript and Flash.&lt;/strong&gt;</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.bridgew.edu/ruthsarian/2009/07/28/contuing-to-prove-my-now-5-year-old-argument/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Inkscape</title>
		<link>http://weblog.bridgew.edu/ruthsarian/2009/02/23/inkscape/</link>
		<comments>http://weblog.bridgew.edu/ruthsarian/2009/02/23/inkscape/#comments</comments>
		<pubDate>Mon, 23 Feb 2009 19:23:35 +0000</pubDate>
		<dc:creator>Ruthsarian</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://weblog.bridgew.edu/ruthsarian/?p=238</guid>
		<description><![CDATA[Right now work has me creating some maps to put on the web based of scanned drawings from the contractor behind a bunch of on-campus construction. In the past I would use Adobe Illustrator to do this by importing the maps and then tracing over it with vector lines. This process is relatively quick and [...]]]></description>
			<content:encoded><![CDATA[<p>Right now work has me creating some maps to put on the web based of scanned drawings from the contractor behind a bunch of on-campus construction. In the past I would use Adobe Illustrator to do this by importing the maps and then tracing over it with vector lines. This process is relatively quick and easy. I can use grids to control the initial lines and keep them straight. I can then go in and manipulate points (or add more as needed) along the lines to fine tune things.</p>
<p>Well I don&#8217;t have Illustrator installed and the only version the office has is old and, from my experience, not very responsive. So I set out to find a <em>free</em> alternative. Enter <a href="http://www.inkscape.org/">Inkscape</a>. Inkscape is a free, open source vector graphics program that you can use on Windows, Mac, and Linux platforms (and is probably portable to others should you be into that sort of thing).</p>
<p>I&#8217;ve been using it for just the day and I&#8217;m already in love. The controls are intuitive. There&#8217;s a ton of power in just the mouse commands. I hardly need to touch the keyboard for anything (hiding and unhiding the guides I&#8217;ve created). Working with layers may feel a bit odd; it&#8217;s nothing like Photoshop or Gimp in terms of the UI. But after a few hours I find myself right at home.</p>
<p>It&#8217;s native format is SVG, which open standards people will love. But if that&#8217;s not your thing you can save is most major vector graphic formats (eps, pdf, etc). You can also export the work as a bitmap and tweak it as needed in your favorite graphics editor.</p>
<p>This is a great application. I suggest you give it a try if you&#8217;re ever in the market for a vector graphics format.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.bridgew.edu/ruthsarian/2009/02/23/inkscape/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Still Kicking</title>
		<link>http://weblog.bridgew.edu/ruthsarian/2009/02/06/still-kicking/</link>
		<comments>http://weblog.bridgew.edu/ruthsarian/2009/02/06/still-kicking/#comments</comments>
		<pubDate>Fri, 06 Feb 2009 15:08:11 +0000</pubDate>
		<dc:creator>Ruthsarian</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Web Design]]></category>

		<guid isPermaLink="false">http://weblog.bridgew.edu/ruthsarian/?p=235</guid>
		<description><![CDATA[Just checking in to let everyone know I&#8217;m still around.
Working on a new layout that I&#8217;m going to use as a new WP layout for this blog. I&#8217;d originally intended it to be a separate, new layout, but now I think I&#8217;ll publish it was a WP layout instead. After it&#8217;s been up here for [...]]]></description>
			<content:encoded><![CDATA[<p>Just checking in to let everyone know I&#8217;m still around.</p>
<p>Working on a new layout that I&#8217;m going to use as a new WP layout for this blog. I&#8217;d originally intended it to be a separate, new layout, but now I think I&#8217;ll publish it was a WP layout instead. After it&#8217;s been up here for a bit and the bugs ironed out. Hope to install the first version of this template in the next week or two.</p>
<p>Here&#8217;s a little tip for web designers. Sometimes I&#8217;ll find myself wanting to produce &#8220;previous&#8221; and &#8220;next&#8221; links to appear at the bottom of a web page used to manage some kind of database-driven content. The links would obviously point to the previous and next records in the database.</p>
<p>To style this I sometimes prefer to have the links centered on the page with a bit of a gap between the two links. Why centered and not at the far left and right edges? I don&#8217;t know. Visual preference that fits better with the layout and style perhaps, but I tend to operate more on gut feeling with a layout.</p>
<p>Now in the past I&#8217;d simply make a paragraph tag with <code>text-align:center</code> set and then a bunch of &amp;nbsp; characters to add some space. Now if the text should ever wrap because the viewport is too small then the effect breaks horribly. Also, the text would center based on the center of all the text, and would NOT center on the gap between the two links. The illusion breaks very quickly if these previous/next links include a variable width bit of text like, say, the title of the previous/next record. The position of the gap starts moving from record to record. Ick.</p>
<p style="text-align:center;border:solid 1px #999;padding:1em">« Previous             Next »</p>
<p>So here&#8217;s a new way to do this. Simply create two paragraphs. Float them to either side. Set a width of, say, 40% for each. Right-align the left-float and left-align the right float. Now you&#8217;ve got a gap (20% the page width in this case) between the two links, they&#8217;re centered to the page based on the gap, the gap&#8217;s location won&#8217;t change from page to page, and if the text wraps the visual structure is retained.</p>
<div style="margin:1em 0;border:solid 1px #999;padding:1px 1em">
<p style="float: left;width: 40%;text-align: right">« Previous</p>
<p style="float: right;width: 40%;text-align: left">Next »</p>
<div style="padding-bottom:1px" class="clear"></div>
</div>
<p>Now there&#8217;s no great reveal here, is there? It&#8217;s a pretty basic and simple trick. But I find my mind will sometimes approach a problem from a direction that makes it difficult to see the obvious. So I like to see these simple tips from time to time, because once in a while it&#8217;ll be a trick I&#8217;d never considered before.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.bridgew.edu/ruthsarian/2009/02/06/still-kicking/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Check. One. Two.</title>
		<link>http://weblog.bridgew.edu/ruthsarian/2008/12/12/check-one-two/</link>
		<comments>http://weblog.bridgew.edu/ruthsarian/2008/12/12/check-one-two/#comments</comments>
		<pubDate>Fri, 12 Dec 2008 15:45:42 +0000</pubDate>
		<dc:creator>Ruthsarian</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://weblog.bridgew.edu/ruthsarian/?p=233</guid>
		<description><![CDATA[Right, so here we are. A new server running Wordpress. I&#8217;ve imported all the old posts, but any links to old posts are going to be a bit broken now. So be it. I&#8217;ll have to develop a theme for this place. I&#8217;ve got a new layout that I think will work, I just need [...]]]></description>
			<content:encoded><![CDATA[<p>Right, so here we are. A new server running Wordpress. I&#8217;ve imported all the old posts, but any links to old posts are going to be a bit broken now. So be it. I&#8217;ll have to develop a theme for this place. I&#8217;ve got a new layout that I think will work, I just need to move it to Wordpress. We&#8217;ll see how that goes.</p>
<p>For now, please forgive any errors or problems you might encounter. This server is a bit fresh and may need a bit of time to ripen into delicious fruit. Pineapple!</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.bridgew.edu/ruthsarian/2008/12/12/check-one-two/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Ping</title>
		<link>http://weblog.bridgew.edu/ruthsarian/2008/12/02/ping/</link>
		<comments>http://weblog.bridgew.edu/ruthsarian/2008/12/02/ping/#comments</comments>
		<pubDate>Tue, 02 Dec 2008 15:05:32 +0000</pubDate>
		<dc:creator>Ruthsarian</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://weblog.bridgew.edu/ruthsarian/2008/12/02/ping/</guid>
		<description><![CDATA[
]]></description>
			<content:encoded><![CDATA[<p>Still here.</p>
<p>In the coming days (this month at least) we&#8217;ll be switching blog servers and software here. The URL should stay the same, but this site will be moving to a new physical box and to Wordpress.</p>
<p>I&#8217;ve played with Wordpress enough to see that it should have no problems importing old entries from this old version of MT we&#8217;re using now. Don&#8217;t know how this will affect RSS/ATOM feeds (for the few that use them).</p>
<p>So, heads up guys!</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.bridgew.edu/ruthsarian/2008/12/02/ping/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
