Can’t Even Order a Pizza Safely

Validate input from all sources!

What caught my eye was address information that is not pulled from a backend database:

Papa Johns - Stored Address Info

Where are you stored!?

Values are stored in the “pjCustomer” cookie, not encrypted, right there for you (or another device user) to read:

Papa Johns - Cookie Address Storage


The server does not handle tampered input well–specifically opening and closing script tags:

Papa Johns - Exception


Maybe data stored in this cookie is not validated here because it was set by the server in an earlier web page when a visitor first inputs address information. There the server does a lookup to ensure it is a real address. Once the server validates the address, it locates the closest store and proceeds through the workflow. Perhaps at this point it is assumed that pjCustomer data is safe.

Like other input sources, data stored in cookies should be checked for tampering:
CWE-472: External Control of Assumed-Immutable Web Parameter:


Disclosed (Patched): AddThis Email Sharing Button API XSS and Iframe Injection

Four days ago the AddThis Email Sharing Button API was vulnerable to cross-site scripting (XSS) and iframe injection. The PHP backend service endpoint that handles form submissions would reflect back payloads sent to one parameter in particular. The “tofriend” parameter got left behind when protections were applied to all others. Payloads sent to other parameters were effectively blocked from executing.

Because values sent to the “tofriend” parameter were embedded in an element’s attribute in the response page, it was possible to terminate this attribute prematurely with a double quote and then write your payload. A little circumvention was also needed because on the server side AddThis was checking for pairs of script tags to block. Read more about different XSS payload forms by following the link at the end of this post.

AddThis Email Sharing Button

AddThis Email Sharing Button and Form



XSS was possible with payloads of at least two different forms via the following vector when the “Request expired, please try again” page was returned from POST requests to /tellfriend.php.

  • Image tag payload supplied to the “tofriend” parameter sent to the “tellfriend.php” endpoint page via POST request. Example payload: filler”></span><IMG%20SRC%3d/%20onerror%3d”alert(String.fromCharCode(88,83,83))”></img><span%20class%3d”filler
Image Tag XSS Payload Supplied by Burp Proxy

Image Tag XSS Payload Supplied by Burp Proxy

Resulted in …

XSS Payload Executed in Firefox

XSS Payload Executed in Firefox

  • Inline style attribute payload in the “tofriend” parameter sent to the “tellfriend.php” endpoint page via POST request. This is the same form used in the Telerik CVE disclosure. Example payload: filler”></span><div STYLE=”background-image: expression(alert(‘XSS’))”></div><span class=”filler
XSS Div Style Attribute Payload

Div Style Attribute XSS Payload Supplied by Burp Proxy

Resulted in …

Internet Explorer (IE) XSS Execution

Internet Explorer (IE) XSS Execution


Iframe Injection

Iframe injection was possible via the following vector when the “Request expired, please try again” page was returned.

  • Iframe payload in the “tofriend” parameter sent to the “tellfriend.php” endpoint page via POST request. Example payload: filler”></span><iframe id=”mainframe” width=”400″ height=”200″ src=””>Iframes not supported.</iframe><span class=”filler
Iframe Injection Payload

Iframe Injection Payload Supplied by Burp Proxy

Resulted in …

Iframe Injection Execution

Iframe Injection Execution


Deploying the Payload

Each example posted here contains a payload and additional characters–what are they for? Well, the original HTML response embedded the “tofriend” parameter’s value within the “value” attribute of an input tag. So our submitted payload has extra content whose job was to terminate that value, then its containing element, then create our malicious payload within an element we create (image tag, div tag, iframe tag, etc), then finally create an opening span tag to mesh with the rest of the HTML ensuring everything flowed smoothly and the response page got rendered successfully.


Different XSS Payload Formats

Here is information on different XSS payloads that may work in different browsers. For example, the div style attribute payload worked in IE but not Firefox, etc.


Exploiting XSS Over HTTP POST

And here is information on auto-submitting forms to exploit XSS vulnerabilities over HTTP POST:


Thanks to Matt Abrams and the rest of the AddThis engineering team for quickly deploying a fix.


Disclosing CVE-2014-4958: Stored Attribute-Based Cross-Site Scripting (XSS) Vulnerability in Telerik UI for ASP.NET AJAX RadEditor Control

All versions of the popular UI for ASP.NET AJAX RadEditor Control product by Telerik may be affected by a high-risk stored attribute-based cross-site scripting (XSS) vulnerability that is assigned CVE-2014-4958 by MITRE, NVD, by OSVDB as ID 112083, and covered in the news. This WYSIWYG rich text editor is “…what Microsoft chose to use in MSDN, CodePlex, TechNet, MCMS and even as an alternative to the default editor in SharePoint.”

Telerik UI for ASP.NET AJAX RadEditor Control


Personally tested and confirmed are versions: 2014.1.403.35 (much newer) and 2009.3.1208.20 (much older) using Internet Explorer 8, version 8.0.7601.17514. However, all versions from Telerik at this time may be vulnerable and will continue to be until a patched is released. A workaround may be available.

What makes this discovery interesting are two parts:

  1. It leverages attribute-based cross-site scripting to exploit the input validation vulnerability. This achieves the malicious objective without using JavaScript script tags. Instead it uses an inline style attribute of an HTML element.
  2. The RadEditor exchanges the editor window’s mixed content containing elements, attributes, and text with the server in a double URL-encoded hexadecimal value format detailed below that is translated on the client-side dynamically by Telerik JavaScript into its unencoded form. For example, < first becomes %3C and then finally becomes %253C when the percent sign for the encoded character representation in the first processing round gets encoded again in a second round. This vulnerability is harder to detect than with a typical input vector due to this obfuscated communication protocol. Automated penetration testing tools and Web Application Firewalls (WAFs) may miss this, as might manual testers attempting to directly submit through a proxy an attribute-based exploit in its unencoded, or once-encoded form.

Let’s now look at the example payload as it needs to be submitted to the server from a proxy such as PortSwigger’s Burp Suite for this to work. Ensure that you place this payload somewhere within the parameter value used for the editor window’s contents:

%253cdiv STYLE=”background-image: expression(alert(‘XSS’))”%253e%253c%2fdiv%253e

… which is dynamically translated into the following form after client-side processing by Telerik UI JavaScript:

<div STYLE=”background-image: expression(alert(‘XSS’))”></div>

At the time of discovery the only available XSS protection on the server side was to use the RemoveScripts filter to strip out script tags, which is why attribute-based XSS is necessary here.

Carte blanche output encoding will not fix this issue, but instead may actually break the HTML that is rendered in the WYSIWYG editor window if the wrong encoding type is chosen. Troy Hunt explains the nuance of validating rich text input best by pointing out that markup is being stored in the data layer. Both data and HTML need to be handled by the same input vector here and so looking for script tags is irrelevant in this case because this problem is not that simple. Encoding everything would ensure that user input is displayed only as data and not executed as code by the web browser. However in this case some of the user-supplied content of the rich text editor needs to execute to achieve formatted text.

As an aside, double encoding is a type of attack used to bypass security controls. Double encoding may bypass Web Application Firewalls (WAFs).

Previous guidance on the general issue of XSS in the Telerik forums quietly placed the responsibility of sanitization on developers, but this is likely overlooked in most implementations. Further, the obscure nature of attribute-based XSS leveraging an HTML attribute to achieve execution instead of using the popular script tag route makes this harder to filter against. HTML sanitization involves inspection at a deeper level. Read more about HTML escaping.

Remediation: Telerik states: We have applied a patch to the editor that will be delivered with our Q3 edition of the controls that should be released towards the end of October. A blog post on the issue has been published here.

Additional credit goes to Tyler Hoyle and the rest of my team in CGI Federal’s Emerging Technologies Security Practice for their hard work. This is the original Bugtraq announcement.

Questions? Email me today: main at gsmcnamara dot com.


You Can’t Log Out of Pinterest or Instagram – Django Web Framework Security Weakness

The Django Web application framework made to help you build websites fast offers a session storage mechanism that does not allow a visitor to fully terminate their session when they log out. Though not the default storage mechanism — as is the case with Ruby on Rails — it is an option. I found that at least Pinterest and Instagram use this vulnerable option to handle sessions on their websites and I demonstrate what the issue looks like to a normal Web user in my video: and both suffer from WASC-47, OWASP Top Ten A2, and CWE-613. The situation is especially bad given the lack of SSL protecting the transport of the permanent session cookie/token between their servers and your browser.

To identify additional high-profile Django-based websites that might use the vulnerable cookie-based session storage mechanism, here is a starting point:

 Happy hacking! Contact me with questions.


The Following Information Security Counter Arguments are Invalid

After bringing attention to the inability to terminate a session in some popular open source web application frameworks, many of the counterarguments fell into the following bins:

  1. We already knew about this
    Why is it still an issue? Too few people know about it; other developers, even users need to be informed and heard from.
  2. Developers already know about this
    They don’t, or they don’t care. They’re busy, rushed, and becoming an expert in your open source project is a lower priority than using it to accomplish whatever they’re being paid to deliver. Burying or omitting shortcomings in your project’s design only delays discovering them–the later: the worse, the angrier.
  3. Additional configuration is required to fully protect against this
    These additional protections are not being deployed. They also don’t provide 100% CYA.
  4. The issue isn’t sexy
    Basic issues are still issues. Basic issues that continue to exist are just embarrassing. Focusing on sexy helps no one.

We’re getting nowhere fast with this attitude.

Separately, there’s disagreement over this issue specifically and if it’s even a vulnerability. Well, the OWASP Top Ten will remain unchanged if we can’t even agree on whether this is a feature or a weakness.


How to Verify the Rails CookieStore Session Termination Weakness

I want to try it out myself you say.

Here is a video explanation using as an example:


And here are the steps you take to verify the weakness yourself–using, as well as on other websites you suspect are using Rails’ CookieStore (such as those on this list):

  1. Install a Chrome plugin such as Edit This Cookie to make viewing and editing cookies easier.
  2. Go to a site such as (no SSL!) or one you suspect is using Rails’ CookieStore.
  3. Find a cookie whose value starts with “BAh7″. That’s a good indicator of Ruby on Rails CookieStore-based websites before version 4.0 of Rails, or those that don’t encrypt their CookieStore values. The session cookie will have a value starting with “BAh7″ then a separator of “–” then a hash digest.
  4. Open Edit This Cookie using the little icon in the top right of your browser. Find the cookie whose value starts with “BAh7″ and take note of the cookie’s name. In the case of it’s “_ksr_session”. Copy the entire cookie data (“BAh7…”).
  5. Screen Shot 2013-11-24 at 12.01.20 PM

  6. Log out of the website.
  7. Open Edit This Cookie and overwrite the session cookie’s current value (“_ksr_session” in this case) with the data you copied previously.
  8. Go to the website. You should be in again!

List of websites using Ruby on Rails’ CookieStore for session management

When bringing attention to the session termination security issue present with Ruby on Rails’ CookieStore and Django’s cookie-based session storage mechanism, one of the common questions I get is “Who is using it?”

Well, I did some digging and have the following list of 1,897 websites for your review. These are Rails sites only (before version 4.0, and not including Rails sites that encrypt their cookie values). This is not an exhaustive list, and there is future work to be done in detecting remotely the use of Rails’ CookieStore with encrypted values as well as the presence of Django’s cookie-based storage mechanism.

This Insufficient Session Expiration weakness (WASC-47) is pretty common I found, and it is especially bad when the site does not use SSL. Many of the websites and tools we use store the session hash on the client side, including the applications Redmine, Zendesk, and Spiceworks.

If you don’t have access to the app’s source code, you may be able to figure out if the site you are visiting is using Rails’ CookieStore (before version 4.0 due to its encrypted cookie values) by checking for the string “BAh7″ at the beginning of the value of any of the cookies. A SHODAN search will reveal tens of thousands of these apps:*

Contact me if you are on the development team of any of the following websites and need help switching.

Continue reading


Make your mornings suck less with a alarm clock (for Mac)

I don’t do mornings. I really don’t. I’ll stay up until them, sure, but I do not want to wake up to them.

Using OS X Mountain Lion, here we go: for the impatient, just read the bold.

Edit: I realize that bold doesn’t show up well with my current configuration. I’ll work on that.

  1. Visit in your default web browser, which will be the same browser that the following alarm clock script will work with, sign in to your Pandora account, and choose the radio station you want to play every AM. I play general Trip Hop, but that’s just me. Close Pandora, but DO NOT LOG OUT of your account.
  2. Fire up Automater (it’s included with the OS) and create a new Calendar Alarm.
  3. For your first Automator Workflow step, Select Actions > Utilities > Set Computer Volume.
  4. Set your Output volume where you like. I set mine as follows: Output volume: 50%; Alert volume: 0%; Input volume: 0%. I didn’t want to be jolted out of bed.
  5. For the next step in your Workflow, choose: Actions > Internet > Get Specified URLs.
  6. Change the “” to “”
  7. For your last Workflow step, select: Actions > Internet > Display Webpages. Your Workflow should now resemble this:
  8. Screenshot of the Automator Workflow to launch as a morning alarm clock
  9. At this point you are done editing your Workflow. (Hooray beer!) Chose File > Save and give your Calendar Alarm a descriptive name. Once saved, the native Calendar application should fire up and you should see your Alarm in the current day. You should also see the “Automator” calendar under “On My Mac.”
  10. Specify the time that you want your Internet radio to start playing by right-clicking on the Alarm, choosing Get Info and setting the time. Also set “repeat” to “Every day” or whatever works for you. If you only work every other day, week, or month, that’s awesome.

Protip: To reduce clutter in the Calendar app you can uncheck the box next to the Automator to hide it. The Alarm should still go off as scheduled (it did during my testing). Or use Google Calendar for all your events and meetings. Also, if your default web browser (USE CHROME!) is already running when your alarm goes off–which is the case for me because I always have an obsessive amount of tabs open even though I use Pocket–this script will simply spawn a new tab. If you already have Pandora running, I have no idea what will happen. Good luck brave soul.

After looking through other Automator actions it appears that you could also do this with an iTunes playlist (and a lot of other applications), but I haven’t tried anything out other than what is above out so you will have to DIY. There was also some talk on the ‘net about using Pandora’s desktop application (via Adobe Air) for this. If you used launchd instead, awesome. Tell us about it. Post your solution in the comments.

Note that the first step you created in the Automator Workflow controls the volume of your Mac. If you are using external speakers with their own volume control (like I am) then you will need to adjust those to your liking as well.

Site update: This is the first post in the Life Automation series that I hope to continue posting to. I had an awesome boss that was the master of automation and he got me hooked on attempting to automate everything in life.

Once you’re out of bed, get some Powerthirst.

Disclaimer: Just bought a Mac so this may not be the most optimal way to go about doing this.


Gender and Personality Type Assessments of Your Blog.

Here are two interesting links I came across. alleges that you can determine both the gender and personality type of a site’s author by just entering the URL you want evaluated into their site.

Before this posting, this site is apparently 56% male and of an ESTJ Myers Briggs personality type.