Category Archives: Tips

MapTable.js for all your table and map needs!

2 minutes, 13 seconds

I’m proud to announce that I played a small role in releasing a great new JavaScript library called MapTable. This is an open source JavaScript library that accepts longitude and latitude data (CSV or JSON) as input, and outputs beautiful maps in native SVG with table of the data used to generate the map.  I said I played a small role in this release because Mohammed “Simo” Elalj did 99% of the coding of the library and I just swooped in for testing, PCH specific feature requests and pushing out new builds to GitHub. Version 1.0 of MapTable was technically released way back in December of 2014, but it has been greatly improved since then (again, almost entirely by Simo :).

pch.ixpdir.maptableVersion 1.1.1, the current version, was developed specifically so it could be used on PCH’s next generation Internet Exchange Point directory (IXP Dir). PCH’s IXP Dir was also the original use that MapTable was conceived for, so it has been a long journey until just now (as of Monday, July 25, 2016) that it has been pushed live!  My main role as an employee of PCH was to complete the nascent integration done a while ago and ensure that all feature requests were made on GitHub so that the improvements would be made upstream of us for all to benefit from. It was great fun to do a deep dive into a well though out and highly function JS library.

pch.homepageWhile I was in the IXP Dir, I also replaced the code on our home page which used an outdated version of MapTable. Fortunately, Simo had done PCH the huge favor of making one of the MapTable demo pages be based almost entirely on our home page. The ability to set an entirely custom color palette topped with icing on the cake of being able to specify an arbitrary SVG shape to use as markers on the map was just delightful!

While I’m wildly biased, MapTable is quite easy to use. Here’s the simplest incantation, taken directly from our docs:

Looking at the two examples I cited above, our home page and our IXP Dir, you can see that this simple snippet can be greatly extended to show either a stand alone map or an interactive, zoomable, filterable, printable, map downloadable, tooltipable and sortable map and table. The library is super awesome, and I recommend you start using it today! And yes, I just add “able” to tooltip. Try that in some other JS lib. I think not!

And, before I end this post, if you’re a JS developer and have some spare time, we’d love some help! I’m looking at you Issue #25!

Scanning multiple subnets for SSH servers that accept passwords

1 minute, 25 seconds

At work I was tasked to see if any of our servers are running SSH which allow passwords instead of strictly only allowing SSH keys.  You can tell if they allow passwords when you get a password prompt like this:

$ ssh user@example.com 
user@example.com's password:

Of course we’ll use nmap to scan for open SSH ports. I suspect I should have have used nmap NSE to do scripting, but we’ll plod ahead with out it.  Here’s the call I used to scan each subnet for open SSH ports and append it to ‘open.raw.txt’. Run this for each of your subnets:

nmap -PN -p 22 --open -oG - 1.2.3.0/24 >> open.raw.txt

Here’s an example line from open.raw.txt:

Host: 1.2.3.1 ()	Status: Up
Host: 1.2.3.1 ()	Ports: 22/open/tcp//ssh///

To get that all formatted nice for the next phase, we’ll just cut out dupe and grab just the IPs:

grep 'Up' open.raw.txt |cut -d' ' -f2 > open.ips.txt

Finally, taking much inspiration from this script on StackOverflow, I wrote a bash script to check for servers with a password prompt on SSH called ssh.test.sh:

#!/usr/bin/expect
proc isHostAlive {host} {
set timeout 5 
spawn ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=QUIET -o PasswordAuthentication=yes ssh-testing@$host
expect {
    timeout {puts "Timeout happened"; return 'TIMEOUT'}
    eof {return 'NO'}
    -nocase "password:" {send "exit\r";return 'YES'  } 
}
}

# Lists to maintain the each host's information 
set serverList {1.2.3.1 1.2.3.2 1.2.3.3 1.2.3.4 1.2.3.5}

# Looping through all the servers and checking it's availability
foreach server $serverList { 
    puts "\n$server : [isHostAlive $server]\n"
}

To execute and log the results, call:

ssh.test.sh > password.accepted.raw.txt

And finally, to clean up those results into a file with “YES”, “NO” or “TIMEOUT” for each IP, just use this final grep

egrep  'YES|NO|TIMEOUT' password.accepted.raw.txt > password.accepted.txt

The final results will look like this:

1.2.3.1 : 'YES'
1.2.3.2 : 'NO'
1.2.3.3 : 'YES'
1.2.3.4 : 'YES'
1.2.3.5 : 'TIMEOUT'

Happy SSH testing!

Web App Security Cheat Sheet

1 minute, 36 seconds

I recently documented best security practices for writing a web app. Since I was most of the way there for a nice tidy blog post on the topic, I’m using the contents of those docs as a cheat sheet for web app security. Best to refer to OWASP for a more exhaustive list, but here’s mine in PHP/Apache:

title description sample
No Traffic on Port 80 Always use an encrypted channel for web traffic, never send a session cookie in the clear RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
HSTS Set header so after 1st redirect, client goes directly to SSL connection Header always set Strict-Transport-Security
“max-age=15768000”
Forward Secrecy Use ephemeral keys for TLS connections to prevent wholesale decryption if private key is compromised SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
SSLProtocol All -SSLv2 -SSLv3
SSLHonorCipherOrder On
Anti-Clickjacking Prevent your site from being included in an iframe Header always set X-Frame-Options DENY
Anti-CSRF Nonces No one getting tricked to submit pre-filled forms using their existing session cookie $_POST[$NONCEKEY] == $_COOKIE[$NONCEKEY]
(but more to it – see this gist)
XSS escaping NEVER TRUST USER INPUT, save raw values to DB, cleanse on display print htmlspecialchars($user_string_here, ENT_QUOTES, ‘UTF-8’)
Secure cookies Never transmit cookies in the clear, works well with HSTS setcookie( ‘session’, $sessionId, 0, ‘/’, ‘www.example.com’, isset($_SERVER[“HTTPS”]), true);
HttpOnly cookies don’t allow JavaScript/XSS to access your cookies setcookie( ‘session’, $sessionId, 0, ‘/’, ‘www.example.com’, isset($_SERVER[“HTTPS”]), true);
bcrypt hashes Use a *slow* hashing method instead of a *fast* one (I’m looking at you MD5…) password_hash(“rasmuslerdorf”, PASSWORD_DEFAULT)
Though Argon2 is up and coming!
strong session ID don’t store anything but pseudo random ID in the cookie. Again NEVER TRUST USER INPUT! bin2hex(openssl_random_pseudo_bytes(50))
no session fixation on logout, delete cookie **and** server side entry in DB so session is dead dead dead NA
re-prompt for passwords on email, password or username change or when showing/changing sensitive data NA
no SQL injection still NEVER TRUST USER INPUT, parameterize all queries $dbh = new PDO(…);
$stmt = $dbh->prepare(‘SELECT * FROM users where username = :username’);
$stmt->execute( array(‘:username’ => $_REQUEST[‘username’]) );

Penance for forgetting basic debugging

1 minute, 56 seconds

I was working on implemented a nonce to fight CSRF requests on all our forms. The nonce worked liked you expect: by setting a cookie and then putting the same value in the form. When the form was submitted, the back end checked that the form nonce matched the cookie nonce and, bam, bob is your uncle.

The HTML for the form was hosted on foo.domain.com and was fetched via an AJAX call to render it in a modal on bar.domain.com. It used a JavaScript function that looked like this:

  $('.login_action').click(function(){
    Modal.init({
      id: "login",
      primary_button_action: function(){
        $('form #loginform').submit();
      },
      url: URL_ROOT + "modal/login",
    }).open();
  });

Now, you can’t quite tell, but this is ultimately a wrapper for Twitter’s Bootstrap’s Modal call:

$('#login').modal(options)

For the life of me I could not figure out when the AJAX call from foo subdomain to bar subdomain was not setting the nonce cookie. I thought it would be a CORS issue, but quickly dismissed that because we all know that “AJAX Requests Get And Set Cookies Like Any Other HTTP Request“, right. RIGHT?!!?

I did follow the best practice of putting in poor man’s PHP break points to trace the $_POST and $_COOKIE values, but to no avail.

After far too long, but after a healthy discussion with a friend about how we learn and how we trouble shoot, I remembered my mantra I always tell junior engineers: “Simplify the problem! Distill it down. Ideally, continue to cut the code in half again and again until just the bare minimum manifesting the problem remains.”

This lead me to reproduce the problem in two lines of code on foo.domain.com to call bar.domain.com:



The problem was still there! No nonce cookies getting set. Let’s remove jQuery then and go to raw JS requests:

var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://bar.domain.com', true);
xhr.withCredentials = true;
xhr.send();

Wait ah second! What was that I see in the console?!@@!#%$:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://bar.domain.com. (Reason: CORS header 'Access-Control-Allow-Origin' does not match '*').

Oh…CORS…the thing I dismissed upfront. So, yes, AJAX calls are just HTTP requests per bennadel.com’s blog post, but of course if foo subdomain is calling the modal on bar subdomain via AJAX, it’s an XHR request to another (sub)domain which needs to play by CORS rules.

If any one is interested, I published a gist with our PHP code to do nonces.

Top Posts Update

0 minutes, 54 seconds

A while ago I did a write up of the top blog posts on this site.  Oh…um, I guess that was 5 years ago now.  Wowaa.  Well, Here’s the same script run again to give you an idea of what’s popular:

$ grep 'GET /blog' plip_log/access_log|cut -d" " -f 7|egrep -v '.png|.jpg|wp-includes|.css|/page/|/category/|xmlrpc|wp-trackback|/feed/|wp-login|/wp-content/|/trackback/|wp-comments|wp-app.php|wp-admin|comment-page|index.php|?p=|page_id|comments|feed'|sort|cut -d"/" -f 3|uniq -c|grep -v ' 1 '|sort -nr|head
   1026 free-idea-abstracted-facebook-nonymizer
    959 adendum-to-ashleys-law-problematic-imac-vesa-mounts-and-new-desks
    805 toss-your-salad-code
    693 thoughts-on-very-large-monitors
    650 photos-food-bikes-sunsets-and-stars
    635 sunset-and-rainbows
    385 oakland-sf-photos-coffee-and-scotch-whiskey
    373 wayback-machine-privacy-and-old-plip-com
    361 how-i-make-coffee
    330 our-pet-venus-fly-trap

This may make them all the more popular, but here’s the links for them:

1026 free-idea-abstracted-facebook-nonymizer
    959 adendum-to-ashleys-law-problematic-imac-vesa-mounts-and-new-desks
    805 toss-your-salad-code
    693 thoughts-on-very-large-monitors
    650 photos-food-bikes-sunsets-and-stars
    635 sunset-and-rainbows
    385 oakland-sf-photos-coffee-and-scotch-whiskey
    373 wayback-machine-privacy-and-old-plip-com
    361 how-i-make-coffee
    330 our-pet-venus-fly-trap

A few updates on these post’s topics:

  • A lot of the images are broken on older posts. I think this has to do with going all HTTPS and as well some munging of the markup to rendered HTML.  I’ll try and fix these, but sorry!
  • I’ve been using an AeroPress to make my coffee of late (though the Chemex’s siren song is wooing me)
  • Lastly, I’m proud to see my top 3 posts are what they are ;)

Detecting IPv6 with JS and PHP

0 minutes, 36 seconds

A friend of mine wanted a way to know if visitors to her site were coming from an IPv6 address. To do this, you would run some PHP to output a JS variable with global scope:

// thanks to:
// https://plugins.svn.wordpress.org/ipv6detector
$ip =  $_SERVER['REMOTE_ADDR'];
if (substr_count($ip, ":") > 0 && substr_count($ip, ".") == 0) {
        $js = 'var is6 = true';
} else {
        $js = 'var is6 = false';
}
print "<script>$js</script>";

And then to give the user a sense of excitement, animate showing them if they are v6 or v4. You’ll need jQuery for this, of course:

<div id="ipwhich" style="font-size:2em">?</div>
<script>
var showMe = 'v4!';
if(is6){
        var showMe = 'v6!';     
}
$("#ipwhich").delay(1000).hide().delay(1000).html(showMe).fadeIn();
</script>
</div>

I did up a live demo: give it a try!

Let’s Encrypt TLS & A+ on SSL Labs

1 minute, 23 seconds

As you may recall, around here we like our TLS, and we like it rare!  I have no idea what “rare” means in the context of web encryption, but you know, that’s the way we like it!  We also like it cheap!  Even better than cheap (free) is open (libre)!  So, put it all together, and you get Let’s Encrypt TLS certs on plip.com and related properties.  Yay!

I saw the EFF/Let’s Encrypt crew speak at at DEF CON this past summer,  and it was super inspiring.  I’d already heard about the project, but it was that much more exciting to hear their talk.  I was dead set on cutting over from my old CA, to the new, definitively open, one.

While I was in my server, I went and visited my fave site for secure web server configs, cipherli.st. The only option I can’t run is SSLSessionTickets, as it requires Apache 2.4.11 or later. We’ll get there later with an Apache upgrade.

Put this all together?  You get a big fat A+ on SSL Labs.  w00t!

Some caveats are that Let’s Encrypt is just in public beta, so there’s some still some kinks to work out. For example, I mistakenly tried to get a cert for a wildcard vhost (eg “*.foo.bar.com”).  I got back an error:

An unexpected error occurred:
The request message was malformed :: Error creating new authz :: Invalid character in DNS name
Please see the logfiles in /var/log/letsencrypt for more details.

So, while I shouldn’t have selected the domain to get a cert (Let’s Encrypt doesn’t do wildcard certs), the error was a bit cryptic.  Fortunately the fine folks in their IRC channel (web IRC client – #letsencrypt @ Freenode to DIY) quickly pointed out to not use wildcards and that there was issue 1683 already open.

Awesome sauce, thanks Let’s Encrypt!

Bootstrapping with secure passwords

2 minutes, 6 seconds

I recently fat fingered the partitions on my 5k iMac when installing Ubuntu (more on Ubuntu on a 5k later!), so I was stuck doing a double clean install of both OS X and Ubuntu.  Given how often I find myself re-installing a system from scratch, I’ve gotten pretty good at getting all my core apps set up.  All the software I run is open source or free, so downloading it is quite easy.  But how do you log in using all your secure passwords?  The passwords are stored in my password safe, but the password safe is stored in a password protected, self hosted cloud file server. Classic chicken and egg scenario.  Here’s how I get around it:

  1. Go to a computer where you have your password safe handy
  2. Log into your cloud file server
  3. Generate an unprotected shared link to your password safe.  This will look something like this: http://my_owncloud_server.com/public.php?service=files&t=4617c2d4e806fa0d8bf6f47e4123f695
  4. Then take that link, and use a URL shortener to make a short, but not too guessable URL

Now, when you need to bootstrap a new computer, it’s simple as pie:

  1. Download password safe binary
  2. Go to http://tinyurl.com/MySecretPasswordSafeURLHere
  3. Download password safe file

Thus we solve the chicken and egg problem.  As well, since we’re pointing to the most up to date version of your password safe on your cloud server, you’ll always have your latest passwords!

Yes, yes, we are exposing our selves here to some risk that some one will guess the shortened URL of our our password safe.  However, this is pretty unlikely that it’ll be guessed.  As well, you use a good pass phrase on your password safe, right?!

For smart phones, I’ve had similar problems bootstrapping when I can’t download the password safe app because I can’t log into the app store. Another chicken and egg!  Here’s how I work around this (which would work for the desktop scenario too):

  1. Turn your phone on, skip account set up
  2. Connect to WiFi or cellular data so your mobile browser can connect to the internet
  3. On another computer, where you have access to your password safe, copy your primary login for your app store (aka your iCloud or gmail/google app login)
  4. Go to onetimesecret.com and create a secret URL
  5. Go to ye’ ol’ URL shortener, and create a customized, short URL: http://tinyurl.com/help-obi-won-kanobi linking to your onetimesecret URL
  6. Now you can manually type the short URL on your phone and get the password which you can then copy and paste to log into to the phone/app store.

Though it seems like a number of painful steps they both go more quickly than you think and I seem to do them enough they’re second nature.

Using Git on Ubuntu with SSH Tunnels to Mac OS X Host

4 minutes, 9 seconds

Intro & Prerequisites

Are you using Linux but cannot get your LT2P-IPSEC VPN hosted on your Mac OS X server working?   Do you write code on your Ubuntu client and check into a git server behind your VPN? Maybe you should consider ditching the VPN client and using SSH tunnels instead. Really, this will work for any server that’s on the remote LAN that you have SSH access to, but in my case it was the same host as the VPN Server, a mac. As well, this can be any client as well, not just Ubuntu.

In all the notes below, any time you see “mrjones” or USERNAME, replace it with your username.  Anytime you see an all caps computer name that’s SERVER_NAME.com, replace it your server’s name.  The VPN server, SSH jump host and jump host are all the same.

You’ll need:

  • An SSH client you know how to configure. For OS X and Ubuntu clients, this is built in.  For Windows you can use putty.
  • An SSH account the remote server which has access to your remote LAN you want to access.
  • An SSH public key you have put on on your ~USERNAME/.ssh/authorized_keys file on this same remote server.

SOCKS5

You can use SSH to create an SSH tunnel, specifically one that has dynamic ports and hosts as specified by the requesting app – aka a SOCKS5 proxy. To do this, you can use any local port above 1024, but I use 1080.  It looks like this:

ssh -D 1080 mrjones@SECRET_DOMAIN.com

In your browser then, for example FireFox, you set up the proxy by:

  • socksPreferences -> Advanced -> Network -> Connection -> Settings
  • Choose “Manual Proxy Configuration”
  • In the bottom option for “SOCKS Host” put “127.0.0.1” and for port put “1080”

 

The benefit of setting up a SOCKS5 proxy is that your URLs are the same as if you were on the VPN. This means that when you copy and paste them into/out of IM chats and emails, they just work as opposed to having localhost in them or trailing, odd ports.

SSH Tunnels with agent forwarding

You may still need to SSH to a production machine via the remote server jump host.  In order to do this and not have to re-federate your private key the SSH jump host (or generate a new private key on the jump host and then federate that out to the production machines), you can just do this:

ssh -A -t -l mrjones SECRET_DOMAIN.com ssh -A -t -l root SECURE_INTERNAL_SERVER.com

After running that you should have a prompt on SECURE_INTERNAL_SERVER.com as root.  This assumes that you have your public on your *local* box added to the authorized_keys of the account your SSHing to on the remote most box (SECURE_INTERNAL_SERVER.com).  This is a thing of beauty.

Checking code out with git over SSH

If you’re like me, you need to git clone for repos hosted on your stash/gitlab/whatever server which is only accessible on the VPN or LAN. You can do this with tunnels as well!  For me, I use  Stash professionaly, so instead of running this command to clone a repo:

git clone  ssh://git@STASH_SERVER.com:7999/path/to/repo.git

You can run this to add a tunnel to the stash host and then clone via a specialized host:

ssh mrjones@SECRET_DOMAIN.com -N -L 7999:STASH_SERVER.com:7999
git clone ssh://git@localhost:7999/path/to/repo.git

subsequent git commands like commit, pull, status etc. work with out modification transparently.

Pushing code with git over SSH

If you’re like me, you need to push using git via awesome git post-commit hooks. You can do this with tunnels as well!  Instead of running this command to add your remote:

git remote add live ssh://git@PROD_WEB.com/opt/git/web.git

You can run this to add a tunnel to PROD_WEB.com and then add a specialized remote:

ssh mrjones@SECRET_DOMAIN.com -N -L 2200:PROD_WEB.com:22
git remote add live ssh://git@localhost:2200/opt/git/web.git

subsequent git commands to push new branches work with out modification transparently.

Side note, you can push specific tags using this syntax:

 git push live +TAG_HERE^{}:master

SSH Tunnel manager

gstm

DDG gSTM pic

Managing all these tunnels is a total pain.  You could create a shell script to do it, but the cleanest way by far is to use a tunnel manager.  For me on Ubuntu this gSTM (Gnome SSH Tunnel Manager).  This allows you to, with one click, turn on and off all the tunnels listed above.

 

Caveats

Right now the biggest caveat with this set up is that *ALL* your web traffic goes over the VPN host (this is actually the same as when you’re on your mac based VPN). Further, your browser will not work *at all* with out the tunnels set up, even for any hosts (not same as VPN ;).  Which means even if you want to use your browser for non-work when you’re not working, all your browser traffic goes through your VPN server.

As well, if you run a vagrant dev environment, you can not access your VMs via their local Virtual Box IP, as they’re not accessible from VPN server.

You can fix both of these issues by either using a different browser for non work/vagrant hosts or disabling the proxy by flipping it back to “no proxy” back in settings.

I believe that Foxy Proxy might solve this, but haven’t tried it yet!

Your mom just got her first smart phone: what should she learn first?

2 minutes, 25 seconds

My mom just got her first smart phone, an iPhone 5S. What should she learn to do on it first? Fortunately, she has an iPad already so the iOS as a whole isn’t entirely foreign.

First up is the core list of phone phone features which is actually only limited to 6:

  • How to receive a call
  • How to place a call
  • How to send an SMS (text message)
  • How to receive an SMS (text message)
  • How to adjust or turn off your ring volume
  • How to turn on and off airplane mode

My mom wants to barely use her phone so she doesn’t have to pay a lot per month.  Right now she’s paying $17.50 for 250 minutes, 300 texts and 30 MB per month from Consumer Cellular.  With these tight constraints, airplane mode will be your friend to ensure while you’re phone is not actively being used that it’s not using data while your email is checked or while some app is sucking down bits. As well, knowing if you’re phone is going to sound like Defcon level 1 alert when some one calls you is important. Know your sounds vs your silence!

The second set of features to learn are centered around how your phone is not just a phone, but a super powerful mini computer that fits in your purse:

  • How to get on WiFi at your house and other primary locations you frequent.  Though calls and texts will still be deducted from your plan, surfing the web and looking up directions will not. Couple this with your airplane mode savviness, and you’ll be a penny pinching queen!
  • Know your camera!  You always have it with you and you can use it in airplane mode! Your camera can not only take selfies and scenic shots, but it can take pictures of:
    • Where you parked your car at the airport
    • That recipe you’re reading in a magazine at the doctors
    • Slides of a presentation
  • Know your maps app.  You can look where to find a cup of coffee in a part of town you don’t know.  You can have it navigate it for you to a business you’ve never been to.  You can instantly look up where that deli you went to last year is in NYC or what country Estonia is next to (Latvia and Russia ;)
  • Know your audio app(s).  You can not only load your phone with your favorite tunes exactly like an iPod, but you can stream them from providers like Google Play and Pandora. NOTE! This will use a lot of your monthly data if you’re not on WiFi. On top of all this, you can get a podcast app and load your phone full of amazing stories and info that can all be listened to with airplane mode one.

I don’t know if she agrees (Mom?), but I think some of the best advice I gave her was that she didn’t need to rush things with the new phone.  She could take as long as she needed to learn how to do a task (or wait until I’m free to walk her through it).

Do you know someone who just got a smart phone for the first time? What do you think should be on the top items to learn?