Category Archives: Tips

A great, small USB-C charger for your XPS 13 (or MacBook) (Updated 4/16/17 DO NOT BUY)

1 minute, 53 seconds

5/12/18 Update: I’ve found a new charger that’s working well (and seemingly safely) – check it out!

4/17/17 Update: These chargers have been deemed unsafe. Please do not use them. See this post for details.

While I was on vacation, I forgot my laptop charger. I found on amazon that you can get an OEM charger for the XPS 13 (9350) for about $30. This is fine, it will work the prior gen XPS 13 with out USB-C/Thunderbolt too. I got it and used it for the remainder of my trip.

Then, when I got home, I wondered if there were any good, cheap, small USB-C chargers that would work with my laptop. Lo, the RAVPower USB-C charger. Full title, on Amazon, is, “USB C Charger RAVPower 36W Dual Ports USB Wall Charger with USB-C (20V 1.5A, 15V 2A, 9V 2A, 5V 3A max) for MacBook, Dell XPS 13, Nexus 5X/ 6P and iSmart (5V 2.4A max) for iPhone and more Black”. OK, what ever RAVPower, too long on the title. But you know what is not too long? The products it works with:

  • Apple’s 2015 MacBook
  • Google’s second Chromebook Pixel
  • ASUS Transformer book T100HA
  • Dell XPS 13 & 15
  • HP Elite x2 1012 G1
  • Razer Blade Stealth, Blade (2016)
  • Nokia N1, ASUS ZenPad S8, Google’s Pixel C
  • Nexus 5X, Nexus 6P
  • Asus ZenFone 3 Deluxe
  • BLU Vivo XL and BLU Vivo 5
  • HTC 10, LG G5
  • Microsoft Lumia 950, 950 XL
  • Motorola Moto Z, Moto Z Force

Totally awesome list! I got the charger today, so I don’t have any long term usage notes just yet. However, given it can both charge my phone over speedy USB-C, or dual charge my laptop AND my phone, as it has normal USB port to charge with, I’m fairly confident it’s my new fave travel charger. One caveat is that it does not come with a USB-C to USB-C cord. I got a nice looking 10′ one which I’ll put a velcro tie on when it arrives.

If you are an XPS 13 user, or thinking about becoming one, be sure to read my write up on running Ubuntu 16.04 after purchasing the windows version of the 9350.

1/4/17 Update – I’ve been using this charger for 4 months now and it’s awesome! I got solid, braided 10′ USB-C <-> USB-C cable to use with which I recommend as well. It comes in 6′ flavors as well. Cable aside, the only caveat is that the charger does get quite hot – but so far not so much that it has me concerned; I don’t see any signs of the plastic discoloring.

Laser Cut Acrylic SYN Shop Dice

2 minutes, 19 seconds

Back in May for this past Las Vegas Science and Technology Festival, the SYN Shop hosted an open house. It was awesome!

first.draftI volunteered to show folks our Laser Cutter. This is by far one of, if not *the*, most popular tool at the SYN Shop. In preparation of showing folks how it worked, I made a bunch of cubes. Not just any cubes though! I started with a 1.6″ cube at Maker Case with finger joints. I then added our logo. I did a test run and quickly saw that the translucent side of the acrylic I was using looked much better when viewing it from through the oppisite clear side, instead of viewing it directly. close.upI reversed our logo and as well added a very small mark in the upper left. This mark would allow me to run two discrete jobs: an engrave job and then a cut job. If you do them as one the laser cutter will engrave all your cuts and then cut them – a huge waste of time. The mark in the upper left allows me to keep the registration the same as long as I don’t move the bed or the piece on the bed. After feeling confident I had a good prototype design and size, I embellished it a bit by adding the 5 dice sides 1-5, the sixth would be our logo. I then laid it out as many up on the design as our laser cutter would handle, 4 x 3. Each sheet took over an hour to engrave the logos and dice faces and cut. I think I ended up making 48.

IMG_20160429_142319I learned after doing one sheet later on that though you get a bit less burn marks when you leave the protective sheets of paper on – it takes WAAAAAAY longer to peel when it has a logo engraving into it one side and then the cube face cutting it too. I pre-peeled both faces to save time. However, my son was totally into the production of peeling, stacking, and rubber banding the whole thing. I didn’t even need to tell him that he and his sister would get one to share after we ere done. We had fun!

IMG_20160504_231512During the event it self, I wanted to keep the laser cutter running to show how it works. As well, we quickly ran out of acrylic dice, so I needed another design to cut. I found a good, butterfly image that I traced in Ink Scape to create a nice looking SVG. From that, I made a bunch of test cuts and then just left it running during the day. As soon as the job was done I could pop open the lid and hand out hot, freshly cut butterflies. of the SVGs in this post are free to use for what ever purpose you want. It’d be great to hear of any uses though! I actually have a huge backlog of SVGs I’ve created over the past 1+ year that I should share…

Finally, here’s a video of my kids very much enjoying two octopi 3D printed with heat sensitive filament (also free handouts that day ;)

Blogs I Read

1 minute, 54 seconds

After my upgrade to my new phone, I accidentally deleted the list of all my RSS feeds I follow. It took some months to remember all the different ones, but I’ve finally recreated the entire list and re-subscribed to them all. I use RSS Reader on Android with pro version (no ads, no tracking!).

After completing the great resubscribe of ’16, I decided to make a post about my list mainly so I have a backup but also so my friends who sometimes ask where I get my news can follow along if they so desire.

A list of blogs I follow, non-personal:

Blogs I follow, personal (people I know):

MapTable in WordPress

3 minutes, 31 seconds

After my last post on MapTable, a friend of mine asked how he might include a map and table in a blog post on a WordPress Instance. In this post I’ll outline the steps to doing just that.


The steps to render a MapTable in WordPress post are:

  1. Include MapTable and related JS and CSS files
  2. Generating and posting your .csv file
  3. Author and post the actual JS for rendering the MapTable

Though this is specific to WordPress, the same logic applies to generically creating an HTML page in which you want to include a MapTable.

1: Ye Old <script> and <link> tags: MapTable, D3 and TopoJSON

Thanks to all the working examples hosted on the MapTable GitHub page, there’s no shortage of code snippets to look at on how to assemble the JavaScript and CSS to render a MapTable. I’ll be using the Example titled “Global Airport by Countries – +6000 rows, Log scale for country colors, tooltip“.

Looking at the source of that page, we see this code:

In order to render these in your blog post you need to switch to “Text” mode when editing your post (as opposed to Visual). Please note WordPress’s word of caution:

Switching between Visual and Text view can cause some of your HTML entities to be lost. This is due, in part, to the manner in which TinyMCE handles your HTML. If formatting is very important, do not switch between views. If you’re writing a lot of code, we suggest you remain in the text editor.

Following their advice, I don’t ever edit in visual mode.

So, now that you’re in text mode, go ahead an paste in the those three script and two style blocks.

2: CSV (or JSON) FTW

MapTable is very lenient on the format of the data you give it. While you do need to have at least Latitude and Longitude fields to render a map, you don’t need them if you’re just rendering a table! For our 6k aiport example, here’s what the first bit of the CSV will look like:

1,Goroka,Goroka,Papua New Guinea,GKA,-6.081689,145.391881
2,Madang,Madang,Papua New Guinea,MAG,-5.207083,145.7887
3,Mount Hagen,Mount Hagen,Papua New Guinea,HGU,-5.826789,144.295861
4,Nadzab,Nadzab,Papua New Guinea,LAE,-6.569828,146.726242
5,Port Moresby Jacksons Intl,Port Moresby,Papua New Guinea,POM,-9.443383,147.22005
6,Wewak Intl,Wewak,Papua New Guinea,WWK,-3.583828,143.669186

Unlike the script and CSS files, this needs to originate from the same domain as your blog is hosted on. To facilitate this, you’ll need to upload the .csv file to your blog via the “Add Media” feature. If you get an error like “Sorry, this file type is not permitted for security reasons.” then you’ll need to try and allow this file to be upload. This forum post does a good job of describing how to do it – however please note: this may introduce some security risks to your site. Please make this change with caution!

In the end, despite explicitly adding “json” as a file type, I could not upload a file ending in “.json”. I had to change the name of “ne_110m_admin_0_countries.json” to “ne_110m_admin_0_countries.js”.


We’ll cull a bit of the javascript, but it otherwise is just about identical to the one on the MapTable demo page. As well, we prepend the JS with a bit of HTML and styles. Here is the complete code I’ll use to render my map:

MapTable now!

This is a MapTable of “Global Airport by Countries – +6000 rows, Log scale for country colors, tooltip” embedded in WordPress:


If you use more than one MapTable on your blog, you’ll really want to move the .css and .js files to be in your template, as you’ll be including them many times, possible more than once on places like your home page. As well, if you do use more than one MapTable – you’ll only need to upload the ne_110m_admin_0_countries.json (or .js in our case ;) once and re-use the URL.

As well, I had some trouble getting the tooltip to work just as it is in the example. If I used HTML in it, the JS would break :( I suspect this has to do with the way WordPress aggressively adds line returns to HTML. This included taking a lot of line returns out above the MapTable JS and between my <script>, <link> and <style> tags.

Finally, if there is sufficient interest, I can see that a MapTable WordPress plugin would be really handy! Let me know if you’re interested and I’ll see what I can do!

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'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 - >> open.raw.txt

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

Host: ()	Status: Up
Host: ()	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

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 {}

# 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: > 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: : 'YES' : 'NO' : 'YES' : 'YES' : '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
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, ‘/’, ‘’, isset($_SERVER[“HTTPS”]), true);
HttpOnly cookies don’t allow JavaScript/XSS to access your cookies setcookie( ‘session’, $sessionId, 0, ‘/’, ‘’, 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 and was fetched via an AJAX call to render it in a modal on It used a JavaScript function that looked like this:

      id: "login",
      primary_button_action: function(){
        $('form #loginform').submit();
      url: URL_ROOT + "modal/login",

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


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 to call

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();'GET', '', true);
xhr.withCredentials = true;

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 (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’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:
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>
var showMe = 'v4!';
        var showMe = 'v6!';     

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