PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / trunk
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration vtrunk
2.0.15 2.0.12 2.0.10 2.0.4 2.0.1 2.0.0 1.95.3 1.95.2 1.95 1.91.6 trunk 1.11 1.12 1.13 1.20 1.21 1.22 1.23 1.30 1.31 1.32 1.35 1.40 1.41 1.45 All 41 releases
← All changes | app/Services/Libs/FileSystem.php +70 -0 2.0.12trunk View file →
@@ -63,8 +63,78 @@
63 63 return $this->_getDir() . DIRECTORY_SEPARATOR . $file;
64 64 }
65 65
66 66 /**
67 + * Resolve a stored attachment path only when it belongs to Fluent Boards uploads.
68 + *
69 + * @param string $storedPath
70 + * @param int|null $boardId
71 + * @return string|null
72 + */
73 + public function _resolveLocalAttachmentPath($storedPath, $boardId = null)
74 + {
75 + if (!$storedPath) {
76 + return null;
77 + }
78 +
79 + $storedFilename = rawurldecode((string) $storedPath);
80 + $isBareFilename = $storedFilename !== ''
81 + && strpos($storedFilename, '/') === false
82 + && strpos($storedFilename, '\\') === false;
83 +
84 + if ($isBareFilename && $boardId === null) {
85 + return null;
86 + }
87 +
88 + $filePath = $isBareFilename ? null : realpath($storedPath);
89 + $allowedDirectory = $this->_getDir();
90 + $pluginRoot = realpath($allowedDirectory);
91 +
92 + if (!$pluginRoot) {
93 + return null;
94 + }
95 +
96 + $pluginRoot = rtrim($pluginRoot, DIRECTORY_SEPARATOR);
97 + $allowedRoot = $pluginRoot;
98 +
99 + if ($boardId !== null) {
100 + if (!is_int($boardId) && !is_string($boardId)) {
101 + return null;
102 + }
103 +
104 + $boardId = filter_var($boardId, FILTER_VALIDATE_INT, [
105 + 'options' => ['min_range' => 1],
106 + ]);
107 + if ($boardId === false) {
108 + return null;
109 + }
110 +
111 + $allowedDirectory .= DIRECTORY_SEPARATOR . 'board_' . $boardId;
112 + if (is_link($allowedDirectory)) {
113 + return null;
114 + }
115 +
116 + $allowedRoot = realpath($allowedDirectory);
117 + $expectedBoardRoot = $pluginRoot . DIRECTORY_SEPARATOR . 'board_' . $boardId;
118 + if (!$allowedRoot || $allowedRoot !== $expectedBoardRoot) {
119 + return null;
120 + }
121 + }
122 +
123 + if ($isBareFilename) {
124 + $filePath = realpath($allowedDirectory . DIRECTORY_SEPARATOR . $storedFilename);
125 + }
126 +
127 + if (!$filePath || !$allowedRoot || !is_file($filePath)) {
128 + return null;
129 + }
130 +
131 + $allowedRoot = rtrim($allowedRoot, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
132 +
133 + return strpos($filePath, $allowedRoot) === 0 ? $filePath : null;
134 + }
135 +
136 + /**
67 137 * Upload files into custom upload dir of this application
68 138 * @return array
69 139 */
70 140 public function _uploadFromRequest()