Issues (13)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

examples/pdo/index.php (5 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 52 and the first side effect is on line 36.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * Copyright (c) 2014 Yubico AB
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions are
8
 * met:
9
 *
10
 *   * Redistributions of source code must retain the above copyright
11
 *     notice, this list of conditions and the following disclaimer.
12
 *
13
 *   * Redistributions in binary form must reproduce the above
14
 *     copyright notice, this list of conditions and the following
15
 *     disclaimer in the documentation and/or other materials provided
16
 *     with the distribution.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
 */
30
31
/**
32
 * This is a simple example using PDO and a sqlite database for storing
33
 * registrations. It supports multiple registrations associated with each user.
34
 */
35
36
require_once('../../src/u2flib_server/U2F.php');
37
38
$dbfile = '/var/tmp/u2f-pdo.sqlite';
39
40
$pdo = new PDO("sqlite:$dbfile");
41
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
42
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
43
44
$pdo->exec("create table if not exists users (id integer primary key, name varchar(255))");
45
$pdo->exec("create table if not exists registrations (id integer primary key, user_id integer, keyHandle varchar(255), publicKey varchar(255), certificate text, counter integer)");
46
47
$scheme = isset($_SERVER['HTTPS']) ? "https://" : "http://";
48
$u2f = new u2flib_server\U2F($scheme . $_SERVER['HTTP_HOST']);
49
50
session_start();
51
52
function createAndGetUser($name) {
53
    global $pdo;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
54
    $sel = $pdo->prepare("select * from users where name = ?");
55
    $sel->execute(array($name));
56
    $user = $sel->fetch();
57
    if(!$user) {
58
        $ins = $pdo->prepare("insert into users (name) values(?)");
59
        $ins->execute(array($name));
60
        $sel->execute(array($name));
61
        $user = $sel->fetch();
62
    }
63
    return $user;
64
}
65
66
function getRegs($user_id) {
67
    global $pdo;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
68
    $sel = $pdo->prepare("select * from registrations where user_id = ?");
69
    $sel->execute(array($user_id));
70
    return $sel->fetchAll();
71
}
72
73
function addReg($user_id, $reg) {
74
    global $pdo;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
75
    $ins = $pdo->prepare("insert into registrations (user_id, keyHandle, publicKey, certificate, counter) values (?, ?, ?, ?, ?)");
76
    $ins->execute(array($user_id, $reg->keyHandle, $reg->publicKey, $reg->certificate, $reg->counter));
77
}
78
79
function updateReg($reg) {
80
    global $pdo;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
81
    $upd = $pdo->prepare("update registrations set counter = ? where id = ?");
82
    $upd->execute(array($reg->counter, $reg->id));
83
}
84
85
?>
86
87
<html>
88
<head>
89
    <title>PHP U2F example</title>
90
91
    <script src="../assets/u2f-api.js"></script>
92
93
    <script>
94
        <?php
95
96
        if($_SERVER['REQUEST_METHOD'] === 'POST') {
97
          if(!$_POST['username']) {
98
            echo "alert('no username provided!');";
99
          } else if(!isset($_POST['action']) && !isset($_POST['register2']) && !isset($_POST['authenticate2'])) {
100
            echo "alert('no action provided!');";
101
          } else {
102
            $user = createAndGetUser($_POST['username']);
103
104
            if(isset($_POST['action'])) {
105
              switch($_POST['action']):
106
                case 'register':
107
                  try {
108
                    $data = $u2f->getRegisterData(getRegs($user->id));
109
110
                    list($req,$sigs) = $data;
111
                    $_SESSION['regReq'] = json_encode($req);
112
                    echo "var req = " . json_encode($req) . ";";
113
                    echo "var sigs = " . json_encode($sigs) . ";";
114
                    echo "var username = '" . $user->name . "';";
115
        ?>
116
        setTimeout(function() {
117
            console.log("Register: ", req);
118
            u2f.register([req], sigs, function(data) {
119
                var form = document.getElementById('form');
120
                var reg = document.getElementById('register2');
121
                var user = document.getElementById('username');
122
                console.log("Register callback", data);
123
                if(data.errorCode) {
124
                    alert("registration failed with errror: " + data.errorCode);
125
                    return;
126
                }
127
                reg.value = JSON.stringify(data);
128
                user.value = username;
129
                form.submit();
130
            });
131
        }, 1000);
132
        <?php
133
                  } catch( Exception $e ) {
134
                    echo "alert('error: " . $e->getMessage() . "');";
135
                  }
136
137
                  break;
138
139
                case 'authenticate':
140
                  try {
141
                    $reqs = json_encode($u2f->getAuthenticateData(getRegs($user->id)));
142
143
                    $_SESSION['authReq'] = $reqs;
144
                    echo "var req = $reqs;";
145
                    echo "var username = '" . $user->name . "';";
146
        ?>
147
        setTimeout(function() {
148
            console.log("sign: ", req);
149
            u2f.sign(req, function(data) {
150
                var form = document.getElementById('form');
151
                var auth = document.getElementById('authenticate2');
152
                var user = document.getElementById('username');
153
                console.log("Authenticate callback", data);
154
                auth.value=JSON.stringify(data);
155
                user.value = username;
156
                form.submit();
157
            });
158
        }, 1000);
159
        <?php
160
                  } catch( Exception $e ) {
161
                    echo "alert('error: " . $e->getMessage() . "');";
162
                  }
163
164
                  break;
165
166
              endswitch;
167
            } else if($_POST['register2']) {
168
              try {
169
                $reg = $u2f->doRegister(json_decode($_SESSION['regReq']), json_decode($_POST['register2']));
170
                addReg($user->id, $reg);
171
              } catch( Exception $e ) {
172
                echo "alert('error: " . $e->getMessage() . "');";
173
              } finally {
174
                $_SESSION['regReq'] = null;
175
              }
176
            } else if($_POST['authenticate2']) {
177
              try {
178
                $reg = $u2f->doAuthenticate(json_decode($_SESSION['authReq']), getRegs($user->id), json_decode($_POST['authenticate2']));
179
                updateReg($reg);
180
                echo "alert('success: " . $reg->counter . "');";
181
              } catch( Exception $e ) {
182
                echo "alert('error: " . $e->getMessage() . "');";
183
              } finally {
184
                $_SESSION['authReq'] = null;
185
              }
186
            }
187
          }
188
        }
189
        ?>
190
    </script>
191
</head>
192
<body>
193
194
<form method="POST" id="form">
195
    username: <input name="username" id="username"/><br/>
196
    register: <input value="register" name="action" type="radio"/><br/>
197
    authenticate: <input value="authenticate" name="action" type="radio"/><br/>
198
    <input type="hidden" name="register2" id="register2"/>
199
    <input type="hidden" name="authenticate2" id="authenticate2"/>
200
    <button type="submit">Submit!</button>
201
</form>
202
203
</body>
204
</html>
205