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 | /** |
||
4 | * Dispatcher provides functionality to make it easier to work with frontend React components. |
||
5 | * See deploynaut/docs/dispatcher.md for more information. |
||
6 | * |
||
7 | * @todo: currently we can't have more than one component mounted in parallel on any given Dispatcher, |
||
8 | * because the SecurityID will diverge as soon as one of these components submit. |
||
9 | */ |
||
10 | abstract class Dispatcher extends DNRoot { |
||
11 | |||
12 | /** |
||
13 | * The CSRF token name that is used for all frondend dispatchers |
||
14 | */ |
||
15 | const SECURITY_TOKEN_NAME = 'DispatcherSecurityID'; |
||
16 | |||
17 | /** |
||
18 | * Generate the data structure used by the frontend component. |
||
19 | * |
||
20 | * @param string $name of the component |
||
21 | * @return array |
||
22 | */ |
||
23 | abstract public function getModel($name); |
||
24 | |||
25 | /** |
||
26 | * Renders the initial HTML needed to bootstrap the react component. |
||
27 | * |
||
28 | * Usage: $getReactComponent(YourComponent); |
||
29 | * |
||
30 | * @param string $name Used to name the DOM elements and obtain the initial model. |
||
31 | * @return string A snippet good for adding to a SS template. |
||
32 | */ |
||
33 | public function getReactComponent($name) { |
||
34 | $model = $this->getModel($name); |
||
35 | $model['InitialSecurityID'] = $this->getSecurityToken()->getValue(); |
||
36 | |||
37 | return $this->customise([ |
||
38 | 'Name' => $name, |
||
39 | 'Model' => htmlentities(json_encode($model)) |
||
40 | ])->renderWith('ReactTemplate'); |
||
41 | } |
||
42 | |||
43 | /** |
||
44 | * Return the validator errors as AJAX response. |
||
45 | * |
||
46 | * @param int $code HTTP status code. |
||
47 | * @param array $validatorErrors Result of calling Validator::validate, e.g. |
||
48 | * [{"fieldName":"Name","message":"Message.","messageType":"bad"}] |
||
49 | * @return \SS_HTTPResponse |
||
50 | */ |
||
51 | public function asJSONValidatorErrors($code, $validatorErrors) { |
||
52 | $fieldErrors = []; |
||
53 | foreach ($validatorErrors as $error) { |
||
54 | $fieldErrors[$error['fieldName']] = $error['message']; |
||
55 | } |
||
56 | return $this->asJSONFormFieldErrors($code, $fieldErrors); |
||
57 | } |
||
58 | |||
59 | /** |
||
60 | * Return field-specific errors as AJAX response. |
||
61 | * |
||
62 | * @param int $code HTTP status code. |
||
63 | * @param array $fieldErrors FieldName => message structure. |
||
64 | * @return \SS_HTTPResponse |
||
65 | */ |
||
66 | public function asJSONFormFieldErrors($code, $fieldErrors) { |
||
67 | $response = $this->getResponse(); |
||
68 | $response->addHeader('Content-Type', 'application/json'); |
||
69 | $response->setBody(json_encode([ |
||
70 | 'InputErrors' => $fieldErrors |
||
71 | ])); |
||
72 | $response->setStatusCode($code); |
||
73 | return $response; |
||
74 | } |
||
75 | |||
76 | /** |
||
77 | * Respond to an AJAX request. |
||
78 | * Automatically updates the security token and proxy pending redirects. |
||
79 | * |
||
80 | * @deprecated the use of getAPIResponse() is encouraged |
||
81 | * @param array $data Data to be passed to the frontend. |
||
82 | * |
||
83 | * @return SS_HTTPResponse |
||
84 | */ |
||
85 | public function asJSON($data = []) { |
||
86 | $securityToken = $this->getSecurityToken(); |
||
87 | $securityToken->reset(); |
||
88 | $data['NewSecurityID'] = $securityToken->getValue(); |
||
89 | |||
90 | $response = $this->getResponse(); |
||
91 | |||
92 | // If we received an AJAX request, we can't redirect in an ordinary way: the browser will |
||
93 | // interpret the 302 responses internally and the response will never reach JS. |
||
94 | // |
||
95 | // To get around that, upon spotting an active redirect, we change the response code to 200, |
||
96 | // and move the redirect into the "RedirectTo" field in the JSON response. Frontend can |
||
97 | // then interpret this and trigger a redirect. |
||
98 | if ($this->redirectedTo()) { |
||
99 | $data['RedirectTo'] = $this->response->getHeader('Location'); |
||
100 | // Pop off the header - we are no longer redirecting via the usual mechanism. |
||
101 | $this->response->removeHeader('Location'); |
||
102 | } |
||
103 | |||
104 | $response->addHeader('Content-Type', 'application/json'); |
||
105 | $response->setBody(json_encode($data)); |
||
106 | $response->setStatusCode(200); |
||
107 | return $response; |
||
108 | } |
||
109 | |||
110 | /** |
||
111 | * We want to separate the dispatchers security token from the static HTML |
||
112 | * security token since it's possible that they get out of sync with eachother. |
||
113 | * |
||
114 | * We do this by giving the token a separate name. |
||
115 | * |
||
116 | * Don't manually reset() this token, that will cause issues when people have |
||
117 | * several tabs open. The token will be recreated when the user session times |
||
118 | * out. |
||
119 | * |
||
120 | * @return SecurityToken |
||
121 | */ |
||
122 | protected function getSecurityToken() { |
||
123 | return new \SecurityToken(self::SECURITY_TOKEN_NAME); |
||
124 | } |
||
125 | |||
126 | /** |
||
127 | * @see getSecurityToken() |
||
128 | */ |
||
129 | protected function checkSecurityToken() { |
||
130 | $securityToken = $this->getSecurityToken(); |
||
131 | if (!$securityToken->check($this->request->postVar(self::SECURITY_TOKEN_NAME))) { |
||
132 | $this->httpError(403, 'Invalid security token, try reloading the page.'); |
||
133 | } |
||
134 | } |
||
135 | |||
136 | /** |
||
137 | * Return an XHR response object without any CSRF token information |
||
138 | * |
||
139 | * @param array $output |
||
140 | * @param int $statusCode |
||
141 | * @return SS_HTTPResponse |
||
142 | */ |
||
143 | View Code Duplication | protected function getAPIResponse($output, $statusCode) { |
|
0 ignored issues
–
show
|
|||
144 | $output['server_time'] = SS_Datetime::now()->format('U'); |
||
145 | $output['status_code'] = $statusCode; |
||
146 | $response = $this->getResponse(); |
||
147 | $response->addHeader('Content-Type', 'application/json'); |
||
148 | $response->setBody(json_encode($output, JSON_PRETTY_PRINT)); |
||
149 | $response->setStatusCode($statusCode); |
||
150 | return $response; |
||
151 | } |
||
152 | |||
153 | /** |
||
154 | * Decode the data submitted by the Form.jsx control. |
||
155 | * |
||
156 | * @return array |
||
157 | */ |
||
158 | protected function getFormData() { |
||
159 | return $this->stripNonPrintables(json_decode($this->request->postVar('Details'), true)); |
||
160 | } |
||
161 | |||
162 | /** |
||
163 | * @param string|array |
||
164 | * @return string|array |
||
165 | */ |
||
166 | View Code Duplication | protected function trimWhitespace($val) { |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
167 | if (is_array($val)) { |
||
168 | foreach ($val as $k => $v) { |
||
169 | $val[$k] = $this->trimWhitespace($v); |
||
170 | } |
||
171 | return $val; |
||
172 | } else { |
||
173 | return trim($val); |
||
174 | } |
||
175 | } |
||
176 | |||
177 | /** |
||
178 | * Remove control characters from the input. |
||
179 | * |
||
180 | * @param string|array |
||
181 | * @return string|array |
||
182 | */ |
||
183 | View Code Duplication | protected function stripNonPrintables($val) { |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
184 | if (is_array($val)) { |
||
185 | foreach ($val as $k => $v) { |
||
186 | $val[$k] = $this->stripNonPrintables($v); |
||
187 | } |
||
188 | return $val; |
||
189 | } else { |
||
190 | return preg_replace('/[[:cntrl:]]/', '', $val); |
||
191 | } |
||
192 | } |
||
193 | |||
194 | } |
||
195 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.