You can't write secure sites with Java because the source code can be examined, does PHP fix this problem? What should I pick up and look to to find out how to write a web server that can handle payments, like with Bitcoin or an0ther protocol?
1. Don't rely on difficulty of reverse-engineering to maintain security.
Every language can be reverse-engineered, whether it produces native assembly code, Java byte code or is a scripting language such as PHP or Javascript. The final product of any coding language, whether script or byte code, can usually be obfuscated to make attempts at reverse-engineering more difficult BUT REVERSE-ENGINEERING WILL NEVER BE IMPOSSIBLE.
2. Don't rely on obscurity of source code to maintain security.
How difficult a language is to reverse-engineer, however, holds no bearing on whether that makes it a good or bad candidate for programming a web server. As long as your server is secure, your server code will not leak out.
Best practices dictate that your server security should not rely on any secrets in your code. Even if your code were to leak out and be accessible by the public, it should not affect the security of your web server as long as it is properly coded (no secrets stored in code and no vulnerabilities).
Your secrets, such as password hashes, should be stored in a shared (shared between instances of your web server) database or some other form of shared secure storage.
In some cases, your code may contain vulnerabilities, and exposing the code to the public may reveal these vulnerabilities. This is generally considered A Good Thing. Whether or not vulnerabilities are known to the public, they will still exist until they are fixed in the code. Public review helps to identify these vulnerabilities early on (allowing them to be fixed and the vulnerabilities eliminated) instead of allowing them to be surreptitiously exploited.
3. Combine IT best practices with coding best practices to create and maintain a secure server.
Maintaining a secure server requires not only wise coding but wise IT practices. Ultimately, selecting the best language for a web server should be more a case of selecting the best tool for the job, or the one you are most comfortable with.
Consider posting security questions to https://security.stackexchange.com/
Related
Very closely related: How to protect strings without SecureString?
Also closely related: When would I need a SecureString in .NET?
Extremely closely related (OP there is trying to achieve something very similar): C# & WPF - Using SecureString for a client-side HTTP API password
The .NET Framework has class called SecureString. However, even Microsoft no longer recommends its use for new development. According to the first linked Q&A, at least one reason for that is that the string will be in memory in plaintext anyway for at least some amount of time (even if it's a very short amount of time). At least one answer also extended the argument that, if they have access to the server's memory anyway, in practice security's probably shot anyway, so it won't help you. (The second linked Q&A implies that there was even discussion of dropping this from .NET Core entirely).
That being said, Microsoft's documentation on SecureString does not recommend a replacement, and the consensus on the linked Q&A seems to be that that kind of a measure wouldn't be all that useful anyway.
My application, which is an ASP.NET Core application, makes extensive use of API Calls to an external vendor using the HttpClient class. The generally-recommended best practice for HttpClient is to use a single instance rather than creating a new instance for each call.
However, our vendor requires that all API Calls include our API Key as a header with a specific name. I currently store the key securely, retrieve it in Startup.cs, and add it to our HttpClient instance's headers.
Unfortunately, this means that my API Key will be kept in plaintext in memory for the entire lifecycle of the application. I find this especially troubling for a web application on a server; even though the server is maintained by corporate IT, I've always been taught to treat even corporate networks as semi-hostile environments and not to rely purely on corporate firewalls for application security in such cases.
Does Microsoft have a recommended best practice for cases like this? Is this a potential exception to their recommendation against using SecureString? (Exactly how that would work is a separate question). Or is the answer on the other Q&A really correct in saying that I shouldn't be worried about plaintext strings living in memory like this?
Note: Depending on responses to this question, I may post a follow-up question about whether it's even possible to use something like SecureString as part of HttpClient headers. Or would I have to do something tricky like populate the header right before using it and then remove it from memory right afterwards? (That would create an absolute nightmare for concurrent calls though). If people think that I should do something like this, I would be glad to create a new question for that.
You are being WAY too paranoid.
Firstly, if a hacker gets root access to your web server, you have WAY bigger problems than your super-secret web app credentials being stolen. Way, way, way bigger problems. Once the hackers are on your side of the airtight hatchway, it is game over.
Secondly, once your infosec team detects the intrusion (if they don't, again, you've got WAY bigger problems) they're going to tell you and the first thing you're going to do is change every key and password you know of.
Thirdly, if a hacker does get root access to your webserver, their first thought isn't going to be "let's take a memory dump for later analysis". A dumpfile is rather large (will take time to transfer over the wire, and the network traffic might well be noticed) and (at least on Windows) hangs the process until it's complete (so you'd notice your web app was unresponsive) - both of which are likely to raise some red flags.
No, hackers are there to grab as much valuable information in the least amount of time, because they know their access could be discovered at any second. So they're going to go for the low-hanging fruit first - usernames and passwords. Then they'll move on to trying to find out what's connected to that server, and since your DB credentials are likely in a config file on that server, they will almost certainly switch their attentions to that far more interesting target.
So all things considered, your API key is pretty darn unlikely to be compromised - and even if it is, it won't be because of something you did or didn't do. There are far more productive ways of focusing your time than trying to secure something that already is (or should be) incredibly secure. And, at the end of the day, no matter how many layers of security you put in place... that API or SSL key is going to be raw, in memory, at some stage.
I would like go get my head around how is best to set up a client server architecture where security is of up most importance.
So far I have the following which I hope someone can tell me if its good enough, or it there are other things I need to think about. Or if I have the wrong end of the stick and need to rethink things.
Use SSL certificate on the server to ensure the traffic is secure.
Have a firewall set up between the server and client.
Have a separate sql db server.
Have a separate db for my security model data.
Store my passwords in the database using a secure hashing function such as PBKDF2.
Passwords generated using a salt which is stored in a different db to the passwords.
Use cloud based infrastructure such as AWS to ensure that the system is easily scalable.
I would really like to know is there any other steps or layers I need to make this secure. Is storing everything in the cloud wise, or should I have some physical servers as well?
I have tried searching for some diagrams which could help me understand but I cannot find any which seem to be appropriate.
Thanks in advance
Hardening your architecture can be a challenging task and sharding your services across multiple servers and over-engineering your architecture for semblance security could prove to be your largest security weakness.
However, a number of questions arise when you come to design your IT infrastructure which can't be answered in a single SO answer (will try to find some good white papers and append them).
There are a few things I would advise which is somewhat opinionated backed up with my own thought around it.
Your Questions
I would really like to know is there any other steps or layers I need to make this secure. Is storing everything in the cloud wise, or should I have some physical servers as well?
Settle for the cloud. You do not need to store things on physical servers anymore unless you have current business processes running core business functions that are already working on local physical machines.
Running physical servers increases your system administration requirements for things such as HDD encryption and physical security requirements which can be misconfigured or completely ignored.
Use SSL certificate on the server to ensure the traffic is secure.
This is normally a no-brainer and I would go with a straight, "Yes"; however you must take into consideration the context. If you are running something such as a blog site or documentation-related website that does not transfer any sensitive information at any point in time through HTTP then why use HTTPS? HTTPS has it's own overhead, it's minimal, but it's still there. That said, if in doubt, enable HTTPS.
Have a firewall set up between the server and client.
That is suggested, you may also want to opt for a service such as CloudFlare WAF, I haven't personally used it though.
Have a separate sql db server.
Yes, however not necessarily for security purposes. Database servers and Web Application servers have different hardware requirements and optimizing both simultaneously is not very feasible. Additionally, having them on separate boxes increases your scalability quite a bit which will be beneficial in the long run.
From a security perspective; it's mostly another illusion of, "If I have two boxes and the attacker compromises one [Web Application Server], he won't have access to the Database server".
At foresight, this might seem to be the case but is rarely so. Compromising the Web Application server is still almost a guaranteed Game Over. I will not go into much detail into this (unless you specifically ask me to) however it's still a good idea to keep both services separate from eachother in their own boxes.
Have a separate db for my security model data.
I'm not sure I understood this, what security model are you referring to exactly? Care to share a diagram or two (maybe an ERD) so we can get a better understanding.
Store my passwords in the database using a secure hashing function such as PBKDF2.
Obvious yes; what I am about to say however is controversial and may be flagged by some people (it's a bit of a hot debate)—I recommend using BCrypt instead of PKBDF2 due to BCrypt being slower to compute (resulting in slower to crack).
See - https://security.stackexchange.com/questions/4781/do-any-security-experts-recommend-bcrypt-for-password-storage
Passwords generated using a salt which is stored in a different db to the passwords.
If you use BCrypt I would not see why this is required (I may be wrong). I go into more detail regarding the whole username and password hashing into more detail in the following StackOverflow answer which I would recommend you to read - Back end password encryption vs hashing
Use cloud based infrastructure such as AWS to ensure that the system is easily scalable.
This purely depends on your goals, budget and requirements. I would personally go for AWS, however you should read some more on alternative platforms such as Google Cloud Platform before making your decision.
Last Remarks
All of the things you mentioned are important and it's good that you are even considering them (most people just ignore such questions or go with the most popular answer) however there are a few additional things I want to point:
Internal Services - Make sure that no unrequired services and processes are running on server especially in productions. These services will normally be running old versions of their software (since you won't be administering them) that could be used as an entrypoint for your server to be compromised.
Code Securely - This may seem like another no-brainer yet it is still overlooked or not done properly. Investigate what frameworks you are using, how they handle security and whether they are actually secure. As a developer (and not a pen-tester) you should at least use an automated web application scanner (such as Acunetix) to run security tests after each build that is pushed to make sure you haven't introduced any obvious, critical vulnerabilities.
Limit Exposure - Goes somewhat hand-in-hand with my first point. Make sure that services are only exposed to other services that depend on them and nothing else. As a rule of thumb, keep everything entirely closed and open up gradually when strictly required.
My last few points may come off as broad. The intention is to keep a certain philosophy when developing your software and infrastructure rather than a permanent rule to tick on a check-box.
There are probably a few things I have missed out. I will update the answer accordingly over time if need be. :-)
I am building a relatively simple program to gather and sort data input by the user. I would like to use a local server running through a web browser for two reasons:
HTML forms are a simple and effective means for gathering the input I'll need.
I want to be able to run the program off-line and without having to manage the security risks involved with accessing a remote server.
Edit: To clarify, I mean that the application should be accessible only from the local network and not from the Internet.
As I've been seeking out information on the issue, I've encountered one or two remarks suggesting that local servers have their own security risks, but I'm not clear on the nature or severity of those risks.
(In case it is relevant, I will be using SWI-Prolog for handling the data manipulation. I also plan on using the SWI-Prolog HTTP package for the server, but I am willing to reconsider this choice if it turns out to be a bad idea.)
I have two questions:
What security risks does one need to be aware of when using a local server for this purpose? (Note: In my case, the program will likely deal with some very sensitive information, so I don't have room for any laxity on this issue).
How does one go about mitigating these risks? (Or, where I should look to learn how to address this issue?)
I'm very grateful for any and all help!
There are security risks with any solution. You can use tools proven by years and one day be hacked (from my own experience). And you can pay a lot for security solution and never be hacked. So, you need always compare efforts with impact.
Basically, you need protect 4 "doors" in your case:
1. Authorization (password interception or, for example improper, usage of cookies)
2. http protocol
3. Application input
4. Other ways to access your database (not using http, for example, by ssh port with weak password, taking your computer or hard disk etc. In some cases you need properly encrypt the volume)
1 and 4 are not specific for Prolog but 4 is only one which has some specific in a case of local servers.
Protect http protocol level means do not allow requests which can take control over your swi-prolog server. For this purpose I recommend install some reverse-proxy like nginx which can prevent attacks on this level including some type of DoS. So, browser will contact nginx and nginx will redirect request to your server if it is a correct http request. You can use any other server instead of nginx if it has similar features.
You need install proper ssl key and allow ssl (https) in your reverse proxy server. It should be not in your swi-prolog server. Https will encrypt all information and will communicate with swi-prolog by http.
Think about authorization. There are methods which can be broken very easily. You need study this topic, there are lot of information. I think it is most important part.
Application input problem - the famose example is "sql injection". Study examples. All good web frameworks have "entry" procedures to clean all possible injections. Take an existing code and rewrite it with prolog.
Also, test all input fields with very long string, different charsets etc.
You can see, the security is not so easy, but you can select appropriate efforts considering with the impact of hacking.
Also, think about possible attacker. If somebody is very interested particulary to get your information all mentioned methods are good. But it can be a rare case. Most often hackers just scan internet and try apply known hacks to all found servers. In this case your best friend should be Honey-Pots and prolog itself, because the probability of hacker interest to swi-prolog internals is extremely low. (Hacker need to study well the server code to find a door).
So I think you will found adequate methods to protect all sensitive data.
But please, never use passwords with combinations of dictionary words and the same password more then for one purpose, it is the most important rule of security. For the same reason you shouldn't give access for your users to all information, but protection should be on the app level design.
The cases specific to a local server are a good firewall, proper network setup and encription of hard drive partition if your local server can be stolen by "hacker".
But if you mean the application should be accessible only from your local network and not from Internet you need much less efforts, mainly you need check your router/firewall setup and the 4th door in my list.
In a case you have a very limited number of known users you can just propose them to use VPN and not protect your server as in the case of "global" access.
I'd point out that my post was about a security issue with using port forwarding in apache
to access a prolog server.
And I do know of a successful prolog injection DOS attack on a SWI-Prolog http framework based website. I don't believe the website's author wants the details made public, but the possibility is certainly real.
Obviously this attack vector is only possible if the site evaluates Turing complete code (or code which it can't prove will terminate).
A simple security precaution is to check the Request object and reject requests from anything but localhost.
I'd point out that the pldoc server only responds by default on localhost.
- Anne Ogborn
I think SWI_Prolog http package is an excellent choice. Jan Wielemaker put much effort in making it secure and scalable.
I don't think you need to worry about SQL injection, indeed would be strange to rely on SQL when you have Prolog power at your fingers...
Of course, you need to properly manage the http access in your server...
Just this morning there has been an interesting post in SWI-Prolog mailing list, about this topic: Anne Ogborn shares her experience...
Web applications on uncompromised computers are vulnerable to XSS,CRSF,sql injection attacks and cookie stealing in unsecure wifi environments.
To prevent those security issues there are the folowing remedies
sql injection: a good datamapper(like linq-to-sql) does not have the risk of sql injection (am i naïeve to believe this?)
CSRF: Every form-post is verified with the <%:Html.AntiForgeryToken() %> (this is a token in a asp.net mvc environment that is stored in a cookie and verified on the server)
XSS: every form that is allowed to post html is converted, only bb code is allowed, the rest is encoded . All possible save actions are done with a post event so rogue img tags should have no effect
cookie stealing: https
Am i now invulnerable to web-based hacking attempts(when implemented correctly)? Or am i missing some other security issues in web-development?(except for possible holes in the OS platform or other software)
The easy answer is "No you're not invulnerable - nobody is!"
This is a good start, but there are a few other things you could do. The main one you haven't mentioned is validation of untrusted data against a white-list and this is important as it spans multiple exploits such as both SQLi and XSS. Take a look at OWASP Top 10 for .NET developers part 1: Injection and in particular, the section about "All input must be validated against a whitelist of acceptable value ranges".
Next up, you should apply the principle of least privilege to the accounts connecting to your SQL Server. See the heading under this name in the previous link.
Given you're working with ASP.NET, make sure Request Validation remains on and if you absolutely, positively need to disable it, just do it at a page level. More on this in Request Validation, DotNetNuke and design utopia.
For your output encoding, the main thing is to ensure that you're encoding for the right context. HTML encoding != JavaScript encoding != CSS encoding. More on this in OWASP Top 10 for .NET developers part 2: Cross-Site Scripting (XSS).
For the cookies, make them HTTP only and if possible, only allow them to be served securely (if you're happy to only run over HTTPS). Try putting your web.config through the web.config security analyser which will help point you in the right direction.
Another CSRF defense - albeit one with a usability impact - is CAPTCHA. Obviously you want to use this sparingly but if you've got any really critical functions you want to protect, this puts a pretty swift stop to it. More in OWASP Top 10 for .NET developers part 5: Cross-Site Request Forgery (CSRF).
Other than that, it sounds like you're aware of many of the important principles. It won't make you invulnerable, but it's a good start.
Am I now invulnerable to web-based hacking attempts?
Because, no matter how good you are, everyone makes mistakes, the answer is no. You almost certainly forgot to sanitize some input, or use some anti-forgery token. If you haven't now, you or another developer will as your application grows larger.
This is one of the reason we use frameworks - MVC, for example, will automatically generate anti-CSRF tokens, while LINQ-to-SQL (as you mentioned) will sanitize input for the database. So, if you are not already using a framework which makes anti-XSS and anti-CSRF measures the default, you should begin now.
Of course, these will protect you against these specific threats, but it's never possible to be secure against all threats. For instance, if you have an insecure SQL-connection password, it's possible that someone will brute-force your DB password and gain access. If you don't keep your versions of .Net/SQL-Server/everything up to date, you could be the victim of online worm (and even if you do, it's still possible to be zero-dayed).
There are even problems you can't solve in software: A script kiddie could DDOS your site. Your server-company could go bankrupt. A shady competitor could simply take a hedge-clippers to your internet line. Your warehouse could burn down. A developer could sell the source-code to a company in Russia.
The point is, again, you can't ever be secure against everything - you can only be secure against specific threats.
This is the definitive guide to web attacks. Also, I would recommend you use Metasploit against your web app.
It definitely is not enough! There are several other security issues you have to keep in mind when developing a web-app.
To get an overview you can use the OWASP Top-Ten
I think this is an very interesting post to read when thinking about web-security: What should a developer know before building a public web site?
There is a section about security that contains good links for most of the threats you are facing when developing web-apps.
The most important thing to keep in mind when thinking about security is:
Never trust user input!
[I am answering to this "old" question because I think it is always an actual topic.]
About what you didn't mention:
You missed a dangerous attack in MVC frameworks: Over Posting Attack
You also missed the most annoying threats: Denial of Service
You also should pay enough attention to file uploads (if any...) and many more...
About what you mentioned:
XSS is really really really waster and more annoying to mitigate. There are several types of encoding including Html Encoding, Javascript Encoding, CSS Encoding, Html Attribute Encoding, Url Encoding, ...
Each of them should be performed to the proper content, in the proper place - i.e. Just doing Html Encoding the content is not enough in all situations.
And the most annoying about XSS, is that there are some situations that you should perform Combinational Encoding(i.e. first JavascriptEncode and then HtmlEncode...!!!)
Take a look at the following link to become more familiar with a nightmare called XSS...!!!
XSS Filter Evasion Cheat Sheet - OWASP
I consider myself to be quite a good programmer but I know very little about sever administration. I'm sorry if these questions are noobish but I would really appreciate some advice or links on steps I can take to make this more secure.
I've completed a project for a client that involves storing some very sensitive information, ie personal details of big donors. From a programming perspective it's protected using user authentication.
I don't mind spending some money if it means the info will be more secure, what other steps should I take?
Can the database be encrypted some how so that even if the server is compromised people can't just dump the mysqldb and have everything?
Is it worth purchasing an ssl certificate?
The site is currently hosted on a personal hosting plan with a reasonably trustworthy host. Would a virtual private server be more secure? Are there special hosts I can use that take additional steps to protect info (ie would it be more secure on amazon s3)?
As a side note to the specific question, I would recommend reading some books on computer/programming security. Some good ones are 19 Deadly Sins of Software Security and Writing Solid Code.
You don’t need to encrypt the database itself, just encrypt the data before storing it. (Make sure to use real, cryptographically-secure algorithms instead of making one up yourself.)
Using SSL is definitely an important step if you want to avoid MITM attacks or snooping. A certificate allows you to use SSL without having to take extra steps like installing a self-signed one on each of the client systems (not to mention other benefits like revocation of compromised certs and such).
It depends on just how sensitive the information is and how bad leakage would be. You may want to read some reviews of hosts to get an idea of how good the host is. (If possible, sort the reviews ascending by rating and look at the bad reviews to see if they are objective problems that could apply to you and/or have to do with security, or if they are just incidental or specific issues to that reviewer.) As for the “cloud”, you would kind of be taking a chance since real-world security and privacy of it has yet to be determined. Obviously, if you do go with it, you’ll want a notable, trustworthy host like Amazon or Microsoft since they have benefits like accountability and work constantly and quickly to fix any problems.
HTH