Jan
27
No, a stolen iPhone isn’t a brick: How thieves access your data
January 27, 2019 | Leave a Comment
Stop and read this. It may save you whole lot of grief and panic.
Maybe you’ve heard that a stolen iPhone is nothing more than a brick. Perhaps you feel as if your data is safe.
You have a password and it’s not 123456.
You have find my iPhone.
Allow me to burst your bubble by telling you what happened to me and why it could have been WAY worse. Also, turn off Siri right fucking now. If you cannot bear to part with it, turn it off when locked. Go to Settings , then Siri and Search. Turn off answering when locked.
HOW THIEVES ALMOST GOT AWAY WITH EVERYTHING
On Thursday, when I got of the subway I noticed the side of my bag was unzipped. I didn’t see my phone but my credit card and money was still in the pocket so I didn’t think I was robbed. I just figured I’d thrown it in with my computer. When I got home, i emptied my bag and still couldn’t find it. I used find my iPhone and saw it was 7 miles away. So, I put it in lost mode.
Keep this mind, the thieves had my phone for an hour at most before I noticed and locked it.
After I contacted people from my office and made sure I hadn’t left it there,I erased it.
HOW SIRI IS YOUR ENEMY
In the meantime , the thieves had gotten into my yahoo email and my Facebook page. How did they do that?
Because when you get your phone and you don’t disable this, Siri will answer hi when your phone is locked. Say,
“Siri, what’s my phone number? Siri, what’s my email?”
…. and Siri will tell you.
So, now the thief has your phone, your phone number and your email. TURN OFF SIRI NOW!
I never would have thought the default setup would have such a huge security flaw.
It gets worse.
Now the thief goes to yahoo, enters your email and click “Forgot my password.” They have the reset sent to your phone and then they reset the password . Guess what? The default is that messages show up on locked iPhones so they get the message and enter a new password. Now, they have your email and your password and your phone.
Next, they go to Facebook and log in using that email. They say that they have lost the password and have the password reset code sent to your iPhone or email they have stolen.
Now the thief has your email, Facebook, phone and phone number.
By this time, it had maybe been a few hours, I had figured out what they were doing ERASED my iPhone using the Find my iPhone app, deleted the yahoo email from my Facebook and changed the phone number on my yahoo account .
WATCH OUT FOR PHISHING EMAILS CLAIMING TO HAVE YOUR PHONE
This is where disaster really could have happened. So, I’m back in the office on Friday trying to do a million things plus reset my password on everything , handle things that come up every day with two companies in two countries and in one of my company accounts I get a message from “Find my iPhone “ . It looks legit . It says we’ve found your iPhone. It gives the model of iPhone , storage , how would a thief know that ? If you think about it , duh, they have my iPhone . But I’m thinking someone jacking iPhones on the subway certainly doesn’t have the skills to create something this professional. So, I click on it. Nothing happens. Thank God for my internet provider that strips out malicious code .
What this was supposed to have done was take me to a page that asked for my Apple ID and password to prove I was me. I might have done it,too. I’m staying with my ISP for life now.
After I switched phones,I got the same message in a text to my new phone number. I can only guess that either a) they were still logged in when I changed it or b) they searched for me on Google.
!!!!! These were not some gifted thieves. There are actually SERVICES that do this for them ! Want to get the Apple ID and password of a person whose phone you’ve stolen? Send them all of the info you have and they will create the rack email and text messages !
EVEN IF YOUR PHONE IS DISABLED,THEY STILL HAVE YOUR SIM CARD
They can (and did) swap that into another phone. When I thought of it two days later,Dennis disabled the account with ATT and he got a message that it was now disabled on a Huawei phone which is not sold in the US but very popular in Chile .
HERE IS WHAT I DID WRONG BEFORE MY PHONE WAS STOLEN
Obviously the Apple default is a huge security flaw. I should have disabled Siri as I never use it and also disabled messages showing on lock mode.
Ironically, I had the yahoo account on my Facebook account thinking it gave me EXTRA security. I hadn’t really used that account in years .
It was possible to reset my yahoo account from a phone, so if someone had my phone they could get access to my email.
HERE IS WHAT I DID RIGHT
I had a second email account that could NOT be reset from a phone. I used that to lock the thief out before they thought of removing it.
When I changed the password and phone associated with my email and Facebook I picked “Log me out of other devices” so if they were logged in somewhere else they couldn’t just change it back.
My phone does not allow purchases so even when someone had my SIM card they could not use it to buy anything. We turned this off with ATT years ago.
None of my bank information is written down anywhere , not passwords, accounts, SSN, nothing . I memorized them. Logins for things like that Software I bought five years ago and the license are written down , or for that stupid forum on blogs. These are not used for anything important .
Any information that might be important is recorded like this:
Password- same as for that computer we used to have in the living room
Had an Internet service provider that stripped out the script on the phishing email and saved me from a huge mistake.
Called ATT to block the number so no one else could use the SIM card
My social media accounts are not connected. Getting into my Facebook doesn’t allow you access to my Instagram, Twitter or anything else. Whenever Facebook asks to connect to anything I say No.
There is very little information in my social media profiles and some of what has been put there automated by Facebook is wrong. So,if anyone was hoping to use the information they got for identity theft they are out of luck .
WHAT SHOULD YOU DO NOW?
At the very least , this second, disable Siri when locked and turn off notifications when locked.
Turn off purchases from your phone.
Turn off resetting your password from a phone .
Disconnect social media accounts form each other so if someone has one account they don’t have all of them.
And for the love of God quit believing that bullshit that stolen iPhone is no more than a brick!
Support my day job!
Jan
20
SUPER BASIC INTRODUCTION TO DATA ANALYSIS
January 20, 2019 | 1 Comment
I was going to write more about reading JSON data but that will have to wait because I’m teaching a biostatistics class and I think this will be helpful to them.
What’s a codebook?
If you are using even a moderately complex data set, you will want a code book. At a minimum, it will tell you the name of each variable, the type (character, numeric or date), a label, if it has one and its position in the data set. It will also tell you the number of records and number of variables in a data set. In SAS, you can get all of this by running a PROC CONTENTS. (Also from a PROC DATASETS but we don’t cover that procedure in this class.)
So, for the sashelp.heart data set, for example, you would see:
The variable AgeAtDeath is the 12th variable in the data set. It is numeric, with a length of 8 and the label for it is “Age At Death”. Because it is a numeric variable, if you try to use it for any character functions, like finding a substring, you will get an error. (A substring is a subset of a string, so ‘ABC’ is a substring of ‘ABCDE’.)
Similarly, BP_Status is the 15th variable in the data set, it is a character, with a length of 7 and a label of “Blood Pressure Status”. Because it’s a character variable, if you try to do any procedures or functions that expect numeric variables, like find the mean, you will get an error. The label will be used in output, like in the table below.
This is useful because you may have no idea what BP_Status is supposed to mean. HOWEVER, if you use “Blood Pressure Status” in your statements like the example below, you will get an error.
**** WRONG!!!
Proc means data=sashelp.heart ;
Var blood pressure status ;
Seems unfair, but that’s the way it is.
The above statement will assume you want the means for three separate variables named “blood” “pressure” and “status”.
There are no variables in the data set named “blood” or “pressure” so you will get an error. There is a variable named “status”, but it’s something completely different, a variable telling if the subject is alive or dead.
Even if you don’t have a real codebook available, you should at a minimum start any analysis by doing a PROC CONTENTS so you have the correct variable names and types.
What about these errors I was talking about, though? Where will you see them?
LOOK AT YOUR SAS LOG!!
If you are using SAS Studio , it’s the second tab in the middle window, to the right of the tab that says CODE.
Click on that tab and if you have any SYNTAX errors, they will conveniently show up in red.
Also, if you are taking a course and want help from your professor or a classmate, the easiest way for them to help you is if you is to copy and paste your SAS log into an email, or even better, download it and send it as an attachment.
Just because you have no errors in the SAS log doesn’t mean everything is all good, but it’s always the first place you should look.
To get a table of blood pressure status, you may have typed something like
Proc freq data=sashelp.heart ;
Tables status ;
That will run without errors but it will give you a table that gives status as alive or dead, not blood pressure as high, normal or optimal.
PROC CONTENTS is a sort of “codebook light”. A real codebook should also include the mean, minimum, maximum and more for each variable. We’ll talk about that in the next post. Or, who knows, maybe I’ll finally finish talking about reading in JSON data.
Jan
2
Reading JSON data saved in a column and other SAS string function tricks
January 2, 2019 | Leave a Comment
Sometimes data changes shape and type over time. In my case, we had a game that was given away free as a demo. We saved the player’s game state – that is, the number of points they had, objects they had earned in the game, etc. as a JSON object. Happy Day! The game became popular. Schools started using it. We came out with a premium version with lots more activities, a bilingual Spanish-English version, a bilingual Lakota- English version. Life is good.

Once schools started using our games, they wanted data on how much students played, how many problems they answered. This is when life started to get complicated. We added more fields to the JSON object to show which activities they had completed and whether they had won.
Data for one person might look like this, or much, much longer.
“{“”points””:””8″”,””first_trade””:””false””,””first_visit””:””true””, “”has_wigwam””:””true””,””inventory””:””6,3,4,14″”,””inventory_position””:””[{\””left\””:0,\””top\””:0},{\””left\””:0,\””top\””:0},{\””left\””:0,\””top\””:0},{\””left\””:176,\””top\””:4},{\””left\””:-309,\””top\””:-254},{\””left\””:0,\””top\””:0},{\””left\””:619,\””top\””:-45},{\””left\””:0,\””top\””:0},{\””left\””:0,\””top\””:0},{\””left\””:0,\””top\””:0},{\””left\””:0,\””top\””:0},{\””left\””:0,\””top\””:0},{\””left\””:0,\””top\””:0},{\””left\””:0,\””top\””:0},{\””left\””:293,\””top\””:-44},{\””left\””:0,\””top\””:0},{\””left\””:0,\””top\””:0},{\””left\””:0,\””top\””:0},{\””left\””:0,\””top\””:0},{\””left\””:0,\””top\””:0},{\””left\””:0,\””top\””:0},{\””left\””:0,\””top\””:0}]””,””milestone””:””EarnPage””}”
The JSON engine didn’t work (not surprisingly)
I actually didn’t expect it would work because we didn’t actually have a JSON object but rather a JSON object converted to a string and saved in an SQL database. However, if something would only take a minute, I try it first
libname testmcb JSON fileref =reffile ;
Okay, so what now? We have a variable record length, the values we want might be in any column. It must be really difficult to figure out, right? Not really.
This next bit looks complicated but it actually took very little time to code. Before we get into the code, let’s talk about what I needed to do and why. The “why” is that I want to know how much kids played the games. There are three milestones – logging in, getting a wigwam and trading for items. However, some kids just liked playing the mini-games and they played A LOT without pausing to trade in their points. Also, you can’t just look at how many points they have because they may have traded some points for items. Fortunately, all items cost two points, so I need to compute points + (items in inventory/2).
- First, there were some records that did NOT start with points, they started with “milestone” because we were coding the JSON object one way and then we switched. (Pause to swear under my breath at people here.) So, I need to decide what type of record it was.
- Second, I want to read in those variables that are milestones in the game play. That is, is this their first time playing, did they get points, did they get a wigwam and did they trade for anything for their wigwam. I need to keep in mind that a variable might be coded 1 or true if the player passed that milestone and 0, false or null if not. (Pause for more swearing.)
- Third, I want to create Boolean variables that show whether or not a player passed a particular milestone.
- Fourth, find out the NUMBER of objects in the inventory.
- Fifth, divide the number in inventory by two and add to the points
This actually took me very little time. Let’s look at it bit by bit (ha ha).
The first line just assigns a file reference for where my text file is located.
FILENAME reffile '/home/annmaria.demars/data_analysis_examples/data2018/exceldata/mc_bilingualtest.txt';
Data mcb_json ;
INFILE reffile DLM="," LRECL = 1337 ;
*** READ IN FILE, VARIABLES ARE SEPARATED (DELIMITED) BY A COMMA. LENGTH OF THE RECORD IS 1,337 ;
INFORMAT first_trade $40. first_visit $40. has_wigwam $40. ;
INPUT firstcol $ 15-16 @@ ;
IF firstcol = '":' THEN INPUT @43 points $ first_trade $ first_visit $ has_wigwam $ ;
ELSE INPUT @15 points $ first_trade first_visit has_wigwam ;
***** READ IN THE VARIABLES FOR TRADING, FIRST VISIT AND WIGWAM AS CHARACTER WITH A LENGTH OF 40 ;
**** READ COLUMNS 15-16 AND STAY ON THAT LINE ;
**** IF THE VALUE IN COLUMNS 15-16 = “: THEN IT HAD MILESTONE AT THE BEGINNING;
***** THE VARIABLES WE WANT START AT COLUMN 43, OTHERWISE, THEY START AT COLUMN 15;
*** THESE ARE SEPARATED BY COMMAS SO WE CAN JUST LIST THE VARIABLE NAMES;
*** NOTE THAT I NEED TO SPECIFY THAT POINTS IS CHARACTER DATA SINCE IT’S NOT IN MY INFORMAT STATEMENT ;
IF INDEX(first_trade,"true") > 0 or index(first_trade,"1") > 0 then traded =0 ;
ELSE IF INDEX(first_trade,"false") or index(first_trade,"0") then traded =1 ;
IF INDEX(first_visit,"false") or index(first_visit,"0") then play_twice = 1 ;
ELSE IF INDEX(first_visit,"true") or index(first_visit,"null") or index(first_visit,"1") then play_twice = 0 ;
IF INDEX(has_wigwam,"true") then wigwam = 1 ;
ELSE IF INDEX(has_wigwam,"null") > 0 or index(has_wigwam,"0") > 0 then wigwam = 0 ;
*** ABOVE I JUST USE A FEW IF THEN STATEMENTS TO CREATE MY NEW VARIABLES ;
**** The INDEX function returns the position in the variable in the first argument where it finds the value in the second argument;
**** If the value isn’t found, it returns a value of 0 ;
This last step isn’t strictly necessary, except that it is. Here I do a cross-tabulation to make sure that all of the variables were assigned correctly and they were. For example, you can see that if the value of “has_wigwam” was 0 or null the wigwam variable was set to 0. If has_wigwam was equal to “true” the wigwam variable was set to 1.
PROC FREQ ;
TABLES traded*first_trade first_visit*play_twice wigwam*has_wigwam ;

This would have worked for the whole JSON object except for the commas in the inventory. If you look at just a piece of the data, you can see that after the variables denoting milestones there is a variable that is actually an array, separated by commas.
“first_visit””:””true””, “”has_wigwam””:””true””,””inventory””:””6,3,4,14″”,”
We’ll look at how to handle that in the next post.
Blogroll
- Andrew Gelman's statistics blog - is far more interesting than the name
- Biological research made interesting
- Interesting economics blog
- Love Stats Blog - How can you not love a market research blog with a name like that?
- Me, twitter - Thoughts on stats
- SAS Blog for the rest of us - Not as funny as some, but twice as smart. If this is for the rest of us, who are those other people?
- Simply Statistics, simply interesting
- Tech News that Doesn’t Suck
- The Endeavor -John D Cook - Another statistics blog