How Someone Accessed My Lyft Account and Stole a Ride

I’m on vacation in California (from Australia). I’ve spent close to $300 on Uber so far and $0 on Lyft, so I wanted to try it out. After redeeming a first ride coupon, I lined up a great time to try it out. Here is the story of how I lost my first ride.

Upon attempting to try and order a ride, I realised (only after a user clicks through to book a ride) that the app requires a user to add a US contact number to their profile before they can book a ride. It was unfortunate I had to find that out just as I was trying to get somewhere. So I googled the format of US phone numbers and threw a fake number in there. But the app sends a validation message, so I was not be able to validate using this method. As such, I tried setting up Google Voice to get a US number to use for validation, but discovered that even Google requires a US number before you can use their Voice service.

I was out of luck and the processes involved to actually contact Lyft are can be slow (and they want to prevent this, by attempting to limit user messages via FAQs and automation). But even if you navigate through to a contact form, even that requires a US number to submit. And even if I fake my way through that, they could take days to reply.

I googled some more and decided to use a random service online that provides US numbers and a simple public webpage that displays all the text messages sent to these numbers. I used this to get the validation code and activate my account. Great. I was planning to try it out the following morning.

I end up getting an email during the night, which was a ride receipt thanking me for riding with Lyft and documenting my ride. My first ride coupon was used and it would have charged my credit card if I didn’t have that coupon or if the amount surpassed the value of it.

I now have an educated suspicion that instead of logging in via Facebook, someone logged into Lyft using the same publicly available number I had found online. They would have had to validate the login [I assume] via text message, which was easy since they could also see the webpage I had used. They then were able to access my account; see the last 4 numbers of my credit card, my Facebook profile pic and my email address. They then immediately took advantage of this and ordered a ride within locations in Colorado. Image receipt:

Upon seeing this the following morning, I tried to cancel my account but this is not possible without contacting support. I tried to remove my credit card but this is not possible. I proceeded to change my number to a blatantly fake number in the app (after you have validated a first number, Lyft app does not require validation for subsequent numbers). This would hopefully prevent the user from logging into my account again.

In summary, I understand that my own actions caused what happened and that I used the app in a way not intended for users. Still, it was an uncomfortable feeling to find out users could log in via a phone number and that I couldn’t cancel my account, remove my credit card or contact support in an urgent scenario. If the malicious user had decided to change the email address on the account, I can imagine that they could lock me out and then proceed to charge many unrestricted rides to my credit card. I was also so surprised by how quickly this happened (only hours after).

So, I don’t know why Lyft even has the requirement of a US number for accounts. I have used Uber many many times here and never had a problem locating a driver without the use of a phone.

Read More

Kicking Ass at a High-Level IT Job Interview

Here are a few key ideas that helped me do well in an interview and score a good IT/ops job. This is coming from someone who works in IT, rather than someone in HR.

– If asked for salary expectations, don’t offer a salary “range”. It pretty much sets the bottom tier of your range, as their potential offer.
– Quote $10-20k over what your expected salary is. Companies like to play games and undercut you. Worst case scenario, you can bargain a bit. If you are not good at negotiating, perhaps even avoid saying a number at all. Something like: “I am looking to be appropriately remunerated for my skills and what the market is paying for such a role.”, would suffice.
– Maintain lots of eye contact and speak slowly. Think for a few moments before you answer questions.
– Act really enthusiastic. Speak about your work history, key projects and knowledge as if it’s super interesting and you’re really passionate about it.
– Be on time or a bit early. There are people who like to rock up 30 mins early, but I wouldn’t go that far. Sometimes the interviewer won’t even be ready for you if you arrive that early. The key idea behind being on-time/early is to not waste their time and being punctual is polite.
– Research the company beforehand. Read all over their website, browse the first few pages of Google for sites with their content, look through LinkedIn for the people you’ll be working with (look at their skills, technologies they work with etc). It also helps to be familiar with their industry and target market, competitors etc.
– Compliment the company’s product and convey that you admire what they do and what they offer the market. It makes them feel proud.
– Joke around, if appropriate. It depends on the culture of the company, but making the interview less formal at times or making funny observations can convey that you would be a good culture fit.
– Prepare and study for surprise/trick questions. I typically find some questions pretty illogical and don’t think they are relevant to the job, but it’s much better to have a memorised answer rather than be caught off-guard. For example: “What is your biggest weakness?” or “what did you struggle with at your previous workplace?” would stump a lot of people. If you do get caught off-guard, try your best.
– Wear formal attire to the interview. Even if you’ll be wearing a tshirt to work if you end up getting a job there, business shirt or otherwise formal attire, still helps. Even if it is a really informal place, it still portrays a nice image of yourself.
– If the opportunity arises, try to name drop specific technologies or programming languages you have worked with (should be a follow up to what you’ve listed on your resume).
– I’d recommend not listing references on your resume, as you are more prepared if the company asks you for some during the interview. Use this warning to your advantage and prep your references well. Make sure you choose people who will talk you up really well, even if they are biased.
– Make your Linkedin profile look neat and up to date prior to the interview. Some employers like to do a bit of research on you beforehand.
– Don’t undersell yourself or give them a reason to doubt you. aka. don’t say “I have experience with X… but I’m not that great”, which effectively /tells/ them that you are not good at something. Be more smooth; say you’ve only dabbled in it or have worked with something similar.
– Get the interviewer to sell the company to you. Ask about the culture and what’s good about working there. You may like to take this to the next level by asking to speak to someone that already works there in a similar position, to give you a more appropriate idea of what it really is like to work there and what day to day activities you can expect. This may not always be communicated in the best manner if you only speak to the HR person or higher level manager interviewing you.

Good luck, soldier.

Read More

Android Custom ROM Flashing – Issues

A few issues loading Cyanogenmod onto a Samsung S4 from a Debian 64 bit machine.

Bash would originally fail to execute the adb file (from Android SDK). Even though it was there, bash did not recognise it (with or without sudo:

./adb bash: ./adb: No such file or directory

Surprisingly enough, it was a problem with missing dependencies. Many people recommended installing ia32-libs but the fix for me were the following packages:

sudo apt-get install libc6-i386 lib32stdc++6 lib32gcc1 lib32ncurses5

Next, I was using adb sideload to copy my rom, rather than pushing it or copying it via any other method. I was getting:

ADB: error: insufficient permissions for device

Fix was to [when the device is connected]: “sudo ./adb kill-server”, “./adb start-server” and “./adb sideload /path/to/”.

Next, I also was unable to properly use Cyanogenmod after I flashed the ROM. It was taking me to a “Encryption unsuccessful” message and while it offered a button to attempt to fix it, this then resulted in a reboot loop [if you kept pressing the buttom]. This would relate to the fact I had encrypted my S4 and sd card in the past.

This seemed tricky to fix (after trying a few things and wanting to tread carefully) but I ended up rebooting into recovery once more and playing around. Most of the options in ClockworkMod Recovery [formatting-wise], failed with an error. Attempting a “format /data” failed, but for some reason, I had luck with the following option, with proceeded to *actually* format the partition for me and fix the problem:

 format /data and /data/media (/sdcard)

I then proceeded to re-run the original options to “wipe data/factory reset”, “wipe cache partition” and within “Advanced”, “wipe dalvik cache”. Then repeat the step of “install zip”, “install zip from sideload” and try again. I was then able to boot into Cyanogenmod fo’ real.

Read More

OpenNMS Failing to Start

This will outline some troubleshooting steps to take when OpenNMS is refusing to start. In this scenario, the service looked like the following, before eventually stopping:

OpenNMS.Eventd         : start_pending
OpenNMS.Trapd          : start_pending
OpenNMS.Queued         : start_pending
OpenNMS.Actiond        : start_pending
OpenNMS.Notifd         : start_pending
OpenNMS.Scriptd        : start_pending
OpenNMS.Rtcd           : start_pending
OpenNMS.Pollerd        : start_pending
OpenNMS.PollerBackEnd  : start_pending
OpenNMS.Ticketer       : start_pending
OpenNMS.Collectd       : start_pending
OpenNMS.Discovery      : start_pending
OpenNMS.Vacuumd        : start_pending
OpenNMS.EventTranslator: start_pending
OpenNMS.PassiveStatusd : start_pending
OpenNMS.Statsd         : start_pending
OpenNMS.Provisiond     : start_pending
OpenNMS.Reportd        : start_pending
OpenNMS.Alarmd         : start_pending
OpenNMS.Ackd           : start_pending
OpenNMS.JettyServer    : start_pending
opennms is partially running
[00:11:56]-> service opennms status
Could not connect to on port 8181 (OpenNMS might not be running or could be starting up or shutting down): Connection refused
opennms is stopped

With the web server rendering:

Service Temporarily Unavailable

The server is temporarily unable to service your request due to maintenance downtime or capacity problems. Please try again later.

A key step is going to be analysing the daemon logs to assess any potential issues, which can be found in: /var/log/opennms/daemon/ (tail -f /var/log/opennms/daemon/* to show them in real-time, as you start the service in another terminal).

You may see some exceptions like the following, but they are commonly only shown as a symptom of another problem. AKA. it is unable to call stop because the service could never start:

2014-06-15 00:19:29,166 DEBUG [Main] Invoker: Invoking stop on object OpenNMS:Name=Vacuumd
2014-06-15 00:19:29,172 ERROR [Main] Invoker: An error occurred invoking operation stop on MBean OpenNMS:Name=Vacuumd: java.lang.NullPointerException java.lang.NullPointerException
2014-06-15 00:19:29,231 DEBUG [Main] Manager: Thread dump completed.
2014-06-15 00:19:29,232 DEBUG [Main] Manager: memory usage (free/used/total/max allowed): 47401760/116815072/164216832/1200160768
2014-06-15 00:19:29,232 INFO  [Main] Manager: calling System.exit(1)
An error occurred while attempting to start the "OpenNMS:Name=Notifd" service (class org.opennms.netmgt.notifd.jmx.Notifd).  Shutting down and exiting. java.lang.reflect.UndeclaredThrowableException
	at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.rethrow(

However, this is indicative of a startup problem and a common reason for this is broken config files. A good step would be to have a close look at any files yourself or others have modified and perform a check on them. Else, you can parse the XML for syntax errors using xmllint:

xmllint --noout /etc/opennms/*xml

At least in my case, this showed that there was a missing “<" at the beginning of a file I had been working on, but had somehow accidentally removed this character.

notifd-configuration.xml:1: parser error : Start tag expected, ‘<' not found
?xml version="1.0" encoding="UTF-8"?>

Fix this up and perform another service start on OpenNMS. It can take a while to start but you can keep checking the status to see if the service remains active until it eventually gets into a permanent working state.

Read More

Salt Failing to Highstate due to Keys on Upgrade to 2014

Upon upgrading from a 17.x to 2014 version of Saltstack, some care needs to be taken to switch out the keys in the process. “Deleting” the key (with ‘salt-key -D’) will not be sufficient on its own.

Upon upgrading an existing instance of a Salt Master, you may notice issues when attempting to highstate a Minion (even a Minion and Master on the same box). Running the highstate in debug mode will identify delay and repeated attempts to load in keys.

[DEBUG   ] Loaded minion key: /etc/salt/pki/minion/minion.pem
[DEBUG   ] Reading configuration from /etc/salt/minion
[DEBUG   ] Including configuration from '/etc/salt/minion.d/master.conf'
[DEBUG   ] Reading configuration from /etc/salt/minion.d/master.conf
[DEBUG   ] Loaded minion key: /etc/salt/pki/minion/minion.pem
[DEBUG   ] Decrypting the current master AES key
[DEBUG   ] Loaded minion key: /etc/salt/pki/minion/minion.pem
[DEBUG   ] Loaded minion key: /etc/salt/pki/minion/minion.pem

The solution is to delete everything within /etc/salt/pki/* on Master and Minion. Then, delete the existing key from the Mater (salt-key -D or salt-key -d $key). Proceed to restart Minions and Master. You can test connectivity via “sudo salt \*” and proceed with another highstate to see if the problem remains.

Read More

Apache Redirect to Alternate Domain Whilst Passing URI

Moving a site such as to using Apache/Apache2. The requirements were to maintain the URI and 301 for SEO purposes. The last rule will carry across the URI, so hitting will forward through to . The first rule is to catch it when you hit directly. The second query catches the trailing slash, so redirects when you hit . The lack of “L” in the first two rules tells the web server that this is not the final rule for this pattern, and to continue parsing other rewrites.

RewriteRule ^/oldblog$ /blog [R=301]
RewriteRule ^/oldblog/$ /blog [R=301]
RewriteRule ^/oldblog.* /blog%{REQUEST_URI} [R=301,L]

Read More

Cloudflare and Transfer-Encoding of Absent or Chunking in a 403 Java App

There was a problem where a java application was returning this error, after a recent switch to Cloudflare:

Application Error
Application Error	 	A general application error has occurred. 
Server returned HTTP response code: 403 for URL:

It was noticed that the HTTP response header of “Transfer-Encoding:chunked” through Cloudflare, where it was otherwise present when hitting the web server directly.

One option was to look into Cloudflares different levels of caching. They have basic, simplified and aggressive.

Transfer-encoding denotes the transfer method used by HTTP to transfer data to the user. It can be chunked etc.

It turns out the problem was the Cloudflare Web Application firewall was adding in rules to block IPs. Due to this feature being hard to find in the current design of their website, you can find and configure it here: . Please note this is only for paid accounts.

Read More

Github Pull Request HTTP Request Failed

Receiving the message below when attempting a git push on a repo can be caused by a few things, but take note that it may be a permissions issue. If you don’t have permissions to create and push a new branch or push to the master, this message will occur.

error: The requested URL returned error: 403 while accessing
fatal: HTTP request failed> 

If you are looking to create a pull request to a project of this nature, the process will be to fork the project, commit to your fork, then navigate to the original project and click through to create a pull request, then select to compare to a remote fork and it will pick up your commits. This will allow you to create a pull request on the original project. For the future, you may also like to set the upstream in the fork to the original, so you are able to git fetch and merge changes from the original to your clone.

Read More

Postfix and Sendmail MTA Rejecting Mail

A recent issue I’ve experienced is that a person is unable to send mail to a certain email address from a script operating on another server, using their local MTA. Emails from all other places can be forwarded through to this address successfully. Investigation on the receiving server shows no evidence of rejection in mail log.

Sending server sees something like the following, whilst attempting to send a message via telnet for localhost on port 25:

Recipient address rejected: User unknown in virtual alias table

This is a bit confusing at first because it can be comprehended to think that the receiving server is incorrectly configured/inappropriately set up to not receive mail for this alias. In reality, the issue is actually with the sending server. Grepping around in /etc/postfix on sending shows:

virtual:$domain OK | virtual:problemalias@$ $mailbox 

Delete the configuration from the local server to fix the issue, else arrange to relay via an alternate MTA.

Read More

Presence of javac (Java Compiler)

Even with some openjdk jdk or jre installed, javac may not be present on a Debian system. You may receive a message like “The program ‘javac’ can be found in the following packages:” or “bash: javac: command not found” when trying to use it.

It may be worth seeing if you can “find” anything with ‘javac’ presence in /usr/lib/jvm/*, or if you have been playing with multiple versions, what’s configured on /etc/alternatives or /usr/bin .

Otherwise, javac can be pulled in via the following:

 apt-get install default-jdk

You should then be able to interface by typing “javac” in your shell or manipulating /usr/bin/javac , when is a symlink to /etc/alternatives/javac , when could a symlink to [depending on architecture] /usr/lib/jvm/java-6-openjdk-amd64/bin/javac

Note you may also want to try the following on centos:

yum install java-devel

Read More