grack.com

Blog

Javascript primitive conversion quick-reference

Javascript has three primitive types: number, string and boolean. You can quickly coerce values between the primitive types using some simple expressions.

There are a few different coersion expressions, depending on how you want to handle some of the corner cases.  I’ve automatically generated a list below:

Conversion: To Number To Number To Number To String To Boolean To Boolean
Expression: +x (+x)||0 +(x||0) ""+x !!x !!+x
null 0 0 0 "null" false false
(void 0) NaN 0 0 "undefined" false false
NaN NaN 0 0 "NaN" false false
Infinity Infinity Infinity Infinity "Infinity" true true
-Infinity -Infinity -Infinity -Infinity "-Infinity" true true
0 0 0 0 "0" false false
"0" 0 0 0 "0" true false
1 1 1 1 "1" true true
"1" 1 1 1 "1" true true
2 2 2 2 "2" true true
"2" 2 2 2 "2" true true
[] 0 0 0 "" true false
({}) NaN 0 NaN "[object Object]" true false
true 1 1 1 "true" true true
"true" NaN 0 NaN "true" true false
false 0 0 0 "false" false false
"false" NaN 0 NaN "false" true false
"" 0 0 0 "" false false
"null" NaN 0 NaN "null" true false

The above table was generated with this code (note: uses some Firefox-specific code).

<table id="results" style="border-collapse: collapse; border: 1px solid black;">
 <tr id="header">
 <th>Conversion:</th>
 </tr>
 <tr id="header2">
 <th>Expression:</th>
 </tr>
</table>

<script>
function styleCell(cell) {
 cell.style.border = '1px solid black';
 cell.style.padding = '0.2em';
 return cell;
}

values = [
null, undefined, NaN, +Infinity, -Infinity, 0, "0", 1, "1", 2, "2",
   [], {}, true, "true", false, "false", "", "null"
]

coersions = [
["To Number", "+x"],
 ["To Number", "(+x)||0"],
 ["To Number", "+(x||0)"],
 ["To String", "\"\"+x"],
 ["To Boolean", "!!x"],
 ["To Boolean", "!!+x"]
]

var results = document.getElementById('results');
var trHeader = document.getElementById('header');
var trHeader2 = document.getElementById('header2');

for (var i = 0; i < coersions.length; i++) {
 var th = trHeader.appendChild(styleCell(document.createElement('th')));
 th.textContent = coersions[i][0]
 th = trHeader2.appendChild(styleCell(document.createElement('th')));
 th.textContent = coersions[i][1]
}

for (var i = 0; i < values.length; i++) {
 var tr = results.appendChild(document.createElement('tr'));
 var rowHeader = tr.appendChild(styleCell(document.createElement('th')));
 rowHeader.textContent = uneval(values[i]);

 for (var j = 0; j < coersions.length; j++) {
 var td = tr.appendChild(styleCell(document.createElement('td')));
 td.textContent = uneval(eval("(function(x) { return "+coersions[j][1]+"})")(values[i]));
 }
}

</script>

Time for Atom to Put RSS Out to Pasture?

Is it time to the world to move on from RSS and to its successor, Atom? Some considerations:

Atom has an IETF standard for syndication. Atom has an IETF standard for publication. Atom was designed for modularity. Atom supports rich, well-defined activities within feeds.

RSS is effectively frozen at 2.0:

RSS is by no means a perfect format, but it is very popular and widely supported. Having a settled spec is something RSS has needed for a long time. The purpose of this work is to help it become a unchanging thing, to foster growth in the market that is developing around it, and to clear the path for innovation in new syndication formats. Therefore, the RSS spec is, for all practical purposes, frozen at version 2.0.1. We anticipate possible 2.0.2 or 2.0.3 versions, etc. only for the purpose of clarifying the specification, not for adding new features to the format. Subsequent work should happen in modules, using namespaces, and in completely new syndication formats, with new names.

It is full of legacy tags and archaic design decisions:

The purpose of the <textInput> element is something of a mystery. You can use it to specify a search engine box. Or to allow a reader to provide feedback. Most aggregators ignore it.

We are spending all this time duplicating effort. Every feed reader needs to deal with Atom and RSS. Every blog provides an Atom feed and an RSS feed. Users trying to subscribe to blog feeds are presented with an unnecessary choice.

RSS solved a need at the time, even though it was crufty and difficult to use and difficult to parse (remember when RSS XML didn’t have to be well-formed XML?). It served as an inspiration for millions of sites to open up their content to new methods of reading. It inspired a great successor, Atom, which has surpassed it many times over.

We dropped gopher when its time ran out. It’s time to make Atom the primary format for blogs.

Real-time Search and Frnégtttrdre

Robert Scoble’s accidental tweet (“Frnégtttrdre”) earlier tonite caused a minor ripple: people wondering if he was announcing a secret project, under the influence of alcohol or wandering around with an unlocked iPhone in his back pocket.

It also makes for an interesting test for real-time search.

An hour after his tweet:

Anyone else I’ve missed?

Conclusions: If you tweet a random word, there’s no guarantee that you’ll get indexed right away.  Additionally, not every service tests unicode querystring parameters.

Serious rssCloud Protocol DDoS Vulnerability

UPDATE: There’s a new domain parameter in rssCloud that makes this DDoS far, far worse.  Since there’s no verification (yet) on rssCloud endpoints, you can now subscribe any server to any rssCloud hub’s notifications.

While researching some of the issues of rssCloud running in a shared hosting environment, I came across a serious vulnerability in the protocol. The vulnerability allows someone to cripple a shared web host. Because of the sensitive nature of this vulnerability, I’m not going to share example code or which shared host(s) are vulnerable.  The fix is easy: follow these security recommendations to close the hole.

The inspiration for this vulnerability was discovered by Nick Lothian’s post on FriendFeed. It turns out that many shared hosting providers route incoming and outgoing HTTP requests through different IP addresses. The process of routing the HTTP requests is usually done transparently by a networking gear outside of the web servers themselves.

rssCloud’s specification infers the endpoint from the REMOTE_ADDR CGI variable at the time of the subscription. It would be very difficult to get an rssCloud subscriber working in a shared hosting environment because every subscription request you make goes out on IP address A, but all of your incoming requests come in via port 80 on IP address B. For some shared web providers, the machines that make outgoing requests are also web servers, serving banner messages or redirects to sales sites. Because they are web servers, they are considered valid rssCloud REST endpoints (returning 200 OK for POST requests on some URLs).

When you put these pieces together, it becomes readily apparent that you can now subscribe your shared host’s outgoing HTTP request IP address to any number of feeds. Considering that Wordpress has 7.5 million blogs that speak rssCloud, there’s a significant number of blogs that could end up pinging the machine.

There are probably a number of other interesting vulnerabilities in this area, such as traffic that travels through a proxy, or an anonymizing service such as TOR. It may be possible to knock one of these offline by subscribing it to a large number of feeds.

The problem with rssCloud is that its subscription request only proves that you can make requests via the given IP address, not that the given IP address is willing to receive them. By adding the challenge parameter I suggested in the previous post, you can now guarantee that the endpoint is willing to receive these requests, making it much harder to subscribe an unwilling participant in the protocol.

rssCloud Security Recommendations

Copy of an email I sent to http://tech.groups.yahoo.com/group/rss-cloud/messages:

I’ve been looking into the security of rssCloud over the last few days and a number of serious issues have come up. The ones of immediate importance have been reported and fixed, but I’d like to suggest some protocol changes to prevent rssCloud servers from DoS’ing sites or ending up DoS’ing each other.

Here are my implementor guidelines, based on the research over the last few days. These guidelines should mitigate all of the problems I’ve found so far without requiring rssCloud subscribers to make major changes to their code:

  1. An rssCloud implementation MUST validate that the Content-Type of the POST is application/x-www-form-urlencoded.
  2. All rssCloud parameters MUST be read from the body of the HTTP POST (ie: $_POST in PHP or equivalent in other languages). Parameters in the querystring must be ignored.
  3. The path parameter for the callback path MUST begin with a /.
  4. The port parameter, if specified, must be converted to an integer value before constructing the callback URL with it. Any trailing non-digit characters must cause the hub to return a 5xx error.
  5. The subscription callback and all subscription pings MUST include a “challenge” parameter (inspired by PubSubHubbub). The subscriber MUST respond with a response that contains the contents of that challenge parameter as the body of the response. No additional information may appear in the body.

I haven’t taken a look at the SOAP/XML-RPC parts of the protocol yet, but the extra framing should help make them more secure. Someone more familiar with those technologies should run those through their paces.

Feel free to contact me with any rssCloud hub implementation you might have and I’ll run my battery of tests against it.