Apple: "What's a professional?"
Apple announced their new iPad Pro and I couldn’t care less. The hardware itself is brilliant, yet Apple insists on artificially limiting what you can do with it for reasons I don’t understand. A “pro” device would let me run Mac-style apps like Nova and a real local terminal. It would let me compile and run the software I write when Shortcuts scripting isn’t good enough. It would be more like a hyper-portable MacBook for doing things that don’t require a heavier and more powerful computer, and less like a giant iPhone that gives me free rein of a walled garden.
I bought a 2018 iPad Pro 13" when they were released and used it constantly. It was overpowered for the software available to run on it, to the point that my kid in college still uses it for classwork today. The hardware was never the limiting factor in what I could do with it. I finally replaced it last summer with a MacBook Air that’s worse for my wants and needs in every way but one: Apple’s OS for Macs lets me do the professional things that the as-powerful iPad can’t do. Apple ran an ad when that iPad Pro came out, asking “what’s a computer?” I wish Apple would ask themselves, “what’s a professional?”
My vision for the iPad doesn’t align with Apple’s. That’s OK. They know their target market. They’ll still sell a gazillion of these.
Just not to me.
You know how sometimes you come to decide that an entire niche market is so filled with awful and overpriced alternatives that you’d rather just write your own and give it away for free?
My toes are on the precipice.
Gigi turns 15 today. We’re celebrating with lots of cuddles and ancient dog appropriate treats.

Demand that car companies respect your privacy
How to escape Honda’s privacy hell:
With sensors, microphones, and cameras, cars collect way more data than needed to operate the vehicle. They also share and sell that information to third parties, something many Americans don’t realize they’re opting into when they buy these cars. Companies are quick to flaunt their privacy policies, but those amount to pages upon pages of legalese that leave even professionals stumped about what exactly car companies collect and where that information might go.
So what can they collect?
“Pretty much everything,” said Misha Rykov, a research associate at the Mozilla Foundation, who worked on the car-privacy report. “Sex-life data, biometric data, demographic, race, sexual orientation, gender — everything.”
That’s despicable. Shame on you, Honda. Mozilla’s privacy report says their competitors are all pretty bad, too.
If you live in a state with a privacy law, you can and should write to your car’s manufacturer and demand that they show you all the information they collect about you, that they delete it all, that they not share it with anyone else, and that they limit how they use your data only to provide the services you’ve requested from them. These are your legal rights and manufacturers are legally obligated to respect them, even if it’s inconvenient and expensive for them. In fact, I think it’s our duty as citizens to make it cost companies more to process millions of our opt-out requests than they make selling our personal information.
Previous lock picking sets having been sneaked out of my possession by various household children, I’ve now bought my own nice meant-to-be-permanent set that I’ll keep safely tucked away.

Very fancy electronic badges at BSidesSF this year.
Conference tracks where more than a few people are wearing khaki:
- Defending your AI assets
- Defending your assets from AI
- Defending your assets with AI
Additional conference tracks where more than a few people have primary colored hair:
- Prompt injection for lolz and cash
While I dropped a friend off and helped him unload his stuff, I told him about the Oakland Ballers cap I was wearing and how I’m glad we have a new local baseball team. Not 10 seconds after we’d finished talking about it, a woman on the sidewalk yelled “Go Ballers!” to me, and that started a new conversation with her about opening day, season tickets, the new ballpark renovations, and all that.
I think I’ve convinced my buddy that he should get tickets, too. 100% of the time he’s heard of the Ballers, they were so popular that complete strangers entered the chat.
My credit union called this morning: “Did you just make a purchase from OnlyFans?” Nope. Thus ends my longest recent streak of not having my debit card compromised. The security department said it looks like I’ve been the victim of a “BIN stuffing” attack where a criminal tries random combinations of card numbers, expiration dates, and CVV numbers until they get lucky. One day I may have a debit card that reaches the expiration date printed on it. Not this time, though.
I got the first “your credit card was declined” email from one of my monthly bills a few minutes later. This will be an irksome week.
Keeva wants pets.

The BASIC programming language turns 60 | Ars Technica
The BASIC programming language turns 60 | Ars Technica
Like so many others, I got my start typing in program listings for games, utilities, art projects, and all kinds of other things I found in magazines. Inevitably there’d be some small thing I wished a program would do differently, so I’d tweak and alter it — usually breaking things horrendously along the way — until I made it do what I wanted. That was an addictive rush of magical power.
While BASIC wasn’t a great language, I’ve never seen a programming environment more approachable an alluring than turning on a Commodore 64 and instantly seeing the word “READY.” and a blinking cursor waiting for me to give it instructions.
What sadist invented this captcha?

What's my Apple Card balance?
I spent 1 hour and 25 minutes on a call with Goldman Sachs about their mistakes on my Apple Card statement. It’s not resolved but I think we’re finally making progress.
I’m a stickler about reconciling my monthly account statements. My dad taught me how to balance a checkbook when I was a kid and I’m diligent about that. This was the first time I’ve ever been unable to make sense of a statement. The process normally looks like this:
- Start with last month’s balance.
- Subtract any money you paid toward that balance.
- Add any new transactions.
- Add any fees and interest.
- Compare the result to what the bank says your new closing balance is, and if it’s not an exact match, go back to the beginning until you find the missing piece.
Last month’s Apple Card statement worked like that. So did the month before that. And the month before that, all the way back 5 years. This month they threw a twist:
- Start with last month’s balance, $1000.001.
- Subtract the $500.00 payment I made.
- Add $100.00 in new transactions.
- Add $50 in fees and interest.
- My arithmetic came out to a new balance of $650. Goldman Sachs computed my new balance as $425.
However I juggled the numbers, I couldn’t reproduce their result. I gave up and contacted the support chat. That was useless. The conversation went like this:
Me: There’s a problem with my statement.
Them: Your balance is $425! Is there anything else I can help you with? disconnect
Me: reconnecting There’s a problem with my statement.
Them: Oh no! It looks like that’s $425. Have a nice day! disconnect
I asked them to escalate, which resulted in someone sending me an email like:
Here’s how we resolved your case: Start with $1000.00. Now, the moon weighs more than a duck, so carry the 5 and you get $893. Add the length of the Titanic and subtract purple. That’s $425. Share and enjoy!
Today I called them and repeated “talk to a human” into the phone tree until it connected me to a person. This time I got to explain my situation to a sentient being, who went off to repeat my calculations before uttering those magic tech support words: “huh, that’s strange.” It sure is! The agent was able to reproduce my math and couldn’t figure out how to compute Goldman Sachs’s balance. I can’t exaggerate the relief I felt. I’m not alone. It’s not my imagination or inability to add a few numbers together.
Although we haven’t fixed the problem, a thinking person wrote up my problem and opened an official inquiry for me. I’m optimistic.
And don’t waste your time on Apple Card’s online chat. Nothing good comes from it.
-
All numbers are fictional for storytelling purposes. ↩︎
Today’s first software update for the Rabbit r1 adds missing keys to its on-screen keyboard, and now I can type in our Wi-Fi password. That’s a nice fix!
Next up: Make it trust its own GPS instead of IP geolocation so that it doesn’t think we’re 50 miles away from here. That wreaks havoc on its weather reports.
Drug Scheduling
On the subject of Drug Scheduling:
Schedule IV
Schedule IV drugs, substances, or chemicals are defined as drugs with a low potential for abuse and low risk of dependence. Some examples of Schedule IV drugs are: Xanax, Soma, Darvon, Darvocet, Valium, Ativan, Talwin, Ambien, Tramadol
So the devil’s lettuce is currently Schedule I with "a high potential for abuse”, but Xanax and Valium are not. Got it. That tells you what you need to know about the DEA’s evaluation processes.
US will reclassify marijuana in historic shift: AP sources | AP News
US will reclassify marijuana in historic shift: AP sources | AP News:
Once OMB signs off, the DEA will take public comment on the plan to move marijuana from its current classification as a Schedule I drug, alongside heroin and LSD. It moves pot to Schedule III, alongside ketamine and some anabolic steroids, following a recommendation from the federal Health and Human Services Department. After the public-comment period the agency would publish the final rule.
That’s fantastic news! It’s ludicrous that weed was ever Schedule I, i.e. “with no currently accepted medical use and a high potential for abuse”, when alcohol isn’t. I can’t think of a single criterion by which marijuana is worse for users or for society than America’s current favorite drug of choice.
My Rabbit R1 just arrived. I haven’t played with it enough yet to have an opinion on the software’s usability. The hardware itself is nice, though. Photos can’t accurately convey how very orange! the thing is. It just about glows in the dark.
I wish OmniFocus used perspectives in Forecast
I wish OmniFocus would replace the way its Forecast view selects items to display with a user-selectable perspective. Then I could make my own choices about what to include, and OmniFocus would display those items in its handy integrated view alongside calendar events.
I can’t make those choices today. For example, the Forecast view doesn’t allow me to include actions that have a defer date in the past. That is, once an action is past its “start date” and available to be worked on, it no longer shows up on Forecast’s Today tab, or even in the Past tab. This is all the configuration available to decide what the Forecast view should show:

That’s one place I think Things is better than OmniFocus: If I have an action like “pay the rent (after the 20th of the month)”, the Things Today view will still show that action as something I could and should be doing on the 22nd of the month.
Purists might argue that I’m using OmniFocus wrong. I shouldn’t be leaning on the Forecast view at all, but should be regularly checking my tags and projects to see what I should be doing. That workflow isn’t the right fit for me. I know. I’ve tried it many times. What does work is a nice Today view that shows all my available scheduled actions in one place, along with actions I’ve tagged with “Today” during a review. I have a personal items perspective like that which ends up looking much like Things if I squint at it the right way:

Notice that the Forecast configuration looks an awful lot like a pared-down version of a regular perspective. If I had a magic wand to wave, I’d remove the “Items” checkboxes from the “In Forecast, include” and “Today includes” sections and replace them with the name of the perspective that would select all the items I wanted to show on the Forecast. Ta-da, done. Then I could customize the Forecast to make it perfect for my own needs. Others could make their own perspective, or use a default that OmniGroup could include to emulate the current behavior. Alternatively, a perspective could gain a “Display as Forecast” checkbox where I could have multiple Forecasts, each with its own filtered view of items. Tell me a separate “Personal Forecast” and “Work Forecast” view doesn’t sound nice. Imagine that you could associate each one with the appropriate focus filter so that they show up automatically when you’re doing personal or work things on your computer. The heart flutters!
Please consider this, Omni Group. OmniFocus is powerfully customizable in so many ways! I’d be delighted if this one last set-in-stone limitation were removed.
Palo Alto's exploited Python code
watchTowr Labs has a nice blog post dissecting CVE-2024-3400. It’s very readable. Go check it out.
The awfulness of Palo Alto’s Python code in this snippet stood out to me:
def some_function():
...
if source_ip_str is not None and source_ip_str != "":
curl_cmd = "/usr/bin/curl -v -H \"Content-Type: application/octet-stream\" -X PUT \"%s\" --data-binary @%s --capath %s --interface %s" \
%(signedUrl, fname, capath, source_ip_str)
else:
curl_cmd = "/usr/bin/curl -v -H \"Content-Type: application/octet-stream\" -X PUT \"%s\" --data-binary @%s --capath %s" \
%(signedUrl, fname, capath)
if dbg:
logger.info("S2: XFILE: send_file: curl cmd: '%s'" %curl_cmd)
stat, rsp, err, pid = pansys(curl_cmd, shell=True, timeout=250)
...
def dosys(self, command, close_fds=True, shell=False, timeout=30, first_wait=None):
"""call shell-command and either return its output or kill it
if it doesn't normally exit within timeout seconds"""
# Define dosys specific constants here
PANSYS_POST_SIGKILL_RETRY_COUNT = 5
# how long to pause between poll-readline-readline cycles
PANSYS_DOSYS_PAUSE = 0.1
# Use first_wait if time to complete is lengthy and can be estimated
if first_wait == None:
first_wait = PANSYS_DOSYS_PAUSE
# restrict the maximum possible dosys timeout
PANSYS_DOSYS_MAX_TIMEOUT = 23 * 60 * 60
# Can support upto 2GB per stream
out = StringIO()
err = StringIO()
try:
if shell:
cmd = command
else:
cmd = command.split()
except AttributeError: cmd = command
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, bufsize=1, shell=shell,
stderr=subprocess.PIPE, close_fds=close_fds, universal_newlines=True)
timer = pansys_timer(timeout, PANSYS_DOSYS_MAX_TIMEOUT)
It uses string building to create a curl
command line. Then it passes that command line down into a function that calls subprocess.Popen(cmd_line, shell=True)
. What? No! Don’t ever do that!
I fed that code into the open source bandit static analyzer. It flagged this code with a high severity, high confidence finding:
ᐅ bandit pan.py
[main] INFO profile include tests: None
[main] INFO profile exclude tests: None
[main] INFO cli include tests: None
[main] INFO cli exclude tests: None
[main] INFO running on Python 3.12.1
Run started:2024-04-16 17:14:52.240258
Test results:
>> Issue: [B604:any_other_function_with_shell_equals_true] Function call with shell=True parameter identified, possible security issue.
Severity: Medium Confidence: Low
CWE: CWE-78 (https://cwe.mitre.org/data/definitions/78.html)
More Info: https://bandit.readthedocs.io/en/1.7.8/plugins/b604_any_other_function_with_shell_equals_true.html
Location: ./pan.py:14:26
13 logger.info("S2: XFILE: send_file: curl cmd: '%s'" % curl_cmd)
14 stat, rsp, err, pid = pansys(curl_cmd, shell=True, timeout=250)
15
--------------------------------------------------
>> Issue: [B602:subprocess_popen_with_shell_equals_true] subprocess call with shell=True identified, security issue.
Severity: High Confidence: High
CWE: CWE-78 (https://cwe.mitre.org/data/definitions/78.html)
More Info: https://bandit.readthedocs.io/en/1.7.8/plugins/b602_subprocess_popen_with_shell_equals_true.html
Location: ./pan.py:49:8
48 bufsize=1,
49 shell=shell,
50 stderr=subprocess.PIPE,
51 close_fds=close_fds,
52 universal_newlines=True,
53 )
54 timer = pansys_timer(timeout, PANSYS_DOSYS_MAX_TIMEOUT)
--------------------------------------------------
Code scanned:
Total lines of code: 41
Total lines skipped (#nosec): 0
Run metrics:
Total issues (by severity):
Undefined: 0
Low: 0
Medium: 1
High: 1
Total issues (by confidence):
Undefined: 0
Low: 1
Medium: 0
High: 1
Files skipped (0):
From that we can infer that Palo Alto does not use effective static analysis on their Python code. If they did, this code would not have made it to production.
I fought State Farm (and won)
State Farm claimed we owed them money. I said we didn’t. They pursued it. I countered. They ended up owing us money instead.
My wife’s small business purchased our unemployment insurance through State Farm until we sold the company a couple years ago. Unemployment insurance premiums are proportional to your payroll: you pay the insurer a certain percentage of each dollar you pay your employees. When you cancel a policy, you reconcile your payroll numbers with them to settle up one last time.
State Farm said they estimated we’d been paying our employees $100,000 a year1. Therefore, by their reckoning, we owed them another $1,000 in additional premiums as if we’d paid out $100,000 in payroll that final year, even though we sold the business in May. They sent me an audit form to complete if we wanted to use our true numbers instead of their estimate. I submitted their form and promptly forgot all about it.
6 months later I got an email from our insurance agent saying that we still owed State Farm $1,000. I replied that we did not and that they needed to recompute our supposed debt using the real numbers that I’d submitted to the audit.
We had the same interaction about 6 months later, then again another 6 months after that. State Farm claimed they’d sent us all the information in writing. We found that they’d been sending letters to the old office that we’d lost access to on the day we sold the business, and the new owner never bothered forwarding them to us. Regardless, I wasn’t about to pay them the $1,000.
I got a more urgent email from our agent toward the end of last year. State Farm wanted their money and were turning our account over to a bill collector if we didn’t pay it. I replied and made our position clear: if State Farm would put it in writing that they had computed our amount due based on our real payroll numbers, and if they mailed that to us at our current home address and not the old business address we weren’t at anymore, only then would I pay them.
Again, silence.
A couple months ago I got a call from a bill collector. He was OK to talk to. I told him his customer was smoking crack and he laughed. Then I repeated our demands: I wanted State Farm to give us an itemized invoice showing their accurate calculations, and I wanted it sent to our house. I promised him that if both happened, I’d cheerfully make arrangements to pay the invoice in full immediately. He said that was reasonable. We parted ways.
However, I’d run out of patience. I filed a formal complaint with California’s Department of Insurance explaining our side of the conversation, asking them to rule on our behalf, and loading them with evidence proving our argument.
2 weeks later, the Department of Insurance replied saying that we needed to appeal the dispute through State Farm’s internal process before involving the state. Their letter contained details about the precise person we needed to contact and the legal jargon to use.
I did that. I got a response from that person yesterday. Their letter contained the itemized calculations I’d asked for all along, a final ruling that State Farm owes us $200, and a promise to mail a refund check to our correct address by the end of the week.
It took 2 years for State Farm to straighten out their math. They could have offered to write off our “debt” a year ago and stop pestering us. I would have accepted that. Instead, they kept it up and lost.
Yay me!
If that check isn’t here in the next few days, I have the number of a bill collector I might hire.
-
All numbers are fictional for storytelling purposes. ↩︎