Hacker News new | past | comments | ask | show | jobs | submit | notpushkin's comments login

If it is what I think it is, it’s extremely neat. Parsing both HTML and templating syntax at the same time is way more robust than doing just the templating and hoping for the best.

I was thinking about something like this, but with some blend of Jinja2 / Twig / Nunjucks [1] syntax and Svelte/JSX-like use of variables in element attributes:

  {% for para in page.body %}
    <p class={{ para.class }} {{ **para.attrs }}>
      {{ para.text }}
    </p>
  {% endfor %}
---

[1]: the irony is not lost on me that I’m mentioning Python, PHP and JS template engines in a Ruby discussion :-) Liquid is the closest equivalent I think, but there was some crucial piece missing last time I had to use it, though I can’t remember what exactly.


This is something you could do with tree-sitter https://tree-sitter.github.io/tree-sitter/

I've been working with FastHTML and I have to say, I rather enjoy HTML-markup-as-objects.

It works pretty seamlessly and you get something like this:

    @app.post('/part/add')
    def create_part(part_number: str, name: str, description: str):
        p = Part(part_number=part_number, name=name, description=description)
        p.save()
        return (p,
            Input(placeholder="part number", id="part_number", hx_swap_oob='true'),
            Input(placeholder="description", id="description", hx_swap_oob='true'),
            Input(placeholder="name", id="name", hx_swap_oob='true'))
Note, I'm not using FastHTML's built-in database interface. I prefer a little less implicit than the strict FastHTML style.

Phoenix (Elixir) has a very elegant version of that, without the need for the extra indent:

  <p :for={para <- paras} class={para.class} {para.attrs}>
    {para.text}
  </p>
With :for being a list comprehension.

I was afraid at first this is the only option (which makes it difficult to generalize this to loops with body consisting of anything but a single element). But as an optional shorthand it is indeed pretty neat! (Personally though, I still like explicit “layering” of a separate `for` block a bit more.)

I’m not sure it’s targeted towards those not familiar with Ruby... though yeah, at least mentioning it’s a templating engine would make it a lot easier to grasp.

(ERB is, I think, “embedded Ruby”, and it functions basically like old school PHP: you just insert pieces of Ruby code wrapped by <% .. %> or <%= .. %>: https://github.com/ruby/erb#recognized-tags)


ERB is also the default templating language of Rails. I wish Django would use an embedded Python instead of the mutilated tool it uses in its own templates. Not only it's yet another language to learn, but it's also underpowered and it forces developers to define custom tags and filters where a call to a method of a plain Python object would be enough. Apparently they are afraid that people embed logic in the templates but I've seen db calls inside the Python code of the custom tags. There is no perfect defense.


Would be a nice touch if Squiggle supported the `a~b` syntax :^)

Ever so slightly easier to read (IMO) if you inline arguments:

    def hotp(key: bytes, counter: int, digits: int = 6, digest: Literal["sha1", "sha256", "sha512"] = "sha1"):
        mac = hmac.digest(
            key=base64.b32decode(key.upper() + "=" * ((8 - len(key)) % 8)),
            msg=struct.pack(">Q", counter),
            digest=digest,
        )
        offset = mac[-1] & 0x0F
        binary: int = struct.unpack(">L", mac[offset : offset + 4])[0] & 0x7FFFFFFF
        return str(binary)[-digits:].zfill(digits)
And Pyright doesn’t yell at this version because no type-changing variables here: https://basedpyright.com/?typeCheckingMode=all&code=JYWwDg9g...

---

This is actually really helpful. I’m using Pass [1], which requires oathtool for OTP support [2]. I’m currently on a Mac without admin rights (so no Homebrew for me), and compiling oathtool is a PITA. I’ve wanted to put together a pure Python replacement for a while now, but with this it can be a single-file script: https://gist.github.com/notpushkin/7ac32ddf35a0c73bc6f181a1b...

[1]: https://www.passwordstore.org/

[2]: https://github.com/tadfisher/pass-otp#requirements


I don’t think it has live streaming?

> Encryption (can work with sharing), signatures, fall back to CDN. Control is not an issue.

And of course if an encryption key gets leaked, you can just rotate it. Since it’s a stream, past content is not as important.

(That said, I don’t think it will help — any DRM can be cracked, and there’s plenty of online TV streaming sites even with the current centralized systems.)


you can stream blockbuster movie which got released yesterday. DRM is important.

> Also in some examples like Facebook's password recovery, this secret clock is not shared with the user directly but rather server's generated one-time password is sent via a trusted medium, such as an email to the user.

I’m pretty sure Facebook just makes up a random number and stores it?


Yes if you’re sending the number to the user, might as well just be random that’s a lot easier.

Clocks and secrets only needed if the user is providing a number generated on the remote side.


Good catch. In my mind storing that random number is similar to storing a plain-text password, thus I thought they were generating TOTPs. Let's hear from others how they implemented it.

So you are right that the random number becomes "password-like", but of course if you really care about that you don't need to store the exact random number, just as you don't have to store a raw password.

However, if your random login code is easily typable then it's usually drawn from a small enough keyspace that any such code is trivially brute-forceable. Like if it's decimal digits you need more than ten.

So in practice people just trust that you are on good terms with your email provider and anyone else with access to your email, and use other mechanisms to limit access to these codes from insiders.


What's the difference between storing a random number and storing the OTP secret? It's all ones and zeroes in a database

If you store the OTP secret in an HSM, then you can do the same when generating a random number. I'm not aware of anyone actually doing that though (I surely won't have seen even 1% of what's out there, but as a security consultant I get around at least a little bit)


It would be, but you could still store an expiration time, and limit the number of attempts to use the code. Considering you're probably sending it to the user insecurely anyway (via email or text message), that's probably safe enough.

> > storing that random number is similar to storing a plain-text password

> you could still store an expiration time, and limit the number of attempts to use the code

Storing plain-text passwords is bad because:

1. Users re-use passwords

2. An attacker can read the access token from the database (as with SQL injection) or capture it in transit (as on insecure connections) and log in directly (if that is still useful when having, e.g., SQL-injection-based database access)

I do not understand what threat limiting the number of attempts protects against. Even if you have that limit implemented on a hardware level, the attacker either knows the right code or can crack the hash if it's a hash of just a few digits. With something like PAKE you can protect against capturing in transit but on secure channels (e.g., if you already use TLS) that's typically overkill

(Of course, you absolutely need to have rate limiting on OTPs, but that is not to protect against the correct code being read straight from disk by the attacker; it's to protect from guessing the digits, a surprisingly common flaw)

> you're probably sending it to the user insecurely anyway (via email or text message)

(I kind of want to remark about this assumed insecurity: the user needs to be targeted for these to not be adequate. Attackers very rarely go after people to the point where they first compromise an email inbox and then look for your specific service, or drive up to the person with cell tower spoofing equipment. It surely happens in red teaming exercises, spy scenarios, if you have a stalker, and probably more, but it's not the common case. Anyway...)

I don't see how rate limiting and expiration helps against sending it via moderately-secure media either. This is necessarily plain text for random codes because the user would otherwise need a decryption key and then you're basically back at the TOTP scenario makes a difference for at-rest storage security. So with them being plain text, if someone is intercepting your SMSes or sitting in your inbox, they'll either manually trigger the code sending or wait for the legitimate user to do this and then log in. Similar to the previous bit: sure, the security of the transport method is relevant, but not for the security of token storage on the server


Thanks for all your insights, I have updated the post to outline this as a "theoretical" use-case rather than a practical one. I also revised it to include random number approach.

Perhaps you could also highlight how in usual TOTP implementations (“scan this code with your authenticator app”) there’s no channel to MITM? I think it’s one of the key pros of TOTP vs, say, SMS as a second factor.

I haven't mentioned MITM attacks in this article thoroughly. Can you give some examples on what authentication implementations carry a MITM risk?

I thought anything carried over SSL doesn't have a _significant_ MITM risk.


Not sure about emails (probably reasonably secure, I think most MTAs use TLS now).

For text message codes though, there’s plenty of attacks. In authoritarian regimes, government can monitor your text messages directly – I think some protestors in Belarus have lost their Telegram accounts due to this. There’s also the SIM swapping attack, where an attacker pretends to be you and ports out your number: https://en.wikipedia.org/wiki/SIM_swap_scam


I have to pull a number from Google Authenticator to log into my FB account so I can only assume they're not simply generating random numbers.

Two different flows, an online and an offline.

TOTP devices can be powered offline, which makes it extra secure, as you don't transfer any data around, possibility of leaking it is extremely low.

Random numbers could only work in online flow, where server sends you a one-time code using a secure communication method, such as a trusted phone number or email address.


But they’re not sending you this number via email.

Correct. Before they killed mbasic the prompt said they would text me a code, but in reality they were prompting for a TOTP code.

The number is random, so there's no need to worry about plain storage.

Personally, I find Zod’s API extremely intimidating. Anything more resembling TypeScript is way better. ArkType is neat, but ideally we’d have something like:

  export reflect type User = {
    id: number;
    username: string;
    // ...
  };
Edit: just remembered about this one: https://github.com/GoogleFeud/ts-runtime-checks

This is why I like libraries like typia or typebox-codegen; I'd prefer to write TypeScript and generate the validation, rather than write a DSL.

It's not perfect and doesn't cover all of zods functionality (iirc coercion) but I've used https://www.npmjs.com/package/ts-to-zod before to generate zod schemas directly from types.

Good luck finding Asfghjs Fghdjsk using only his email address, fdsfgsd@tempemail.test.

They use the billing address. KYC makes it easy.

Good luck finding Zyyzzyzx Balleyhew whose address on the temporary card is registered at PO Box 42069, Utqiagvik, AK

And you can just get a card with a fake adress?

No need. You can use services like privacy.com, whose generated cards will accept any address. Just pick a random valid one that you aren't connected to. Picking the address of a public park or library in another city can appease address verification checks.


Those don’t have a fake address. You still have to put the right name and billing to pass verification.

A prepaid Visa/MC/Amex gift card might work, but those are easily blockable. I’d expect Adobe to do so.


I mean, that’s one way of getting users to pirate your software and hate you at the same time.

Payment don't really check if address matches, they don't even check if account name matches with credit card name.

No, but you can type in any fake address in your zipcode. (Or – if your card is from outside US – you can type in a completely random address and generally it will work.)


I've always thought this should be first-class syntax in any language with lambdas

Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: