HNHacker News
TopNewBestAskShowJobs

ben509

4,046 karma · joined December 7, 2017

I'm an engineer presently working for Capital One Investing, prior work at AWS for the CloudHSM team, before that Novetta, and before that I did 6 years in the army.

I'm also working on the Tenet language; see https://tenet-lang.org/

Also at https://keybase.io/ben509

YdRK9Q3mIBRWsRBonHhJCsgLnurwJk9eHbw1Jg4wz9M

submissionscomments
ben509··on Google have declared Droidscript is malware
The writing style of the piece looks like a political mailer.

> The Google Play system has declared DroidScript is Malware and accused us of committing Ad Fraud! Needless to say, we are extremely upset and totally flabbergasted at this shocking allegation!

That kind of hyperbole sets off all my BS detectors.

As I go through the back and forth, DroidScript speculates this:

> Our main guess was that one of our users was experimenting with our AdMob ID after extracting it from our APK...

What I don't see is that they ever went back to the policies to check if that was legit. If it wasn't and you tell Google, "right, that was totally a feature but we've removed it," then, you just indicated that you deliberately implemented a feature that violated the terms of your agreement.

> How can they expect people to build organisations or businesses supported by advertising revenue, when they might be subject to this type of summary execution at any moment!

I agree that Google's communication with their customers is awful, but this is not a new problem: _you have to read your contract_. And that means get a lawyer to go over it and explain to you what it really means and not what you'd like it to mean.

ben509··on API versioning has no “right way” (2017)
The wrongest is when it's stuck in an irrelevant header, as in Accept: application/json;v=3

I'm sure that's specified somewhere, but it's a shamefully stupid specification, so don't follow it. Any sane person reading that is going to think you're accepting a specific version of JSON.

Also, if you must put versions be in a header, STOP with the nonsense of pretending things don't exist. Give us some freaking clue, return a 404 and explain that we're missing your stupid header, or that the planets haven't aligned, or whatever we're supposed to fix.

ben509··on The unreasonable effectiveness of print debugging
The worst is when you put print statements in and a bug goes away, and you realize there's some kind of instruction reordering bullshit at work.
ben509··on Microsoft says mandatory password changing is “ancient and obsolete” (2019)
I think that's the best approach.

My router had a random pre-generated password. It was a series of consonant vowel consonant atoms separated by numbers. That manages to be reasonably memorable and highly secure, and it's reasonably unlikely to land on something someone finds offensive.

ben509··on Microsoft says mandatory password changing is “ancient and obsolete” (2019)
> Microsoft employee Aaron Margosis said the requirement is an “ancient and obsolete mitigation of very low value.”

That kind of magical thinking is what got us mandatory password rotation in the first place.

Password rotation has a kernel of truth: automated credential rotation really works, and sometimes you need to force manual rotations to migrate to a newer hash algorithm, and I'll bring up another reason for it.

But the main reason we have password rotation is people have some magical belief that a credential gets "old" so we have to freshen it up.

Security rules are the same: they work, or they don't, and that can be very complicated due to human factors. But they don't "get old" and magically lose their effectiveness. If password rotation is broken, it's always been broken.

> Chief among them, the requirements encourage end users to choose weaker passwords than they otherwise would. A password that had been “P@$$w0rd1” becomes “P@$$w0rd2” and so on.

Not true. If they hadn't been forced to rotate, they would have stuck with P@$$w0rd1 the whole time, and P@$$w0rd2 is not weaker than that.

> At the same time, the mandatory changes provide little security benefit, since passwords should be changed immediately in the event of a real breach rather than after a set amount of time prescribed by a policy.

There is a clear benefit, especially for large enterprise systems: a periodic password change does put a limit on when the attacker could have used the password.

So when a credential is exploited, if you're rotating yearly, you only need to search back at most a year to figure out the scope of the breach.

I don't know how much of a benefit this is, in practice. Maybe someone who has done a real log dive can comment.

The only certainty is that you must never have passwords older than logs.

> If it’s a given that a password is likely to be stolen, how many days is an acceptable length of time to continue to allow the thief to use that stolen password?

They get this right.

ben509··on PEP 563, PEP 649 and the future of pydantic and FastAPI
I had tried to make json-syntax work with __annotations__, glad to know it's not just me having trouble with it.
ben509··on SQLite the only database you will ever need in most cases
After cleaning up some spilled toner, someone put a very indignant notice under the photocopier:

"It would be who of you to be cautious openening a new toner cartridge."

ben509··on Logica, a novel open-source logic programming language
Nope. I believe that's why ANSI SQL doesn't specify a boolean column type.
ben509··on Logica, a novel open-source logic programming language
> However I'd argue that just because you can express something in a language, doesn't mean it's the optimal way to express it.

I completely agree, and I may not have driven this point home, but because a relational system lets you have different views of the same data, you can have sum types in one view, while breaking them into relational structures in another view of the same data. We don't get that in SQL DBMSs because SQL isn't really relational.

> If you could design a relational system that's a touch more ergonomic, that doesn't require learning a mental model that feels a little foreign, maybe the NoSQL options will be a lot less appealing.

What's could be ergonomic about a strongly system is that it can guarantee that if I pull a record from the database, it has exactly what types it says it does, so my code knows what it's dealing with. Even if I'm writing something in Python, I don't actually want to do a mess of instanceof checks.

I think what we want is to properly wire a DBMS into build tools. The production system should have everything strictly typed, presenting a clean API to consumers.

Meanwhile, a development branch should let you put whatever you want in there while you're experimenting, and then you lock it down before you promote your code to prod.

ben509··on Logica, a novel open-source logic programming language
So 2NF and 3NF are rules that aim to eliminate data redundancies. That's Kent's point: everything is a fact about a key.

I'm talking about a more basic idea of expressing structures that are accessible through relational operations, so joins, intersections, unions, etc. That's known as 1NF[1] and, as you might expect, it's a pre-requisite to 2NF and 3NF.

[1]: https://en.wikipedia.org/wiki/First_normal_form

ben509··on Logica, a novel open-source logic programming language
The relational model describes a relational algebra, which in turn specifies a "relation" (often called a table) to be a set of tuples (rows), and "relational operators" that accept and return relations. And the relational algebra is complete in the sense that it can express all queries expressible by predicate logic + types and changes through a small set of operations.

The relational model adds constraints, state, and a mechanism for first-class derived relations (updateable views).

And while you can stick anything with a well-defined equality in a relation, including other relations, the point of the relational algebra is to describe structure using relations, thus making it all accessible to relational operators. In a properly normalized database, all structure can be manipulated through a common set of operations.

So you could, e.g. create a relation with a single JSON attribute and call it a day. But now, in addition to the relational operators, you need a whole mess of JSON operators to query it.

Thus, while you could have a sum type, you don't need this because you can put the various summands into separate relations. For instance, the simple case of booleans:

    Persons(key id: int, name: str, is_tall: bool)
    ... noramlizes to ...
    Persons(key id: int, name: str)
    TallPersons(key id: int)
Or for an Either:

    Persons(key id: int, name: str, zing: either<int, str>)
    ... noramlizes to ...
    Persons(key id: int, name: str)
    LeftPersons(key id: int, zing: int)
    RightPersons(key id: int, zing: str)
    AssertEmpty: LeftPersons{key} & RightPersons{key}
What you really want your database to do is to let you enter that first "Persons" table with the sum type. That should logically be a derived table that is backed by the normalized tables.

Then, you'd get the simplicity of entering Persons.insert(key=5, name='bob', zing=Left(5)), but that's simply an updateable view. It will really update the base tables Persons / LeftPersons with simple atomic values.

ben509··on Downloading files from S3 with multithreading and Boto3
That issue is just botocore not supporting async, which aiobotocore addresses. It's also very long; is there a particular comment on that issue that you wanted to point out?
ben509··on Downloading files from S3 with multithreading and Boto3
Having used aiobotocore, it's pretty good. It can be a bit sketchy about releasing connection pools, though. Normally you shouldn't run into any issues, but we've had trouble with running out of filehandles on AWS Lambda.

I would also point out that for many cases, using a ThreadPoolExecutor works fine.

I maintain a simulation engine and it's distributing work out to AWS Lambda. So I had two distributors, one thread based and one async based. (Also one based on multiprocessing that runs work on a local machine.)

From my tests, the performance is basically equivalent, which is not surprising: most of it was just waiting and then processing incoming responses. Threads work great at this, and botocore is designed to work with threads.

I eventually went with async because Python doesn't let you prioritize threads. That means that if you get a "stop" signal, in the threaded model, the command thread is competing with many worker threads. In the async model, the workers are all in one thread, so the command thread will be woken up per the switch interval[1].

So, broadly, if you're going to need a command channel that must respond in a timely fashion, I'd recommend piling workers into an event loop through async.

The other possibility is to have a command channel run in another process, but then you need to get the fork right, do IPC, etc.

[1]: https://docs.python.org/3/library/sys.html#sys.setswitchinte...

ben509··on Downloading files from S3 with multithreading and Boto3
It is directly checking for s3 to s3[1] and indicates that it wants to copy...

I've read over it and I'm reasonably sure that it's going to issue CopyObject, but it would take me actually getting out paper and pen to really track it down.

The AWS CLI and Boto are a case study in overdoing class hierarchies. Not because there's any obvious AbstractSingletonProxyFactoryBean, but rather that there's no instance that stands out as "this is where they went wrong" and nevertheless the end result is a confusing mess of inheritance and objects.

[1]: https://github.com/aws/aws-cli/blob/45b0063b2d0b245b17a57fd9...

ben509··on You Don't Need a GUI
A UI presents a structure to enable the user to query and manipulate objects.

A CLI represents that structure by accepting textual commands and presenting output textually.

A GUI represents that structure by displaying objects graphically, showing their spatial representation and connection.

And, traditionally, a GUI tends to show more structure up front while a CLI simply prompts you for a command.

The distinction isn't perfect, but a text adventure game is well inside the CLI camp.

ben509··on You Don't Need a GUI
The game industry uses CLIs in text adventure games, besides all their development tools. Many games put out utilities to enhance thier games, some of which have CLIs.
ben509··on You Don't Need a GUI
Google has been around since 1998, and after 23 years, their search is still a CLI stuck in a form.

> Me, on the other hand, I can point you to a trillion dollar business that uses only GUI and not a single CLI, to say the least.

No you can't. There are 5 companies with a market cap over a trillion. We can easily rule out Apple, Microsoft, Amazon and Google as they have all developed CLIs.

That leaves Saudi Aramco. Doesn't take long to see they have openings for CLI heavy jobs.[1][2]

[1]: https://apply.aramco.jobs/us/jobs/1786333?lang=en-us

[2]: https://apply.aramco.jobs/us/jobs/1780310?lang=en-us

ben509··on A man is looking for the friends who shipped him overseas in a crate in 1965
Seemed like a crate idea at the time.
ben509··on Facebook Down?
Social media is a square wheel. Sure, it sort of goes and if you know no alternative, it might be better than no wheel at all. But there's no good way to use it because it's fundamentally flawed.
ben509··on Facebook Down?
Don't forget "The Same Photo of a Gravel Pile Every Day." Almost makes the decline of Western civilization worth it.
ben509··on Twitch will ban users for 'severe misconduct' that occurs away from its site
Especially when such critique is how we're supposed to resolve most disputes in a free society.
ben509··on Mark Zuckerberg's phone number appeared among the leaked data of Facebook users
From my read of it, it's completely independent. The same passwords frequently show up in other breaches.
ben509··on An Apology to COBOL: Maybe Old Technology Isn’t the Real Problem
No, you can discriminate on any basis if there's a "reasonable factor" unrelated to that basis. Models and actors, for example, are selected by age, race and sex quite routinely.
ben509··on HaveIBeenPwned adds yesterday's Facebook breach
How the hell did you find out my Facebook password?! Mark SUCKERberg is about to get a very angry comment from me!
ben509··on Egypt demands over $1B in damages after Suez Canal blockage
The Church would then refer them to Genesis 3:6, which led to the decision in Genesis 3:16-19, as that breach of covenant by mankind is the original cause of our continuing hardship. They'd then go ahead and cite all the additional breaches of covenant.
ben509··on Mark Zuckerberg's phone number appeared among the leaked data of Facebook users
There's a good discussion on this by Troy Hunt[1].

> But for spam based on using phone number alone, it's gold. Not just SMS, there are heaps of services that just require a phone number these days and now there's hundreds of millions of them conveniently categorised by country with nice mail merge fields like name and gender.[2]

> Another general observation on this incident: I'm seeing extensive sharing of the data, both the entire corpus of countries and individual country files. Not just in hacking circles, but very broadly on social media too. This data is everywhere already.[3]

> New breach: Facebook had 2.5M addresses exposed in an incident that impacted 533M subscribers' phone numbers. Most records contained name and gender, many also included DoB, location, relationship status and employer. 65% were already in @haveibeenpwned[4]

> If we look at the data, email is rare, DoB is rare so the greatest impact here is the phone numbers. Even though it’s “only” 20% of FB users, the number is obviously substantial thus so is the impact[5]

[1]: https://twitter.com/troyhunt

[2]: https://twitter.com/troyhunt/status/1378485999781613569

[3]: https://twitter.com/troyhunt/status/1378513457209696256

[4]: https://twitter.com/haveibeenpwned/status/137855490210063565...

[5]: https://twitter.com/troyhunt/status/1378474534760685568

ben509··on An HTTP server in a single .c file
It's often handy for browsing documentation you compiled locally.
ben509··on Microsoft Coffee
Yeah, someone with a sense of humor sees a bad/lame joke as something to riff on.

That's how dad jokes became a thing.

ben509··on AWS CloudFormation Best Practices
Not a great article. Most of the content is far better explained in the AWS docs.

To summarize their best practices:

* don't put creds in templates

* reference other parameters outside of the template, e.g. in Systems Manager Parameter Store

* make your code readable

* add comments

* check your code

Except for the second, all of those are fine practices for maintaining any code.

The one best practice that's actually relevant to CF is to store parameters in SSM. Yet, they mention that drift is a problem with CloudFormation. So... why do you want to store parameters to your stack in a service that allows them to change independently of the stack?

Maybe there's an argument for doing this, but they don't explain it. It's just a "best practice."

They don't mention a major use case for CF, namely CI/CD. The article finishes up with a pitch for their template designer.

ben509··on Golang: Know Your 'Nil'
I think nil/null is a symptom of the real issue: the language permits partially constructed data types, so it has to assign something.

That's a consequence of the "always mutable" model whereby the responsibility of initialization can be shared by the object constructor and the caller.

But there are many cases where it's very intuitive for the caller to set up an object, especially in the objects as actors model.

I think to make that work, you'd want to track the evolution of the object's state, especially noting when all fields have defined values.

← PreviousPage 2 of 34Next →