This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * Login controller class. |
||
4 | * |
||
5 | * @version 1.2.0 |
||
6 | * @since 1.2.0 |
||
7 | */ |
||
8 | |||
9 | namespace Cassava\CAS\Controller; |
||
10 | |||
11 | use Cassava\CAS; |
||
12 | use Cassava\Plugin; |
||
13 | |||
14 | /** |
||
15 | * Implements CAS login. |
||
16 | * |
||
17 | * Implements the `/login` URI and determines whether to interpret the request as a credential |
||
18 | * requestor or a credential acceptor. |
||
19 | * |
||
20 | * @since 1.2.0 |
||
21 | */ |
||
22 | class LoginController extends BaseController { |
||
23 | |||
24 | /** |
||
25 | * Handles login requests. |
||
26 | * |
||
27 | * @param array $request Request arguments. |
||
28 | * |
||
29 | * @global $_POST |
||
30 | * |
||
31 | * @uses \apply_filters() |
||
32 | */ |
||
33 | public function handleRequest( $request ) { |
||
0 ignored issues
–
show
|
|||
34 | $request = array_merge( $_POST, (array) $request ); |
||
35 | |||
36 | /** |
||
37 | * Allows developers to change the request parameters passed to a `/login` request. |
||
38 | * |
||
39 | * @param array $request HTTP request (GET, POST) parameters. |
||
40 | */ |
||
41 | $request = \apply_filters( 'cas_server_login_args', $request ); |
||
42 | |||
43 | if ( isset( $request['username'] ) && isset( $request['password'] ) && isset( $request['lt'] ) ) { |
||
44 | $this->loginAcceptor( $request ); |
||
45 | return; |
||
46 | } |
||
47 | |||
48 | $this->loginRequestor( $request ); |
||
49 | } |
||
50 | |||
51 | /** |
||
52 | * Implements the `/login` URI behaviour as credential acceptor when a set of accepted |
||
53 | * credentials are passed to `/login` via POST. |
||
54 | * |
||
55 | * This plugin does not implement a form to take advantage of this request behaviour, and relies |
||
56 | * on WordPress' own authentication interfaces. Developers may implement custom forms so long as |
||
57 | * they send the request parameters described below. |
||
58 | * |
||
59 | * The following HTTP request parameters MUST be passed to `/login` while it is acting as a |
||
60 | * credential acceptor for username/password authentication. They are all case-sensitive. |
||
61 | * |
||
62 | * - `username`: The username of the client that is trying to log in. |
||
63 | * - `password`: The password of the client that is trying to log in. |
||
64 | * - `lt`: A login ticket. It acts as a nonce to prevent replaying requests. |
||
65 | * |
||
66 | * The following HTTP request parameters are optional: |
||
67 | * |
||
68 | * - `service`: The URL of the application the client is trying to access. CAS will redirect the |
||
69 | * client to this URL upon successful authentication. |
||
70 | * - `warn`: If this parameter is set, single sign-on will NOT be transparent. The client will |
||
71 | * be prompted before being authenticated to another service. |
||
72 | * |
||
73 | * @param array $request Request arguments. |
||
74 | * |
||
75 | * @uses \is_wp_error() |
||
76 | * @uses \sanitize_user() |
||
77 | * @uses \wp_signon() |
||
78 | * @uses \wp_verify_nonce() |
||
79 | * |
||
80 | * @todo Support for the optional warn parameter. |
||
81 | */ |
||
82 | private function loginAcceptor( $request = array() ) { |
||
83 | |||
84 | $username = \sanitize_user( $request['username'] ); |
||
85 | $password = $request['password']; |
||
86 | $lt = preg_replace( '@^' . CAS\Ticket::TYPE_LT . '-@', '', $request['lt'] ); |
||
87 | $service = isset( $request['service'] ) ? $request['service'] : null; |
||
88 | |||
89 | if ( ! \wp_verify_nonce( $lt, 'lt' ) ) { |
||
90 | $this->server->authRedirect( $request ); |
||
91 | } |
||
92 | |||
93 | $user = \wp_signon( array( |
||
94 | 'user_login' => $username, |
||
95 | 'user_password' => $password, |
||
96 | ) ); |
||
97 | |||
98 | if ( ! $user || \is_wp_error( $user ) ) { |
||
99 | $this->server->authRedirect( $request ); |
||
100 | } |
||
101 | |||
102 | $this->login( $user, $service ); |
||
103 | } |
||
104 | |||
105 | /** |
||
106 | * Implements the `/login` URI as credential requestor. |
||
107 | * |
||
108 | * If the client has already established a single sign-on session with CAS, the |
||
109 | * client will have presented its HTTP session cookie to `/login` unless the "renew" |
||
110 | * parameter is set to "true". |
||
111 | * |
||
112 | * If there is no session or the "renew" parameter is set, CAS will respond by |
||
113 | * displaying a login screen requesting (usually) a username and password. |
||
114 | * |
||
115 | * @param array $request Request arguments. |
||
116 | * |
||
117 | * @uses \is_user_logged_in() |
||
118 | * @uses \wp_get_current_user() |
||
119 | */ |
||
120 | private function loginRequestor( $request = array() ) { |
||
121 | |||
122 | $this->server->sessionStart(); |
||
123 | |||
124 | $renew = isset( $request['renew'] ) && 'true' === $request['renew']; |
||
125 | $gateway = isset( $request['gateway'] ) && 'true' === $request['gateway']; |
||
126 | $service = isset( $request['service'] ) ? $request['service'] : ''; |
||
127 | |||
128 | if ( $renew ) { |
||
129 | $this->renew(); |
||
130 | } |
||
131 | |||
132 | if ( ! \is_user_logged_in() ) { |
||
133 | if ( $gateway && $service ) { |
||
134 | $this->server->redirect( $service ); |
||
135 | } |
||
136 | |||
137 | $this->server->authRedirect( $request ); |
||
138 | } |
||
139 | |||
140 | $this->login( \wp_get_current_user(), $service ); |
||
141 | } |
||
142 | |||
143 | /** |
||
144 | * Renews the user session. |
||
145 | * |
||
146 | * Invalidates the user session and repeats the login request without the |
||
147 | * `renew` parameter. |
||
148 | * |
||
149 | * @uses \is_ssl() |
||
150 | * @uses \remove_query_arg() |
||
151 | * @uses \wp_logout() |
||
152 | */ |
||
153 | private function renew() { |
||
0 ignored issues
–
show
renew uses the super-global variable $_SERVER which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
![]() |
|||
154 | \wp_logout(); |
||
155 | |||
156 | $schema = \is_ssl() ? 'https://' : 'http://'; |
||
157 | $url = $schema . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; |
||
158 | $url = \remove_query_arg( 'renew', $url ); |
||
159 | |||
160 | $this->server->redirect( $url ); |
||
161 | } |
||
162 | |||
163 | /** |
||
164 | * Logs the user in. |
||
165 | * |
||
166 | * @param \WP_User $user WordPress user to authenticate. |
||
167 | * @param string $service URI for the service requesting user authentication. |
||
168 | * |
||
169 | * @uses \add_query_arg() |
||
170 | * @uses \apply_filters() |
||
171 | * @uses \esc_url_raw() |
||
172 | * @uses \home_url() |
||
173 | */ |
||
174 | private function login( $user, $service = '' ) { |
||
175 | $ticket = new CAS\Ticket( CAS\Ticket::TYPE_ST, $user, $service ); |
||
176 | |||
177 | $service = empty( $service ) ? \home_url() : \esc_url_raw( $service ); |
||
178 | $service = \add_query_arg( 'ticket', (string) $ticket, $service ); |
||
179 | |||
180 | /** |
||
181 | * Filters the redirect URI for the service requesting user authentication. |
||
182 | * |
||
183 | * @param string $service Service URI requesting user authentication. |
||
184 | * @param WP_User $user Logged in WordPress user. |
||
185 | */ |
||
186 | $service = \apply_filters( 'cas_server_redirect_service', $service, $user ); |
||
187 | |||
188 | $this->server->redirect( $service ); |
||
189 | } |
||
190 | } |
||
191 |
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: