private $mCacheControl = [];
private $mParamsUsed = [];
+ /** @var bool|null Cached return value from self::lacksSameOriginSecurity() */
+ private $lacksSameOriginSecurity = null;
+
/**
* Constructs an instance of ApiMain that utilizes the module and format specified by $request.
*
return $this->mResult;
}
+ /**
+ * Get the security flag for the current request
+ * @return bool
+ */
+ public function lacksSameOriginSecurity() {
+ if ( $this->lacksSameOriginSecurity !== null ) {
+ return $this->lacksSameOriginSecurity;
+ }
+
+ $request = $this->getRequest();
+
+ // JSONP mode
+ if ( $request->getVal( 'callback' ) !== null ) {
+ $this->lacksSameOriginSecurity = true;
+ return true;
+ }
+
+ // Header to be used from XMLHTTPRequest when the request might
+ // otherwise be used for XSS.
+ if ( $request->getHeader( 'Treat-as-Untrusted' ) !== false ) {
+ $this->lacksSameOriginSecurity = true;
+ return true;
+ }
+
+ // Allow extensions to override.
+ $this->lacksSameOriginSecurity = !Hooks::run( 'RequestHasSameOriginSecurity', [ $request ] );
+ return $this->lacksSameOriginSecurity;
+ }
+
/**
* Get the ApiErrorFormatter object associated with current request
* @return ApiErrorFormatter
$this->logRequest( $runTime );
if ( $this->mModule->isWriteMode() && $this->getRequest()->wasPosted() ) {
$this->getStats()->timing(
- 'api.' . $this->getModuleName() . '.executeTiming', 1000 * $runTime );
+ 'api.' . $this->mModule->getModuleName() . '.executeTiming', 1000 * $runTime
+ );
}
} catch ( Exception $e ) {
$this->handleException( $e );
$response = $this->getRequest()->response();
$out = $this->getOutput();
+ $out->addVaryHeader( 'Treat-as-Untrusted' );
+
$config = $this->getConfig();
if ( $config->get( 'VaryOnXFP' ) ) {
protected function setRequestExpectations( ApiBase $module ) {
$limits = $this->getConfig()->get( 'TrxProfilerLimits' );
$trxProfiler = Profiler::instance()->getTransactionProfiler();
- if ( $this->getRequest()->wasPosted() ) {
- if ( $module->isWriteMode() ) {
- $trxProfiler->setExpectations( $limits['POST'], __METHOD__ );
- } else {
- $trxProfiler->setExpectations( $limits['POST-nonwrite'], __METHOD__ );
- $this->getRequest()->markAsSafeRequest();
- }
- } else {
+ if ( $this->getRequest()->hasSafeMethod() ) {
$trxProfiler->setExpectations( $limits['GET'], __METHOD__ );
+ } elseif ( $this->getRequest()->wasPosted() && !$module->isWriteMode() ) {
+ $trxProfiler->setExpectations( $limits['POST-nonwrite'], __METHOD__ );
+ $this->getRequest()->markAsSafeRequest();
+ } else {
+ $trxProfiler->setExpectations( $limits['POST'], __METHOD__ );
}
}