Issues (3)

Security Analysis    no request data  

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.

src/Client.php (1 issue)

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 namespace Scriptotek\Sru;
2
3
use Http\Client\Common\Plugin\AuthenticationPlugin;
4
use Http\Client\Common\PluginClient;
5
use Http\Client\Common\Exception\ServerErrorException;
6
use Http\Factory\Discovery\HttpClient;
7
use Http\Factory\Discovery\HttpFactory;
8
use Http\Message\Authentication\BasicAuth;
9
use Psr\Http\Client\ClientInterface;
10
use Psr\Http\Message\RequestFactoryInterface;
11
12
/**
13
 * SRU client
14
 */
15
class Client
16
{
17
    /** @var ClientInterface */
18
    protected $httpClient;
19
20
    /**
21
     * @var RequestFactoryInterface
22
     */
23
    private $requestFactory;
24
25
    /** @var string SRU service base URL */
26
    protected $url;
27
28
    /** @var string Requested schema for the returned records */
29
    protected $schema;
30
31
    /** @var string SRU protocol version */
32
    protected $version;
33
34
    /** @var string Some user agent string to identify our client */
35
    protected $userAgent;
36
37
    /** @var array Custom headers */
38
    public $headers;
39
40
    /**
41
     * @var string|string[] Proxy configuration details.
42
     *
43
     * Either a string 'host:port' or an
44
     * array('host:port', 'username', 'password').
45
     */
46
    protected $proxy;
47
48
    /**
49
     * @var string[] Array containing username and password
50
     */
51
    protected $credentials;
52
53
    /**
54
     * Create a new client
55
     *
56
     * @param string                  $url             Base URL to the SRU service
57
     * @param array                   $options         Associative array of options
58
     * @param ClientInterface         $httpClient
59
     * @param RequestFactoryInterface $requestFactory
60
     * @throws \ErrorException
61
     */
62
    public function __construct(
63
        $url,
64
        $options = null,
65
        ClientInterface $httpClient = null,
66
        RequestFactoryInterface $requestFactory = null
67
    ) {
68
        $this->url = $url;
69
        $options = $options ?: array();
70
71
        $plugins = [];
72
73
        $this->schema = isset($options['schema'])
74
            ? $options['schema']
75
            : 'marcxml';
76
77
        $this->version = isset($options['version'])
78
            ? $options['version']
79
            : '1.1';
80
81
        $this->headers = isset($options['headers'])
82
            ? $options['headers']
83
            : ['Accept' => 'application/xml'];
84
85
        if (isset($options['user-agent'])) {
86
            // legacy option
87
            $this->headers['User-Agent'] = $options['user-agent'];
88
        }
89
90
        if (isset($options['credentials'])) {
91
            $authentication = new BasicAuth($options['credentials'][0], $options['credentials'][1]);
92
            $plugins[] = new AuthenticationPlugin($authentication);
93
        }
94
95
        if (isset($options['proxy'])) {
96
            throw new\ErrorException('Not supported');
97
        }
98
99
        $this->httpClient = new PluginClient($httpClient ?: HttpClient::client(), $plugins);
100
        $this->requestFactory = $requestFactory ?: HttpFactory::requestFactory();
101
    }
102
103
    /**
104
     * Construct the URL for a CQL query
105
     *
106
     * @param string $cql The CQL query
107
     * @param int $start Start value in result set (optional)
108
     * @param int $count Number of records to request (optional)
109
     * @param array $extraParams Extra GET parameters
110
     * @return string
111
     */
112
    public function urlTo($cql, $start = 1, $count = 10, $extraParams = array())
113
    {
114
        $qs = array(
115
            'operation' => 'searchRetrieve',
116
            'version' => $this->version,
117
            'recordSchema' => $this->schema,
118
            'maximumRecords' => $count,
119
            'query' => $cql
120
        );
121
122
        if ($start != 1) {
123
            // At least the BIBSYS SRU service, specifying startRecord results in
124
            // a less clear error message when there's no results
125
            $qs['startRecord'] = $start;
126
        }
127
128
        foreach ($extraParams as $key => $value) {
129
            $qs[$key] = $value;
130
        }
131
132
        return $this->url . '?' . http_build_query($qs);
133
    }
134
135
    /**
136
     * Perform a searchRetrieve request
137
     *
138
     * @deprecated
139
     * @param string $cql
140
     * @param int $start Start value in result set (optional)
141
     * @param int $count Number of records to request (optional)
142
     * @param array $extraParams Extra GET parameters
143
     * @return SearchRetrieveResponse
144
     */
145
    public function search($cql, $start = 1, $count = 10, $extraParams = array())
146
    {
147
        $url = $this->urlTo($cql, $start, $count, $extraParams);
148
        $body = $this->request('GET', $url);
149
150
        return new SearchRetrieveResponse($body, $this, $url);
151
    }
152
153
    /**
154
     * Perform a searchRetrieve request and return an iterator over the records
155
     *
156
     * @param string $cql
157
     * @param int $batchSize Number of records to request per request
158
     * @param array $extraParams Extra GET parameters
159
     * @return Records
160
     */
161
    public function all($cql, $batchSize = 10, $extraParams = array())
162
    {
163
        return new Records($cql, $this, $batchSize, $extraParams);
164
    }
165
166
    /**
167
     * Alias for `all()`
168
     * @deprecated
169
     * @param $cql
170
     * @param int $batchSize
171
     * @param array $extraParams
172
     * @return Records
173
     */
174
    public function records($cql, $batchSize = 10, $extraParams = array())
175
    {
176
        return $this->all($cql, $batchSize, $extraParams);
177
    }
178
179
    /**
180
     * Perform a searchRetrieve request and return first record
181
     *
182
     * @param string $cql
183
     * @param array $extraParams Extra GET parameters
184
     * @return Record
185
     */
186
    public function first($cql, $extraParams = array())
187
    {
188
        $recs = new Records($cql, $this, 1, $extraParams);
189
        return $recs->numberOfRecords() ? $recs->current() : null;
190
    }
191
192
    /**
193
     * Perform an explain request
194
     *
195
     * @return ExplainResponse
196
     */
197
    public function explain()
198
    {
199
        $url = $this->url . '?' . http_build_query(array(
200
            'operation' => 'explain',
201
            'version' => $this->version,
202
        ));
203
204
        $body = $this->request('GET', $url);
205
206
        return new ExplainResponse($body, $this, $url);
207
    }
208
209
    /**
210
     * @param string $method
211
     * @param string $url
212
     * @return string
213
     */
214
    public function request($method, $url)
215
    {
216
        $request = $this->requestFactory->createRequest($method, $url, $this->headers);
0 ignored issues
show
The call to RequestFactoryInterface::createRequest() has too many arguments starting with $this->headers.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
217
        $response = $this->httpClient->sendRequest($request);
218
219
        if ($response->getStatusCode() >= 500 && $response->getStatusCode() < 600) {
220
            throw new ServerErrorException($response->getReasonPhrase(), $request, $response);
221
        }
222
223
        return (string) $response->getBody();
224
    }
225
}
226