HNHacker News
TopNewBestAskShowJobs

bradleyjkemp

279 karma · joined December 21, 2017

Building <https://phish.report>

[ my public key: https://keybase.io/bradleyjkemp; my proof: https://keybase.io/bradleyjkemp/sigs/KwwyqILJIyQV_L29WmWq8humB4VZlXA8abkWbzBNNm0 ]

submissionscomments
bradleyjkemp··on Show HN: Hashing Go Functions Using SSA and Scalar Evolution
I'd like to see some examples of before/after code samples which have the same hash.

I can see this will be tolerant of simple renames, but seems unlikely this hash will survive any real refactor of code

bradleyjkemp··on You can now directly sync Postgres with Redis
I believe this is another case of abusing GitHub for visibility, not actually doing anything meaningful open source

The code in the repo just seems to be connection code ("provides a way for anybody to test our Redis synchronization service on demand") rather than the sync service itself

bradleyjkemp··on MapTCHA, the open-source CAPTCHA that improves OpenStreetMap [video]
Oh some of them definitely use a real reCAPTCHA, hCAPTCHA, or Turnstile widget. It actually useful sometimes to track the same API key being used across multiple different domains

But yeah, I wouldn't even know where to report those API keys for abuse

bradleyjkemp··on MapTCHA, the open-source CAPTCHA that improves OpenStreetMap [video]
It's really common now for phishing kits to use interstitial pages that require solving a captcha before the actual phishing content is shown

Victims just click through the captcha without thinking, but it makes automatic verdicting by security scanners a pain because they just see a captcha page: can't tell the brand being impersonated, or even if it's a phishing site

I wrote a post about a number of these which actually pretend to be Cloudflare! https://phish.report/blog/fake-cloudflare-interstitials

bradleyjkemp··on Understanding the BM25 full text search algorithm
A typo I think, should be BM25F. From Wikipedia:

> BM25F (or the BM25 model with Extension to Multiple Weighted Fields) is a modification of BM25 in which the document is considered to be composed from several fields (such as headlines, main text, anchor text) https://en.wikipedia.org/wiki/Okapi_BM25

Some papers are linked in the references

bradleyjkemp··on Show HN: MicroSCOPE – identify ransomware statically with heuristics
Cool! Have you run this against a corpus of known ransomware samples to see how well it performs?
bradleyjkemp··on We were not accepted into Google Summer of Code. So, we started our own
Appears the blogpost text is from a LinkedIn post (where the hashtags are clickable): https://www.linkedin.com/posts/zayarni_qdrant-summer-of-code...

Nothing more interesting than copy-paste I'm afraid

bradleyjkemp··on How I run my servers (2022)
If you've got a load balancer (like Caddy) in front of your pods you can configure it to hold requests while the new pod comes up: https://twitter.com/bradleyjkemp/status/1486756361845329927

It's not perfect but it means rather than getting connection errors, browsers will just spin for a couple seconds.

The same technique is used by https://mrsk.dev/

bradleyjkemp··on Doctree
May want to double check that: domain data shows it was only registered today about an hour ago: https://client.rdap.org/?type=domain&object=doctree.dev

It was definitely available to purchase when I commented

bradleyjkemp··on Doctree
And it's not just DNS issues. The domain doesn't even seem to be registered: it's available for purchase...

edit: No longer! Hopefully someone benevolent picked it up

bradleyjkemp··on Show HN: Prevent your computer sleeping with just a webpage
Ah neat, yeah that's exactly what I need, thanks!
bradleyjkemp··on Show HN: Prevent your computer sleeping with just a webpage
Oh, 100% I need some more docs on the page: it's definitely not foolproof.

From my testing, it works even if the window is in the background somewhere but generally it stops working if you switch to a different tab within the same window.

You should get a popup though if you do something that causes the page to lose its Wake Lock (which works by listening to the release event: https://developer.mozilla.org/en-US/docs/Web/API/Screen_Wake...)

bradleyjkemp··on Show HN: Prevent your computer sleeping with just a webpage
Yup, that's my bad CSS I'm afraid. https://bulma.io explicitly resets the color of <a> tags inside a hero, so I need to figure out how to stop/override that
bradleyjkemp··on 7-Zip up to 21.07 on Windows allows privilege escalation and command execution
I think this is "zero day" in the sense of no patch is available, not in the sense of skipping responsible disclosure.

This has a CVE number allocated (CVE-2022-29072) and the README mentions 7-zip disputing that this is their problem (rather, some underlying Windows component).

bradleyjkemp··on Are you building features for phishers?
Good sentiment but so so tricky to get the wording right. You've got to write a sentence so perfect the fraudster can't pervert it or persuade the victim to ignore it.

For your example, the fraudster could say "yes, your account is being targeted by criminals, that's why I'm calling you". The warning inadvertently backs up their story

bradleyjkemp··on Are you building features for phishers?
Defense in depth is a worthy goal though

You'll never get 100% of people remembering that advice 100% of the time. So how do you mitigate the situation when they forget?

bradleyjkemp··on Show HN: Stixify – Turn unstructured data into structured threat intelligence
2FA included in the free tier and there's even a 10% discount on the paid tiers if 2FA is enabled!

That's an incredibly cool and generous offer

bradleyjkemp··on Ask HN: Companies of one, what is your tech stack?
My principle for https://phish.report (a tool for semi-automating the reporting of phishing sites) is: do as much statically or server side rendered as possible.

Deployment: Docker Compose. It's great to just set a DOCKER_HOST environment variable and I can deploy to any server with Docker installed.

Backend: a Go service. Could be any language really but that's what I know. Just takes requests, does some business logic and returns HTML templates.

Frontend: I'm not a frontend dev so I try to avoid it as much as possible. For UI, I use Bulma (a pretty comprehensive bunch of CSS components), with a tiny sprinkling of vanilla JS for small client-side animations (e.g. burger menu toggles). For any user action that hits the backend, I use https://htmx.org/ and just return a small HTML snippet as the API response. No point using client-side JS for that (no latency gains and makes the tech stack less homogenous).

bradleyjkemp··on View your browser's TLS fingerprint
Similar: https://ja3er.com/ which is formed by taking a bunch of (stable) attributes from your TLS handshake, appending them into a string, and hashing it.

They've also done the correlation with User Agent and it's surprisingly accurate.

Original post by Salesforce security team: https://engineering.salesforce.com/tls-fingerprinting-with-j...

bradleyjkemp··on Show HN: Phish.Report – a shortcut to report phishing wherever it's hosted
I report a lot of phishing sites but it gets very annoying very quickly. As well as reporting to SafeBrowsing, etc. for each site you also need to look up the domain registrar and hosting provider (via WHOIS) and email them.

Rather than do this manually every time, I wrote a small CLI to automate the lookups and even open pre-templated emails: https://github.com/bradleyjkemp/abwhose

I'm now redoing this as a web app so that I can do the entire reporting process without leaving the browser: https://phish.report

Kinda fun trying to "speedrun" the process down to as few clicks as possible. And I'm pretty pleased with how fast I've gotten the process.

Now I'm looking to add some more account/user features e.g. a history of sites you've submitted. Perhaps some stats on how many times you've been the first to report a given site.

bradleyjkemp··on Ask HN: Tools you have made for yourself?
As part of my job, I report a lot of phishing sites. This gets very annoying very quickly.

As well as reporting to SafeBrowsing, etc. for each site you also need to look up the domain registrar and hosting provider (via WHOIS) and email them.

Rather than do this manually every time, I wrote a small CLI to automate the lookups and even open pre-templated emails: https://github.com/bradleyjkemp/abwhose

I'm now redoing this as a web app so that I can do the entire reporting process without leaving the browser: https://phish.report

Kinda fun trying to "speedrun" the process down to as few clicks as possible.

bradleyjkemp··on Show HN: View plaintext passwords on GitHub Gists
Neat! I really like the crowdsourcing element where you can easily comment on the gist to make the author aware.

Would something like https://github.com/Yelp/detect-secrets be interesting to include? Either as a filtering step to weed out false positives or to find even more secrets (i.e. that aren't near "password" or "secret")

bradleyjkemp··on Simple A/B testing with Caddy and Plausible Analytics
Ouch, you're right. Thanks for the heads up!

Indeed, on fast connections the request to Plausible gets cancelled before it can be completed. I've updated my code to use that `setTimeout` trick.

`navigator.sendBeacon` support would be amazing! I really like how simple Plausible has been to set up (having never really used analytics before) so removing even more pitfalls/hurdles would be cool

bradleyjkemp··on Show HN: QueryCal – calculate metrics from your calendars using SQL
Does your company let you share your calendar privately via an iCal URL? That's the only method of adding your calendar to QueryCal at the moment anyway but is also more likely to work with corporate restrictions (i.e. because it isn't an OAuth app that needs to be approved)

OAuth + calendar plugins are definitely on the roadmap though because it's a much nicer UX than having to dig around in calendar sharing menus

bradleyjkemp··on Show HN: QueryCal – calculate metrics from your calendars using SQL
It was just a placeholder button I'm afraid :/ I've removed the buttons now to avoid confusion.

I'm planning to have a little SQL client on the homepage you can use to query against demo data (maybe the public holidays calendars from Google?) but I didn't get around to it yet.

It's a bit of a fun challenge locking it down: purposely putting unauthenticated SQLi on your homepage isn't usually recommended!

bradleyjkemp··on Show HN: QueryCal – calculate metrics from your calendars using SQL
I'm planning on a Stripe-style approach where each user (perhaps even each access token) can choose which version of the database schema they want to query.

I don't have any worries about managing long-term schema migrations though because the per-user databases get blown away and reconstructed every time the calendars are refreshed.

At the moment there's just an `events` table but I might handle migrations by having: `events_v1`, `events_v2`, etc. and just have `events` be an SQL view onto the version you chose.

Managing as little persistent state myself was a specific goal so this project is perfect because apart from some authentication info and a list of iCal URLs, the source of truth for your calendar is always with Google/Microsoft/etc.

bradleyjkemp··on Show HN: QueryCal – calculate metrics from your calendars using SQL
Interesting, hadn't seen the virtual table feature of SQLite. I'd have to do some benchmarking but that could be worth switching to in future for perhaps getting fresher data.

Yes, at the moment there's a batch job to download your calendars and convert them into a SQLite DB. Then, all queries are done directly on that concrete DB (read only).

Originally I was using https://github.com/dolthub/go-mysql-server which is quite similar to the virtual table feature (you just provide a struct which implements some getter methods). Unfortunately I found it a bit slow though (it had to call back into my table many times for even simple queries). Might just be a problem with that implementation and not a limitation of virtual tables themselves so thanks for pointing it out!

bradleyjkemp··on Show HN: QueryCal – calculate metrics from your calendars using SQL
Absolutely! A starting point would be something like this to calculate total busy time per day: SELECT sum(end - start) from events group by JULIANDAY(start) Some extra aggregation and you could totally calculate your busy/free ratio

This is one of the queries I'm using to track a rolling average of how many times a week I've been cycling: WITH recursive dates(day) AS ( SELECT date($__unixepochfrom(), 'unixepoch') UNION ALL SELECT date(day, '+1 DAY') FROM dates WHERE day<date($__unixepochto(), 'unixepoch') ) SELECT day AS time, ( SELECT count(DISTINCT julianday(start)) FROM events WHERE summary = " Cycling" AND start <= date(day, '+1 DAY') AND start > date(day, '-7 DAY')) AS cycling, FROM dates ORDER BY day DESC

And yeah 100% admit the documentation is lacking. I'll be honest, I got to the 3 week mark of building and decided I need to validate the idea before putting any more work in. Going to be adding some more pre-done queries like this as inspiration.

bradleyjkemp··on Show HN: QueryCal – calculate metrics from your calendars using SQL
Hey HN, I built this project because last year I did a terrible job of actually taking time off work and needed a way to see just how overdue I was to take a day off.

Because so much is already automatically tracked in my calendar (e.g. the HR system adds calendar events for booked holiday), I just needed a way to query it to get the metrics I wanted.

Originally I used a Go MySQL implementation to evaluate queries but it was a bit buggy and didn’t support all the SQL I wanted. Now I’m using a full SQLite database for each user so you can really do some gnarly queries (recursive CTEs, window functions, the works).

Personally, I’m using QueryCal as a Grafana datasource to power a dashboard that’s displayed on an old Kindle on my desk (using this great project: https://github.com/pascalw/kindle-dash).

bradleyjkemp··on Show HN: gRPC-Dump, a gRPC/gRPC-Web Debugging Proxy
I find debugging gRPC requests can be a pain because debugging proxies like Fiddler/Charles don’t natively understand gRPC. So I built grpc-dump to try and make this easier by doing interception at the gRPC level rather than the HTTP level.

Without requiring any client/server changes, grpc-dump transparently intercepts traffic on your machine and logs a JSON stream of all gRPC(-Web) requests that are made. This stream/dump is already useful for debugging but I’ve also started adding tools like grpc-fixture which uses this dump and responds to future client requests with the saved server responses from the dump.