Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

What? Would you rather have JSON as a string or as something like Map<string, JsonValue>?

> No, if your idea of validating an email is more complicated than "should have an @ symbol"

Then how is just using a string any better? Would you rather litter the entire codebase with validations that this is indeed a valid email or just do it once at the entry point?

I think excessive type system hacks are bad too but they are more often than not the problem of the language where its unable to express certain concepts naturally (see C++ template hacks).



> What? Would you rather have JSON as a string or as something like Map<string, JsonValue>?

This question can't be answered without additional context. What are the requirements?

But as a heads up, Map<string, JsonValue> couldn't be representation of all valid JSON documents. Lists are valid Json as well AFAIK. So I think this is making a point.


Based on the casing JsonValue is an object, not a primitive, so there's no reason that interface wouldn't work. It would just by a different subtype depending on what type the value is, and lists/dicts would also implement the Map<string, JsonValue> interface.


As much as I can just happily ignore JSON because I don't do webdev, I think there is a strong case to make that lists should be implemented using a native list, array, or vector class. But I won't argue because it's not necessary. The possibility for argument already proves my point.

My point is to show that "the type system" provides endless rabbit holes, and often is just a waste of time. There are a lot of situations where you want to represent a JSON document as a string. (Trivial example, as an embedding in an HTTP response object).


> The possibility for argument already proves my point.

Was just correcting something wrong:

> But as a heads up, Map<string, JsonValue> couldn't be representation of all valid JSON documents.

So,

> As much as I can just happily ignore JSON because I don't do webdev

I think this is why you're going wrong here. JSON is pretty much a solved problem, and Map<string, JsonValue> is pretty close to how it's used in Java and other languages that don't have native types that match its structure (like javascript and python do).

> (Trivial example, as an embedding in an HTTP response object)

This isn't json, it's what you get when you stringify/dumps/convert the json into a different datatype. When you need to be specific it's often called a "json string".


JSON is often interpreted as dictionary but is serialized as key-value pairs, for JSON itself this is not a big problem as everybody agrees not to produce JSON documents like {"a":1,"b":2,"a":3} so most people do not care about how their parser reads them.

In cases like URL queries or HTTP headers it is not such a clear cut. There it is common both to use duplicated keys and to use JSON-like dictionaries to read them.

Personally I never had bugs due to this: PHP does the "right" thing with duplicated keys and I never encountered it in node, but it bugs me that we use this kind of lossy[0] representations.

[0] in JS in particular the object are not really adequate to be used as dictionaries, inheritance and predefined keys aside there are also special magical attributes that behave in special ways Object.getPrototypeOf(Object.assign({}, JSON.parse('{"__proto__":null}')))===null;


JSON is a data-interchange format, i.e. a specification how to serialize and deserialize a domain of values. So Map<string, JsonValue> "isn't JSON" either.

JSON isn't a solved problem, it's a solution to a problem (and often used as a non-solution to a non-problem).

But none of that was my point.


> Would you rather litter the entire codebase with validations that this is indeed a valid email

Why would you? Just use it. For most of parts of the program it's not relevant to the computation whether the string is a "valid email", whatever that means. It's a string.


"Just use it" is what lead to the big SQL injection fallout and even today we pay the price as not even a year ago thousands of crucial service were vulnerable via log4j because of the "Just Use It" mantra.


You don't understand what I said.

I say, don't make assumptions unless you need them. Formatting an email address in an HTML document would work by wrapping it in the appropriate tag. (which implies html-quoting it correctly, but that is unrelated to email syntax).

Sending an email using an API would work by passing the email as a string to the API.

Looking up an email address from an address book using a pattern to match would be implemented with normal text search.

It doesn't matter if the email is "valid" or not. Don't overthink it.


SQL injection, XSS, and similar attacks are about incorrectly encoding embedded fragments.

The solution is either not to embed (SQL parameter bindings) or to always escape embedded fragments based on the embedding context

For reference: The Last XSS Defense Talk - Jim Manico - NDC Porto 2022 | https://youtu.be/wRC7jyhTkEM


You don't avoid injection attacks by validation, but by escaping.


escaping requires validation. You don't know what to escape if you aren't allowed to validate.


You don't know what you're talking about. For example, HTML escaping (a.k.a quoting) rules don't care what you're escaping - an email, a street name. It's just text.

And that's the point of it. You quote precisely because the container syntax doesn't know the syntax of what you're embedding. If it knew, there would be no need of the escaping.

It's called abstraction.


HTML escaping requires you to look for characters to escape for it to not interfere with HTML. This is quite literally validating symbols in the input. If they fail validation they need to be escaped. It's literally IMPOSSIBLE to do escaping without first validating every single symbol in the input.


So you're "validating" symbols now (strange choice of word). But certainly validating that the higher-level construct that we're escaping is an email address. Because the escaping procedure doesn't care.


Validating is just the process of ensuring an input is admissible in the way you want to use it. That can be symbols in a string, whether a string is an e-mail or even if a number is in a certain range. Escaping is just validation + fixup which can be used in some cases. Anyway the only way to validate an e-mail in practice is to use it and confirm.


> Escaping is just validation + fixup

You're confused and annoyingly persistent.

Escaping (or quoting in general) is a simple translation from a literal representation of a string to a (lexical) syntax representation with the purpose of embedding the string in an external medium (e.g. source code written in that lexical syntax).

Escaping is a mechanical process that doesn't discriminate between "valid" and "invalid". It is completely ignorant to the higher-level meaning of the string that is translated (e.g. email address) but solely operates on the constituent characters.

That is in contrast to validation, which is a simple function that decides whether a given object is admissible or not (as you say yourself). "Admissible" here is in with respect to a meaning that is higher-level than lexical syntax. It is semantic (is this a valid email), not syntactic.

(There are sometimes certain technical restrictions on which values can be represented in a lexical syntax, for example hard limits on string lengths. So there is a small extent to which "validation" can fill a purpose with relation to lexical syntax, too - but that's not what we're discussing).

To make it even more confusing, email addresses conform to a (albeit poorly specified) lexical syntax, too. And you can certainly attempt to validate if a given string is valid email address. However, HTML syntax doesn't care about that. Email address syntax is not part of the HTML syntax. HTML specifies how to escape _strings_, not email addresses.

And HTML syntax is right not caring about email syntax because it would be unnecessary complication in practice.

Just as the other examples I gave. E.g. looking up email addresses from an address book is not a task that in practice needs to be more specific than looking up a string from a list of strings.

> Anyway the only way to validate an e-mail in practice is to use it and confirm.

Which was my initial statement "Just use it" that you heavily disagreed with.


> Escaping is a mechanical process that doesn't discriminate between "valid" and "invalid". It is completely ignorant to the higher-level meaning of the string that is translated (e.g. email address) but solely operates on the constituent characters.

It does discriminate between "valid" and "invalid". This symbol is "valid" and we don't need to do anything. This symbol is "invalid" and we need to escape it. Validation occurs throughout the whole abstraction stack. Not only at the level of meaning of an entire string.

> Which was my initial statement "Just use it" that you heavily disagreed with.

In the case of e-mail I don't disagree with you. It is however balls to the wall insane to say "Just use it" in general. Which was my point. Notice how my reply specifically mentions vulnerabilities that were caused by the "just use it" mantra.


> This symbol is "valid" and we don't need to do anything. This symbol is "invalid" and we need to escape it.

It's quite a stretch to call symbols that need to be escaped “invalid”. And it's often possible to escape without discerning between “valid” and “invalid” characters. For example, in HTML you might just convert all characters into numeric entities.

> It is however balls to the wall insane to say "Just use it" in general.

Good thing the parent didn't say it in general.


I meant to say "certainly _not_ validating"


You seem to have a weird definition of “validation”.




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

Search: