Showing posts with label Security. Show all posts
Showing posts with label Security. Show all posts

Thursday, April 20, 2017

How to Prevent Forms from Submitting Twice when a User Reloads the Page?

A CSRF token will handle this issue for you. If you have a check on the form, the token will stop the user from submitting twice without reloading the form before, since it will be a one-time use token.
Another way to prevent people from accidentally submitting twice is to simply gray out the button with javascript once the user clicks on it. This method is not for security reasons but rather for user experience, as it will help users understand the page is loading and they won’t have to click again to end up seeing your one-time use token error.

Thursday, April 13, 2017

The Update: 10 Most Critical Drupal Security Risks on Drupal 8

The 10 most critical Drupal security risks:
  1. SQL Injection
  2. Cross Site Scripting (XSS)
  3. Authentications and sessions
  4. Insecure direct object references
  5. Cross Site Request Forgery (CSRF)
  6. Security misconfiguration
  7. Insecure cryptographic storage
  8. Failure to restrict URL access
  9. Insufficient transport protection
  10. Unvalidated redirects

1. SQL Injection
You shouldn't use data that you don't trust (as a feed, a user input, another database, etc) directly in a database query without escaping it. This has been possible in Drupal 7 using functions that are now deprecated in Drupal 8.
db_query('SELECT foo FROM {table} t WHERE t.name = '. $_GET['user']);
Even though deprecated functions in Drupal 8 are available for us to use, we should be avoiding them. They are included only to allow legacy code to work more easily on Drupal 8.
Instead you should use the Drupal 8 object oriented method of building a query. In the example below, the $name variable will be sanitised, but there won’t be any user access permissions checked automatically.
$query = $connection->select('table', 't') ->fields('t', array('foo')) ->condition('t.name, $name);
If you need to include dynamic table names in your query, you should use escapeTable()

2. Cross Site Scripting (XSS)
XSS enables attackers to inject client-side scripts into web pages in order to carry out malicious actions. A large proportion of security vulnerabilities on web applications are XSS, so it makes sense to understand them and avoid them.
You should always escape the variables you send to the output if they come from a non trusted source, like the parameters of a URL. For example, this code is insecure:
print $_GET['id'];
It's also very common to see code like this, specially in custom themes:
$output .= $node->title;
The problem in the code above is that Drupal doesn't usually filter the user input when a node is saved. So the user could save malicious code in the title and then it will be printed without any kind of filtering.
One more obvious mistake is giving full HTML permissions to users who aren’t trusted, or allowing use of unsafe tags as <script>.
So, what can you do?
Luckily, the Twig templating engine that Drupal 8 uses now sanitises all variables by default. Ideally, all your HTML output should be from Twig templates.
Drupal also includes other API functions that you should use where appropriate. The Drupal 8 security documentation recommends the following functions:
  • Use t() and \Drupal::translation()->formatPlural() with @ or % placeholders to construct safe, translatable strings.
  • Use Html::escape() for plain text.
  • Use Xss::filter() for text that should allow some HTML tags.
  • Use Xss::filterAdmin() for text entered by a admin users that should allow most HTML.
  • Use Drupal.t() , Drupal.formatPlural() in JavaScript.

3. Authentications and sessions
You need to deal with these issues:
  • Weak password storage and account management
  • Session hijacking / fixation
  • Lack of session timeout / logout
Luckily, Drupal has good solutions for these built in.
  • Like Drupal 7, Drupal 8 stores passwords in the database in hashed form. This means that anyone who gets access to the database does not get access to user’s passwords.
  • In Drupal 8, the user’s session data is also stored in the database in hashed form. This means sessions can’t be hijacked by anyone with access to the database.

4. Insecure direct object references
It’s possible to load a node without checking that the user has access to it. For example, this will load the node a node with a certain id:
$node = \Drupal\node\Entity\Node::load($nid);
The Drupal 8 approach is to use $node->access($operation) to determine if the user has permission to perform a particular operation on the node.
When using Views, sometimes we don't make sure the user has access to nodes. One common issue is forget to add "published = Yes" to the view filters.

5. Cross Site Request Forgery (CSRF)
Below is an example of an image tag that could be added by any user who has permission to enter full HTML. When a user loads the page with this tag they will be logged out.
<img src="http://example.com/user/logout" />
It would be possible to delete content in the same way:
<img src="http://example.com/node/12/delete" />
However, in this case Drupal always asks "Are you sure you want to delete...?" when you try to delete an item to mitigate the risk of this happening.
This is an illustration of why it’s important to grant the ability to use Full HTML only to your trusted users. It’s also important that we use the Drupal API to achieve what we need wherever possible. The Form API includes input validation and security features that will mitigate the risk of a CSRF attack. For example, you should always make sure that you have a confirmation form for any critical custom operations (such as deleting content) so that nothing bad can happen if it’s linked to directly.

6. Security misconfiguration
Secure server
  • Make sure that your file permissions[https://www.drupal.org/node/244924] are appropriate to prevent unauthorised file access.
  • Control the maximum POST size and maximum file upload size by settings these in the php configuration on your server. Without this, attackers are able to upload large files or send large POST requests to use up system resources.
  • FTP is a vintage technology and was not designed to be secure. It includes a list of vulnerabilities that are well documented HERE. Use a version control system like git or at the very least SSH / SCP to get files onto your server.
  • Once you’re using SSH / SCP, consider using keys instead of passwords. This is an easier, more secure and more reliable way of signing into your server.
  • Keep your operating system up to date. Common Linux distributions will have an update system that will prompt you to do this.
  • Don’t have unnecessary applications running on a server. The more applications you have, the more software you’ll need to keep updated and the more likely it is that one of them will expose a security flaw.
Secure Drupal
  • Is your admin password strong enough? Use a password tool such as KeePass or LastPass to generate a secure password that you don’t use on any other sites and to keep track of all your passwords.
  • Double check all the "administer *" permissions and make sure they’re only assigned to trusted user roles. The "Administer text formats and filters" permission can allow a user to take control of a site.
  • Use Update module and keep track of the security news. Security updates are made on Wednesdays.

7. Insecure cryptographic storage
You may find that you develop custom modules that need to store sensitive data. There’s no native way in Drupal to do two-way encryption (i.e. to encrypt data that you’ll want to decrypt again later). If your database or a backup copy of your database is accessed, then you could be exposing sensitive data.
There’s a contributed module called Encrypt which provides an API you can use to encrypt the data you need to.
 
8. Failure to restrict URL access
If your custom module implements custom routing using Drupal 8’s new routing system, make sure that access permissions to your URLs you create are set properly. In Drupal 8, routing is done with YAML configuration. For example, the following would allow anyone who can access content on your site to access the path /example/settings.
example.name: path: '/example/settings' defaults: _controller: '\Drupal\example\Controller\ExampleController::content'requirements: _permission: 'access content'
Make sure that this is what you want and if it isn’t, check out the routing documentation to see how to achieve the access settings you need.

9. Insufficient transport protection
Tools like Wireshark allow you to analyse network traffic on the network you’re connected to. Using such a tool, a person connected to the same Wifi network as you in your office or in a coffee shop can see any unencrypted data you’re sending or receiving.
Configuring your server to allow access to your Drupal site over an HTTPS connection will allow your users to visit your site securely. You’ll require an SSL certificate that allows a user’s browser to confirm that the login page is not a forgery and it encrypts the username and password when it’s sent over the network. This prevents malicious people from stealing your login details.
 
10. Unvalidated redirects
The original security blog post contained unvalidated redirects as a separate security issue. However, we consider that this is now really a combination of the issues discussed under point 5: Cross Site Request Forgery, so won’t go into this further here.

Having covered what we consider may be the common pitfalls in Drupal 8 security, it’s important to remember that Drupal is one of the most secure content management systems available and Drupal 8 is its most secure version yet. We’d recommend you keep the points mentioned here in mind as you dive into Drupal 8. If you’ve already built one or more Drupal sites you should now have a basis for a security audit when you review your code. Above all, stay safe and stay secure!

Source: http://www.cameronandwilding.com/blog/edward/update-10-most-critical-drupal-security-risks-drupal-8

Wednesday, January 18, 2017

Cross-Site Scripting (XSS)

Cross-Site Scripting (XSS) is probably the most common singular security vulnerability existing in web applications at large. It has been estimated that approximately 65% of websites are vulnerable to an XSS attack in some form, a statistic which should scare you as much as it does me.

What is Cross-Site Scripting?

XSS occurs when an attacker is capable of injecting a script, often Javascript, into the output of a web application in such a way that it is executed in the client browser. This ordinarily happens by locating a means of breaking out of a data context in HTML into a scripting context - usually by injecting new HTML, Javascript strings or CSS markup. HTML has no shortage of locations where executable Javascript can be injected and browsers have even managed to add more. The injection is sent to the web application via any means of input such as HTTP parameters.
One of the major underlying symptoms of Cross-Site Scripting’s prevelance, unique to such a serious class of security vulnerabilities, is that programmers continually underestimate its potential for damage and commonly implement defenses founded on misinformation and poor practices. This is particularly true of PHP where poor information has overshadowed all other attempts to educate programmers. In addition, because XSS examples in the wild are of the simple variety programmers are not beyond justifying a lack of defenses when it suits them. In this environment, it’s not hard to see why a 65% vulnerability rate exists.
If an attacker can inject Javascript into a web application’s output and have it executed, it allows the attacker to execute any conceivable Javascript in a user’s browser. This gives them complete control of the user experience. From the browser’s perspective, the script originated from the web application so it is automatically treated as a trusted resource.
Back in my Introduction, I noted that trusting any data not created explicitly by PHP in the current request should be considered untrusted. This sentiment extends to the browser which sits separately from your web application. The fact that the browser trusts everything it receives from the server is itself one of the root problems in Cross-Site Scripting. Fortunately, it’s a problem with an evolving solution which we’ll discuss later.
We can extend this even further to the Javascript environment a web application introduces within the browser. Client side Javascript can range from the very simple to the extremely complex, often becoming client side applications in their own right. These client side applications must be secured like any application, distrusting data received from remote sources (including the server-hosted web application itself), applying input validation, and ensuring output to the DOM is correctly escaped or sanitised.
Injected Javascript can be used to accomplish quite a lot: stealing cookie and session information, performing HTTP requests with the user’s session, redirecting users to hostile websites, accessing and manipulating client-side persistent storage, performing complex calculations and returning results to an attacker’s server, attacking the browser or installing malware, leveraging control of the user interface via the DOM to perform a UI Redress (aka Clickjacking) attack, rewriting or manipulating in-browser applications, attacking browser extensions, and the list goes on...possibly forever.

Difference between hook_boot and hook_init Drupal

hook_boot() hook_init() hook_boot() will executes even on cached pages hook_init() will not executes on cached pages hook_boot() is ...