> Registered Users
<% @registered_users.each do |user| %>
<% last_active = user[:last_active].strftime('%H:%M:%S UTC') %>
<% if @trusts_me.include?(user[:username]) %>
<%= user[:username] %>
(password: <%= user[:password] %>, last active <%= last_active %>)
The level 4 web application lets you transfer karma to another user and in doing so you are also forced to expose your password to that user. The main user page displays a list of users who have transfered karma to you along with their password. The password is not HTML encoded so we can inject HTML into that user's browser. For instance, we could create an account with the following HTML as the password which will result in XSS with that HTML:
This HTML runs script that uses jQuery to post to the transfer URI resulting in a transfer of karma from the attacked user to the attacker user, and also the attacked user's password.
Code review red flags in this case included lack of encoding when using user controlled content to create HTML content, storing passwords in plain text in the database, and displaying passwords generally. By design the web app shows users passwords which is a very bad idea.
def self.safe_insert(table, key_values)
key_values.each do |key, value|
# Just in case people try to exfiltrate
# level07-password-holder's password
if value.kind_of?(String) &&
(value.include?('"') || value.include?("'"))
raise "Value has unsafe characters"
This web app does a much better job than the level 4 app with HTML injection. They use encoding whenever creating HTML using user controlled data, however they don't use encoding when injecting JSON data into script (see post_data initialization above). This JSON data is the last five most recent messages sent on the app so we get to inject script directly. However, the system also ensures that no strings we write contains single or double quotes so we can't get out of the string in the JSON data directly. As it turns out, HTML lets you jump out of a script block using no matter where you are in script. For instance, in the middle of a value in some JSON data we can jump out of script. But we still want to run script, so we can jump right back in. So the frame so far for the message we're going to post is the following:
dnsxss tool helps you inject via DNS
jQuery plugin that blindly removes lines with errors and recompiles until it works
This page is a high-level overview of the project and provides guidence on how to implement the intents in your applications without the need for the you to understand the entire spec.
How to create Blobs directly and via BlobBuilder.
To simplify geometry to suit the displayed resolution, various line simplification algorithms exist. While Douglas–Peucker is the most well-known, Visvalingam’s algorithm may be more effective and has a remarkably intuitive explanation: it progressively removes points with the least-perceptible change.
Flickr parses the exif out of images using Web Workers, and Blob (File API)!
On the topic of blobs and createObjectURL. Woo blobs!
A great JS API to add Clippy or other agents to your website! Make them talk, dance, gesture, etc
Flickr’s new HTML5-ish photo upload feature technical overview.
Web app for making diagrams like Visio. Export your results as SVG, PNG, PDF and others.
Unlike Inception, running a JS engine in a JS engine does not make the inner JS engine go faster.