<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>OWASP on Security Blog</title><link>https://alonglopvai.date/categories/owasp/</link><description>Recent content in OWASP on Security Blog</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Sun, 04 Oct 2026 10:00:00 +0700</lastBuildDate><atom:link href="https://alonglopvai.date/categories/owasp/index.xml" rel="self" type="application/rss+xml"/><item><title>Dựng lab OWASP Juice Shop an toàn bằng Docker</title><link>https://alonglopvai.date/p/dung-lab-owasp-juice-shop/</link><pubDate>Sun, 04 Oct 2026 10:00:00 +0700</pubDate><guid>https://alonglopvai.date/p/dung-lab-owasp-juice-shop/</guid><description>&lt;img src="https://alonglopvai.date/p/dung-lab-owasp-juice-shop/pasted-image-1791126534938.png" alt="Featured image of post Dựng lab OWASP Juice Shop an toàn bằng Docker" /&gt;&#10; &lt;blockquote&gt;&#10; &lt;p&gt;&lt;strong&gt;Tóm tắt.&lt;/strong&gt; Bài viết trình bày cách triển khai OWASP Juice Shop, một ứng dụng web cố tình chứa lỗ hổng, bằng Docker Compose trên máy cá nhân. Môi trường được cấu hình để chỉ chấp nhận kết nối từ chính máy chủ (localhost) nhằm tránh phơi bày ứng dụng ra mạng. Bài viết cũng ghi lại một sự cố khởi động thường gặp và thử thách đầu tiên của hệ thống.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Từ khóa:&lt;/strong&gt; OWASP Top 10, Juice Shop, Docker, môi trường thực nghiệm.&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&#10;&lt;h2 id="giới-thiệu"&gt;Giới thiệu&#10;&lt;/h2&gt;&lt;p&gt;Loạt bài này đi theo danh sách OWASP Top 10:2025. Nền tảng như PortSwigger Web Security Academy rất phù hợp để học cách khai thác từng lỗi, nhưng một số mục như cấu hình sai, ghi log và xử lý lỗi cần một môi trường tự kiểm soát để quan sát. Juice Shop phủ phần lớn các mục Top 10 và có bảng điểm kèm gợi ý, nên được chọn làm nền thực nghiệm.&lt;/p&gt;&#10;&lt;p&gt;Juice Shop là dự án chính thức của OWASP: một cửa hàng nước ép trực tuyến viết bằng Node.js, cố tình chứa hàng chục lỗ hổng từ dễ đến khó. Vì cố tình dễ bị tấn công, &lt;strong&gt;tuyệt đối không đưa nó ra Internet&lt;/strong&gt;.&lt;/p&gt;&#10;&lt;h2 id="môi-trường-thực-nghiệm"&gt;Môi trường thực nghiệm&#10;&lt;/h2&gt;&lt;h3 id="yêu-cầu"&gt;Yêu cầu&#10;&lt;/h3&gt;&lt;ul&gt;&#10;&lt;li&gt;Docker Desktop (hệ điều hành Windows).&lt;/li&gt;&#10;&lt;li&gt;Một trình duyệt web. Về sau bổ sung Burp Suite.&lt;/li&gt;&#10;&lt;li&gt;Vài GB dung lượng trống cho image.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="cấu-hình"&gt;Cấu hình&#10;&lt;/h3&gt;&lt;p&gt;Tập tin &lt;code&gt;docker-compose.yml&lt;/code&gt; trong thư mục &lt;code&gt;owasp-lab&lt;/code&gt;:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 2&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 3&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 4&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 5&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 6&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 7&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 8&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 9&#10;&lt;/span&gt;&lt;span class="lnt"&gt;10&#10;&lt;/span&gt;&lt;span class="lnt"&gt;11&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;juice-shop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;bkimminich/juice-shop:latest&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;container_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;juice-shop&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;127.0.0.1:3000:3000&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;no&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;security_opt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="kc"&gt;no&lt;/span&gt;-&lt;span class="l"&gt;new-privileges:true&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cap_drop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;ALL&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;Ba lựa chọn cấu hình đáng chú ý:&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Tùy chọn&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Tác dụng&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;127.0.0.1:3000:3000&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Chỉ mở cổng cho chính máy, không cho mạng nội bộ truy cập&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;no-new-privileges&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Ngăn tiến trình trong container tự nâng quyền&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;cap_drop: ALL&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Bỏ các đặc quyền Linux mà ứng dụng không cần&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;Nếu viết &lt;code&gt;3000:3000&lt;/code&gt; thay vì &lt;code&gt;127.0.0.1:3000:3000&lt;/code&gt;, Docker sẽ mở cổng cho cả mạng Wi-Fi, và bất kỳ ai cùng mạng đều truy cập được một ứng dụng đầy lỗ hổng.&lt;/p&gt;&#10;&lt;h2 id="triển-khai"&gt;Triển khai&#10;&lt;/h2&gt;&lt;h3 id="khởi-động"&gt;Khởi động&#10;&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;docker&lt;/span&gt; &lt;span class="n"&gt;compose&lt;/span&gt; &lt;span class="n"&gt;up&lt;/span&gt; &lt;span class="n"&gt;-d&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;docker&lt;/span&gt; &lt;span class="nb"&gt;ps&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;Sau khi chạy, cột &lt;code&gt;PORTS&lt;/code&gt; phải hiển thị &lt;code&gt;127.0.0.1:3000-&amp;gt;3000/tcp&lt;/code&gt;. Nếu hiển thị &lt;code&gt;0.0.0.0:3000&lt;/code&gt; thì cổng đang mở ra ngoài và cần sửa lại tập tin cấu hình.&lt;/p&gt;&#10;&lt;h3 id="sự-cố-err_empty_response"&gt;Sự cố ERR_EMPTY_RESPONSE&#10;&lt;/h3&gt;&lt;p&gt;Truy cập &lt;code&gt;http://localhost:3000&lt;/code&gt; ngay sau khi khởi động, trình duyệt báo lỗi &lt;code&gt;ERR_EMPTY_RESPONSE&lt;/code&gt; dù container ở trạng thái &lt;code&gt;Up&lt;/code&gt;. Nguyên nhân là Docker đã mở cổng nhưng ứng dụng bên trong chưa khởi động xong. Chờ khoảng một phút rồi tải lại là được. Có thể kiểm tra bằng:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;docker&lt;/span&gt; &lt;span class="n"&gt;logs&lt;/span&gt; &lt;span class="nb"&gt;juice-shop&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;-tail&lt;/span&gt; &lt;span class="mf"&gt;30&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;curl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;exe&lt;/span&gt; &lt;span class="n"&gt;-I&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="p"&gt;//&lt;/span&gt;&lt;span class="n"&gt;localhost&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;3000&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;Kết quả &lt;code&gt;HTTP/1.1 200 OK&lt;/code&gt; cho biết ứng dụng đã sẵn sàng. Trong PowerShell cần gõ &lt;code&gt;curl.exe&lt;/code&gt;, vì &lt;code&gt;curl&lt;/code&gt; trơn là bí danh của một lệnh khác.&lt;/p&gt;&#10;&lt;h2 id="kết-quả-và-thảo-luận"&gt;Kết quả và thảo luận&#10;&lt;/h2&gt;&lt;p&gt;Thử thách đầu tiên là tìm trang bảng điểm (Score Board). Trang này tồn tại trong ứng dụng nhưng không có liên kết nào dẫn tới. Đây là mô phỏng của &lt;strong&gt;bảo mật bằng sự che giấu&lt;/strong&gt;: ẩn một chức năng khỏi giao diện không bảo vệ được nó, vì mã JavaScript phía client nằm trong tay người dùng. Cách tiếp cận là mở công cụ phát triển của trình duyệt (F12) và đọc mã nguồn phía client.&lt;/p&gt;&#10;&lt;p&gt;Về lưu tiến độ, Juice Shop dùng chuỗi &lt;strong&gt;continue code&lt;/strong&gt; thay vì lưu dữ liệu bằng Docker volume. Chuỗi này được lưu lại sau mỗi buổi thực hành và nhập lại khi dựng môi trường mới.&lt;/p&gt;&#10;&lt;h2 id="kết-luận"&gt;Kết luận&#10;&lt;/h2&gt;&lt;p&gt;Môi trường Juice Shop chạy trên Docker đã sẵn sàng cho các bài thực hành tiếp theo. Bước kế tiếp là đặt một WAF (ModSecurity với bộ luật OWASP CRS) phía trước ứng dụng để so sánh kết quả khi có và không có lớp bảo vệ này.&lt;/p&gt;&#10;&lt;p&gt;Lưu ý an toàn: chỉ thực hành trên môi trường của mình, không mở cổng ra ngoài, và không dùng các kỹ thuật này lên hệ thống thật khi chưa được phép bằng văn bản.&lt;/p&gt;&#10;&lt;h2 id="tài-liệu-tham-khảo"&gt;Tài liệu tham khảo&#10;&lt;/h2&gt;&lt;ol&gt;&#10;&lt;li&gt;OWASP Juice Shop: &lt;a class="link" href="https://owasp.org/www-project-juice-shop/" target="_blank" rel="noopener"&#10; &gt;https://owasp.org/www-project-juice-shop/&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;OWASP Top 10: &lt;a class="link" href="https://owasp.org/Top10/" target="_blank" rel="noopener"&#10; &gt;https://owasp.org/Top10/&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;Docker Compose: &lt;a class="link" href="https://docs.docker.com/compose/" target="_blank" rel="noopener"&#10; &gt;https://docs.docker.com/compose/&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;</description></item></channel></rss>