When I interview developers, I generally ask some basic questions about security - "Explain to me what an XSS attack is?", or "How would you defend a web app against SQL injection?"
Basic stuff, which - to my mind - literally every person who develops anything which is on the web should know.
And a surprising number of people - even "senior" developers can't answer this stuff. It's really worrying.
I can forgive someone who can’t explain how XSS or CSRF works (I’m not sure I can explain it so clearly myself—kudos to the article’s author for the excellent explanation) if they know about the top 10 and have read it at least once.
I've been developing web apps since .NET 3, and the only thing I understand (and can claim to guard against [1]) in the OWASP top 10 is SQL injection. I always try to explain to my clients that web security is a complex field and they should hire a pro for that area... which, given that Google itself seems to have problems with it, is quite difficult.
[1] - claim, because you never know when someone happily calls exec_sql with a string from a stored procedure (had it happen at two different companies).
> I always try to explain to my clients that web security is a complex field and they should hire a pro for that area...
No. Just no.
Every other field of engineering includes security and safety as a core requirement of anything they do. Software engineering is no different, and while specialists can help, every engineer needs to know how to write secure code if we are to improve the sad situation the Internet is in.
Sell yourself as a software engineer who knows security, and watch the money rain as literally everyone tries to hire you.
The abstraction doesn't fit. Where the civil engineers would be expected to build a bridge that doesn't collapse when the wind is Just Right (key word: Tacoma Narrows Bridge), software makers are expected to build a lock that doesn't open when someone whistles Just Right (key word: SQL injection).
Bridge builders are not expected to make the bridge itself defend against saboteurs, unlike software. To painfully extend the scenario: the wind is relatively well understood and once you've learned a lesson and guarded against it as a bridge builder, a given bridge can be considered stable.
Not so with software. One vuln fix, 5 more show up to take its place over time.
Malicious actors & botnets = the wind now (bear with me please). Once the bridge no longer collapsed via a certain Just Right tune, the wind would stop blowing the old Just Right way and instead try finding a new Just Right way, like whirling in a tight circular motion in just the right spot to see if it can unscrew bolts, or attempt -ddos- to tornado itself into a waterspout to try to collapose the bridge.
> Sell yourself as a software engineer who knows security, and watch the money rain as literally everyone tries to hire you
How can you brag about the fact that a software engineer who knows security is worth more on the market, then try to claim that every engineer needs to know how to write highly secure code? Those are incompatible ideas.
A lock manufacturer designs locks. A carpenter designs the building the lock is securing.
You wouldn't rely on your carpenter to build you a lock, because you understand that they are two separate domains of knowledge. You need to have this same mindset about good security and good engineering.
Digital security requires a high amount of specialized knowledge and involves far more variables than lock construction. It also requires constant vigilance and integration, where as a lock is fire-and-forget.
> How can you brag about the fact that a software engineer who knows security is worth more on the market, then try to claim that every engineer needs to know how to write highly secure code? Those are incompatible ideas.
Software developers who have the abilities they should are more valuable than those who . . . don't. That doesn't seem controversial.
I have almost succeeded Stripe CTF 2 (runed out of time on final step because of the crowd). I am sure I can not give clear definition during an interview without a good refresh before.
I did a code review a while back with a new Web/Software Engineer II hire (I was not involved in the interview process) and noticed they were doing an HTTP GET request when they should have been doing a POST (attempting to change some values in the backend/database).
I talked to him about the issue, just chatting about GET, POST, PUT, etc...and all I got back was a deer-in-the-headlights look. He responded "I...I don't know what any of that is."
:(
I now ask "Can you explain what are some differences between an HTTP GET versus POST request?" with every web developer interview I do. If they get that one wrong or cannot answer...I don't bother with anything deeper.
Do you expect a better answer for the second than "use a framework that parses the input in a way that escapes the input such that it's not interpreted as a command"?
Prepared statements tend to be the best answer for most cases which is similar to the approach you describe but is natively supported by most SQL dialects and also improves performance.
In my experience, many developers and even experienced security engineers can fail to give this answer though.
That's only relevant to know if you're actually implementing the piece that takes raw input and builds a query out of it, and most devs don't work with that piece on a day-to-day basis.
Knowing that you need to use a framework that takes care of input sanitizing is enough for the typical dev.
Edit: Expecting "prepared statements" as "the" answer seems close to making it a trivia question rather than "sufficient understand for doing the job" question.
The article mentions creating a clear access control policy. I haven’t worked on access control at all, but I’ve witnessed colleagues at multiple companies implementing it, something which I’ve only seen being done by hand. This obviously leads to bugs and security issues. I always wondered whether there wasn’t already software built solely or partly for the purpose of access control.
I’ve recently been reading about LDAP. While I don’t have any experience using it, I wondered whether you could simply use LDAP to implement your access control. Someone on Stack Overflow asked the same question: https://stackoverflow.com/questions/3363267/ldap-for-applica.... The accepted answer mentions that LDAP can be used for high-level access information, but that the lower level should be handled by the application, as the LDAP scheme would otherwise become complicated. Fair enough.
My question is: What experience do others here have with implementing access control? Have you used LDAP? Is there another general tool built for this purpose which saves us the trouble of building our own system? Surely someone like IBM and Microsoft have built something for this. Are there any open source alternatives?
Microsoft's architecture usually uses Kerberos Delegation, so access control is implemented in the backend. Say you've got an IIS web server, and SQL server; when the user logs into your application, they either delegate their tgt to the webserver or the web server gets a ticket on behalf of the user via Kerberos Protocol Transition (if they used a username and password in a form), the IIS server then authenticates to the backend, essentially impersonating the end user, so that the backend SQL server can look at it's own ACLs, rather than the web server having full access to the database and implementing its own ACLs. All this relies on having users in LDAP (specifically Active Directory). You could also go with what most people do, which is what is described in that article, in that you have groups as roles in LDAP, and simply lookup what groups a user belongs to, to determine access levels.
We've used LDAP for authentication by binding as the user and checking if they belong to certain groups. Those groups are then used to give the user certain abilities.
I've extensive use with LDAP over the last 20+ years or so.
It's great for various authenticating various Linux/UNIX system bits and applications - in the past I've supported everything from Tacacs and Radius, Apache with LDAP auth, storing SSH public keys (both hosts and user keys), password expiration policies and even sudo rules stored in LDAP.
There is a pretty steep learning curve though and there are many, many applications out there (particularly commercial ones) that claim to support LDAP but when you take a closer look their support is pretty broken and it can take a lot of effort to get everything working.
LDAP also has some legacy warts, and competing/incompatible bits - for example LDAP-TLS vs the deprecated LDAPS, RFC2307 vs RFC2307bis schemas etc. Working with LDIF can be an utter pain sometimes (esp. with trailing whitespace) and the management tools outside of Active Directory leave a lot to be desired.
It still beats the heck out of trying to synchronize tens/hundreds/thousands of user accounts with something like Puppet, which I've seen so many devops orgs do badly.
> The first check you can make is to verify that a request’s origin and referer headers match the location of the website. These headers can’t be programmatically set
Can I stop reading right here? The referer header is presumably the oftenest spoofed header on the planet.
This isn't to defend against a malicious user crafting requests, it's to defend against a malicious site tricking the user's browser into making an authenticated request. Said malicious site can't set those headers.
Edit: I think I misread your comment and you're not arguing that checking origin/referrer isn't enough for security, but rather that it will block legitimate, privacy-conscious users.
Using a CSRF token is a valid alternative, and it's mentioned just below in the article.
It's worth mentioning that in 1999 there were already tools that helped. Perl's Taint Mode was one of them. In a nutshell, any variables containing user input could not be used for stuff involving OS paths, system calls or databases. The only way to use such input would be to "launder" the data, usually by using regular expressions to pull out the pieces that actually look plausible.
As a side-effect, this introduced some great usability conveniences, such as numerical fields (think credit cards, age, dates…) in which the user could type all sorts of junk or poor formatting, and yet get some sane validation.
Nearly 20 years later, we're still a step backwards in having what I call "Forgiving UX", and have things like rigid drop-downs to select month/year of expiration on a credit card, instead of just lifting the first 4 digits—regardless of how the user typed them—and calling it a day.
The thing that drives me crazy is when you have a form that tells you to enter the date, so you go MM/DD/YYYY and when you hit submit it comes back and tells you that it wants MM-DD-YYYY.
That's something the parser could just as easily do itself and avoid making more work for the user. Ideally you would use a parser that's smart enough to figure out 95% of the cases and do the right thing and only return errors if it's completely unparseable or ambiguous.
A date field should be able to accept all values like:
2018-12-13
12/13/2018
Dec 13 18
December 13, 2018
12-13-平成三十年
13.0.6.1.3
1544677200
In cases where the input is ambiguous the parser can make its best guess and toss a warning. Preferably allowing the user to inspect its guess to see if is right.
Agree, it seems this is one area that inventing your own solution is tempting, yet people fail to realize the variety of cases that need to be supported and welded together. Same thing goes for IPs etc
32 comments
[ 0.25 ms ] story [ 80.3 ms ] threadBasic stuff, which - to my mind - literally every person who develops anything which is on the web should know.
And a surprising number of people - even "senior" developers can't answer this stuff. It's really worrying.
I can forgive someone who can’t explain how XSS or CSRF works (I’m not sure I can explain it so clearly myself—kudos to the article’s author for the excellent explanation) if they know about the top 10 and have read it at least once.
Last year: https://www.owasp.org/index.php/Top_10-2017_Top_10
[1] - claim, because you never know when someone happily calls exec_sql with a string from a stored procedure (had it happen at two different companies).
No. Just no.
Every other field of engineering includes security and safety as a core requirement of anything they do. Software engineering is no different, and while specialists can help, every engineer needs to know how to write secure code if we are to improve the sad situation the Internet is in.
Sell yourself as a software engineer who knows security, and watch the money rain as literally everyone tries to hire you.
Not so with software. One vuln fix, 5 more show up to take its place over time.
Malicious actors & botnets = the wind now (bear with me please). Once the bridge no longer collapsed via a certain Just Right tune, the wind would stop blowing the old Just Right way and instead try finding a new Just Right way, like whirling in a tight circular motion in just the right spot to see if it can unscrew bolts, or attempt -ddos- to tornado itself into a waterspout to try to collapose the bridge.
Security is not a one and done operation.
How can you brag about the fact that a software engineer who knows security is worth more on the market, then try to claim that every engineer needs to know how to write highly secure code? Those are incompatible ideas.
A lock manufacturer designs locks. A carpenter designs the building the lock is securing.
You wouldn't rely on your carpenter to build you a lock, because you understand that they are two separate domains of knowledge. You need to have this same mindset about good security and good engineering.
Digital security requires a high amount of specialized knowledge and involves far more variables than lock construction. It also requires constant vigilance and integration, where as a lock is fire-and-forget.
Software developers who have the abilities they should are more valuable than those who . . . don't. That doesn't seem controversial.
When I interview developers, I generally ask some basic questions about ____ - "Explain to me what _____ is?", or "How would you _____?"
Basic stuff, which - to my mind - literally every person who develops anything which is on _____ should know.
And a surprising number of people - even "senior" developers can't answer this stuff. It's really worrying.
I talked to him about the issue, just chatting about GET, POST, PUT, etc...and all I got back was a deer-in-the-headlights look. He responded "I...I don't know what any of that is."
:(
I now ask "Can you explain what are some differences between an HTTP GET versus POST request?" with every web developer interview I do. If they get that one wrong or cannot answer...I don't bother with anything deeper.
In my experience, many developers and even experienced security engineers can fail to give this answer though.
Knowing that you need to use a framework that takes care of input sanitizing is enough for the typical dev.
Edit: Expecting "prepared statements" as "the" answer seems close to making it a trivia question rather than "sufficient understand for doing the job" question.
I’ve recently been reading about LDAP. While I don’t have any experience using it, I wondered whether you could simply use LDAP to implement your access control. Someone on Stack Overflow asked the same question: https://stackoverflow.com/questions/3363267/ldap-for-applica.... The accepted answer mentions that LDAP can be used for high-level access information, but that the lower level should be handled by the application, as the LDAP scheme would otherwise become complicated. Fair enough.
My question is: What experience do others here have with implementing access control? Have you used LDAP? Is there another general tool built for this purpose which saves us the trouble of building our own system? Surely someone like IBM and Microsoft have built something for this. Are there any open source alternatives?
Not as easy as LDAP, it's designed for bigger places, like Universities
https://www.xkcd.com/806/
https://github.com/debolk/bolklogin
User management was done through gosa / fusiondirectory.
There is a pretty steep learning curve though and there are many, many applications out there (particularly commercial ones) that claim to support LDAP but when you take a closer look their support is pretty broken and it can take a lot of effort to get everything working.
LDAP also has some legacy warts, and competing/incompatible bits - for example LDAP-TLS vs the deprecated LDAPS, RFC2307 vs RFC2307bis schemas etc. Working with LDIF can be an utter pain sometimes (esp. with trailing whitespace) and the management tools outside of Active Directory leave a lot to be desired.
It still beats the heck out of trying to synchronize tens/hundreds/thousands of user accounts with something like Puppet, which I've seen so many devops orgs do badly.
Can I stop reading right here? The referer header is presumably the oftenest spoofed header on the planet.
Edit: I think I misread your comment and you're not arguing that checking origin/referrer isn't enough for security, but rather that it will block legitimate, privacy-conscious users.
Using a CSRF token is a valid alternative, and it's mentioned just below in the article.
As a side-effect, this introduced some great usability conveniences, such as numerical fields (think credit cards, age, dates…) in which the user could type all sorts of junk or poor formatting, and yet get some sane validation.
Nearly 20 years later, we're still a step backwards in having what I call "Forgiving UX", and have things like rigid drop-downs to select month/year of expiration on a credit card, instead of just lifting the first 4 digits—regardless of how the user typed them—and calling it a day.
https://perldoc.perl.org/perlsec.html#Taint-mode
That's something the parser could just as easily do itself and avoid making more work for the user. Ideally you would use a parser that's smart enough to figure out 95% of the cases and do the right thing and only return errors if it's completely unparseable or ambiguous.
A date field should be able to accept all values like:
In cases where the input is ambiguous the parser can make its best guess and toss a warning. Preferably allowing the user to inspect its guess to see if is right.