https enabled for is now live. At some point it should become default. This is important so that passwords sent to the site are encrypted when logging in.

On a side note, I find it ironic that sending passwords to websites on unencrypted http raises no warnings while sending to encrypted self-signed websites raises all sorts of alarm bells. How is the former better??

Fortunately, setting up https is easier than it used to be. I thank Startssl for their free basic SSL certificates and this blog post for explaining how to set it up for the nginx server. According to the SSLlabs report, the site is all good to go!

Time to update the links for my training log to

Plate calculator while logging a workout

You know how much weight you want on the bar but do you have the right plates to make that weight? What’s the nearest weight you can achieve with the plates that you do have?

Traditionally, you can use a tool like a plate calculator to enter your plates and target weight to figure it out for you. But usually you’re in the middle of your workout, perhaps logging your workout and don’t want to switch tool.

With gainstrack, you don’t have to! If you’ve already set up the plate calculator, you can view the plates for your weight just by clicking on the icon next to your set and it will tell you

Bug fix update

A few bugs have been squashed recently!

  • [Bug fixed] Cloning and then editing externally imported entries would sometimes not allow you to successfully update the clone weight to something new.
  • [Bug fixed] CrazyStrength integration would break if weight was empty. E.g. pull-ups
  • [Bug fixed] Various scrolling issues on mobile platforms

Strength levels added to your log profile

A new feature is being incubated! On your log profile (or under Stats/Scores on your mobile app), you will now see your Big 3 strength exercises being rated. More to come on how they are calculated but here are the key things to know

  • Barbell squat, bench press and deadlifts are the key exercises to measure your strength
  • Increasing your rep maxes will increase your level and points
  • The scoring is scaled 10 levels, ranging from the rank beginner to an elite lifter.
  • Just like various RPG games out there, the levels get exponentially harder to achieve
  • It takes into account your body weight (so make sure this is recorded!) and how many reps you do in your exercise
  • It will eventually take into account gender and maybe age
  • It doesn’t take into account how height, body physique, training methods etc. but does otherwise provide a fair score of comparison with your fellow lifting buddies, so invite them along to compare scores!

The formula may otherwise get refined but the levels should be pretty accurate as they are.

And this is me as of the time of writing

Analysis on EXRX and Rippetoe’s Strength Standards – Part 1 is a popular website to figure out how “advanced” a lifter you are in various categories. It’s also referred to in Rippetoe’s excellent book Starting Strength – a copy of the standards at

People often refer to this table as gospel but instead miss this key tidbit of information:

In other words, they sort of made it up, albeit from the best possible sources:

To see if I can do better I am going to run some regression analysis and use accumulated performance data to figure out both what we can learn from the experience of these Starting Strength authors, see if the standards can be improved and ultimately get a better measure of strength.

The only regression study I’m aware of is what has become the Wilks Coefficient. Is anyone else aware of similar analyses? If not, I will rely solely on Wilks, exrx and some basic maths.

Before that, I can draw some inferrences from Starting Strength tables alone. All else being equal (i.e. ignoring height, genetics etc. etc.) the Exrx table indicates male atheletes from intermediate onwards split their totals as follows

  • 35% Squat
  • 25% Bench Press
  • 40% Deadlift

Or to interpret it another way, a typical deadlift is 14% higher than the typical squat and benchpress is 71% of the squat. That’s kind of interesting – it’s an FAQ on what typical Squat/Bench/Deadlift ratios are, so here you go. Furthermore, the ratios don’t change across different bodyweights! (Height probably matters though)

For the newer athlete, squat/deadlift take a lower ratio, whilst bench press takes a higher ratio. I pay less interest to this because it may be the typical untrained athelete has actually tried to bench before whereas squat is a foreign exercise. Or perhaps it is interesting because it shows how the Squat can proportionally improve as the fastest exercise when you are first starting out.

Announce: Gainstrack mobile app betas!

Maintain a training log has been one of the keys to my personal success – in terms of accountability and the support you get from others. You get measurable progress in seeing how you progress with your strength goals.

When I heard my old community, SLIC, was getting shut down, I was spurred into action. I thought it unacceptable that hundreds of training logs -  long term diaries of progress could be lost forever. Furthermore, the logging there was never quite as good as it could be.

So since the SLIC shutdown, I’ve been working on making my perfect training log software to track my gains. Perfection will take time but it is now in a state I am happy to log my workouts on my phone for myself and to start sharing the capability with others who want the same things from logging like me.

So who is me then?

I’m a lifting techie. I care about stats, progress. I want to know all the analysis from my training log so I can learn what I’m doing, what to target and how to do better. Rep maxes, graphs, plate calculators etc.!

I believe in open standards and am against vendor lock-in. Never again should a training log be at risk as when the site closes down. Logs should be transferable within sites. You can get your log entries in and out of Gainstrack and I’ll make it as easy as I’m allowed to integrate with sites like CrazyStrength.

I believe in open platforms. Whether you are on your desktop, on your Android or iPhone mobile or offline in the gym, your training log and training tools should be available for you to use. Hence a mobile app.

Desktop version is at

Android users can pick up it up from the Play store now soon. In the mean time, you can download the APK from

iPhone users follow instructions at

I welcome feedback, suggestions, feature requests, bug reports and any general commentary!

iPhone bug with window.alert in web apps

I thought I had a crazy bug. My iPhone tester reported that after closing a pop-up alert, the app would force close. This got me really worried since I don’t think I could cause a browser to crash even if I tried!

It turns out various flavours of iOS have a bug whereby alert/confirm in an event handler would cause the browser to shutdown. C’mon apple! It’s bugs like these that cause developers to have to create crazy workarounds to make things work across browser. The workaround in this case for AngularJS is to delay the alert

$timeout(function(){window.alert('My alert');});

CSRF protection with AngularJS and Mojolicious

Gainstrack is a single page application based on AngularJS that makes Javascript calls to a Mojolicious backend. In the modern age, one just protect against CSRF attacks that change user state triggered by malicious code in a pages on a 3rd party website.

A good first line of defence is to ensure that all requests that may change state are restricted to POST requests. This is as simple as ensuring your route accepts nothing but post

$r->post('/command/doStuff') # Not $r->any

This protects against many attacks caused from sites with XSS vulnerabilities allowing hackers to place carefully crafted IMG tags on such vulnerable sites. However, it doesn’t stop carefully crafted iframes+javascript from executing a POST attack as this Stackoverflow question demonstrates.

For further protection, we should generate a server side token that the client side passes back only via Javascript. This provides protection against CSRF because the Javascript that can process the token is protected by same origin policy. There are various intricacies in implementing CSRF token properly. Fortunately, both AngularJS and Mojolicious have in-built help for CSRF protection – it is just a matter of gluing things together!

Angular $http documentation describes how it has in-built support to use a XSRF-TOKEN cookie to subsequently add the token back via a X-XSRF-TOKEN header. So we just need to support this protocol on the Mojolicious side. Fortunately, Mojolicious already has token generation support. Thus all you need on one your app entry points is to have

$c->cookie('XSRF-TOKEN' => $c->csrf_token, {path => '/'});

Angular will handle this automatically. To perform CSRF validation, simply compare the header

my $csrf = $c->req->headers->header('X-XSRF-TOKEN') // '';
($csrf eq $c->csrf_token) or die("CSRF attack was foiled");

And with no further change on the client side, you have CSRF protection! Not bad for 3 lines of code.

Note that the above doesn’t seem to work of the site is deployed via Cordova/PhoneGap application. I had to do a workaround for that… details available upon request.