diff --git a/clone.module b/clone.module
index 4e603ed..75d9fe5 100644
--- a/clone.module
+++ b/clone.module
@@ -39,9 +39,21 @@ function clone_menu() {
     'file' => 'clone.pages.inc',
     'description' => 'Allows users to clone (copy then edit) an existing node.',
   );
-  $items['node/%node/clone'] = array(
+  $items['node/%node/clone/confirm'] = array(
     'access callback' => 'clone_access_cloning',
-    'access arguments' => array(1),
+    'access arguments' => array(1, FALSE),
+    'page callback' => 'clone_node_check',
+    'page arguments' => array(1),
+    'title' => 'Clone content',
+    'title callback' => 'clone_action_link_title',
+    'title arguments' => array(1),
+    'weight' => 5,
+    'file' => 'clone.pages.inc',
+    'type' => MENU_CALLBACK,
+  );
+  $items['node/%node/clone/%clone_token'] = array(
+    'access callback' => 'clone_access_cloning',
+    'access arguments' => array(1, 3),
     'page callback' => 'clone_node_check',
     'page arguments' => array(1),
     'title' => 'Clone content',
@@ -55,8 +67,22 @@ function clone_menu() {
   return $items;
 }
 
-function clone_access_cloning($node) {
+function clone_token_to_arg($arg = NULL, $map = NULL, $index = NULL) {
+  // Supply CSRF token if needed.
+  if (variable_get('clone_nodes_without_confirm', FALSE)) {
+    return drupal_get_token('clone_access_cloning');
+  }
+  return 'confirm';
+}
+
+function clone_access_cloning($node, $token = FALSE) {
   global $user;
+  // Check CSRF token if needed.
+  if (variable_get('clone_nodes_without_confirm', FALSE)) {
+    if (!$token || $token !== drupal_get_token('clone_access_cloning')) {
+      return FALSE;
+    }
+  }
   // Check basic permissions first.
   $access = clone_is_permitted($node->type) && (user_access('clone node') || ($user->uid && ($node->uid == $user->uid) && user_access('clone own nodes')));
   // Make sure the user can view the original node content, and create a new one..
@@ -120,7 +146,7 @@ function clone_views_api() {
 function clone_admin_paths() {
   if (variable_get('node_admin_theme')) {
     $paths = array(
-      'node/*/clone' => TRUE,
+      'node/*/clone/*' => TRUE,
     );
     return $paths;
   }
@@ -146,13 +172,14 @@ function clone_form_node_form_alter(&$form, $form_state, $form_id) {
  */
 function clone_form_node_admin_content_alter(&$form, $form_state, $form_id) {
   $destination = drupal_get_destination();
+  $token = clone_token_to_arg();
   // Expose a Clone operation on each node.
   foreach($form['admin']['nodes']['#options'] as $nid => &$row){
     $node = node_load($nid);
-    if (clone_access_cloning($node)) {
+    if (clone_access_cloning($node, $token)) {
       $row['operations']['data']['#links']['clone'] = array(
         'title' => t('clone'),
-        'href' => 'node/' . $nid . '/clone',
+        'href' => 'node/' . $nid . '/clone/' . $token,
         'query' => $destination,
       );
     }
diff --git a/views/views_handler_field_node_link_clone.inc b/views/views_handler_field_node_link_clone.inc
index c4bed67..0644b15 100644
--- a/views/views_handler_field_node_link_clone.inc
+++ b/views/views_handler_field_node_link_clone.inc
@@ -10,13 +10,14 @@ class views_handler_field_node_link_clone extends views_handler_field_node_link
    * Renders the link.
    */
   function render_link($node, $values) {
+    $token = clone_token_to_arg();
 
-    if (!clone_access_cloning($node)) {
+    if (!clone_access_cloning($node, $token)) {
       return;
     }
 
     $this->options['alter']['make_link'] = TRUE;
-    $this->options['alter']['path'] = "node/{$node->nid}/clone";
+    $this->options['alter']['path'] = "node/{$node->nid}/clone/" . $token;
     $this->options['alter']['query'] = drupal_get_destination();
 
     $text = !empty($this->options['text']) ? $this->options['text'] : t('clone');
