You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Take a little break in your journey, read some of our extravagant knowledgement to become your best version...
...and, of course, share your sentences with us.
Source code:
<!DOCTYPE html><htmllang="en"><head><metacharset="UTF-8" />
<title>Share your thoughts</title><linkhref="/static/css/style.css" rel="stylesheet"><scriptsrc="https://unpkg.com/shvl@latest/dist/shvl.umd.js"></script><scriptsrc="https://unpkg.com/@popperjs/core@2"></script></head><bodyclass="wrap --rtn"><div><formaction="/admin" method="POST" class="flex-form"><divid="js-usr-new" class="select__label text">Share your coach phrases with our admin</div><inputtype="url" name="url" placeholder="address" class="ui-elem ui-elem-email text" />
<buttonid="send-button" type="submit" class="ui-button text">send</button><divid="send-tooltip" class="tooltip" role="tooltip">
go ahead, click me :)
<divclass="tooltip-arrow" data-popper-arrow></div></div></form><divid="quote" class="flex-form"></div></div><iframeid='#quote-base' src="/quotes"></iframe><script>constbutton=document.querySelector('#send-button');consttooltip=document.querySelector('#send-tooltip');constmessage=document.querySelector('#quote');window.addEventListener('message',functionsetup(e){window.removeEventListener('message',setup);quote={'author': '','message': ''}shvl.set(quote,Object.keys(JSON.parse(e.data))[0],Object.values(JSON.parse(e.data))[0]);shvl.set(quote,Object.keys(JSON.parse(e.data))[1],Object.values(JSON.parse(e.data))[1]);message.textContent=Object.values(quote)[1]+' — '+Object.values(quote)[0]constpopperInstance=Popper.createPopper(button,tooltip,{placement: 'bottom',modifiers: [{name: 'offset',options: {offset: [0,8],},},],});});</script></body></html>
quote.html
<script>phrases=[{'@entrepreneur': 'The distance between your DREAMS and REALITY is called ACTION'},{'@successman': 'MOTIVATION is what gets you started, HABIT is what keeps you going'},{'@bornrich': 'It\'s hard to beat someone that never gives up'},{'@businessman': 'Work while they sleep. Then live like they dream'},{'@bigboss': 'Life begins at the end of your comfort zone'},{'@daytrader': 'A successfull person never loses... They either win or learn!'}]setTimeout(function(){index=Math.floor(Math.random()*6)parent.postMessage('{"author": "'+Object.keys(phrases[index])[0]+'", "message": "'+Object.values(phrases[index])[0]+'"}','*');},0)</script>
Writeup
First, shvl is so suspicious so I went to it's GitHub page and found that there is a prototype pollution we can leverage: robinvdvleuten/shvl#35
There is no X-Frame-Options header so we can embed index page and postMessage to it, but we need to be faster than quote.html because index page only accept first message event.
So I think the goal is to win the race and pollute some attributes to abuse Popper. But how do we do this? Let's check the source code!
When creating new Popper instance, it merges default modifiers and the modifiers user set:
functionapplyStyles({ state }: ModifierArguments<{||}>){Object.keys(state.elements).forEach((name)=>{conststyle=state.styles[name]||{};constattributes=state.attributes[name]||{};constelement=state.elements[name];// arrow is optional + virtual elementsif(!isHTMLElement(element)||!getNodeName(element)){return;}// Flow doesn't support to extend this property, but it's the most// effective way to apply styles to an HTMLElement// $FlowFixMe[cannot-write]Object.assign(element.style,style);Object.keys(attributes).forEach((name)=>{constvalue=attributes[name];if(value===false){element.removeAttribute(name);}else{element.setAttribute(name,value===true ? '' : value);// this line}});});}
So we can set onfocus to the element and use hashtag to trigger the focus event.
The last thing is, how to be faster than quote.html to send message before it? The answer is, just keep sending it! I use requestAnimationFrame to send the message recursively until it reaches a limit(40 times in this case).
The first parameter we send in(which is button) will be state.elements.referecne, and in applyStyles:
functionapplyStyles({ state }: ModifierArguments<{||}>){Object.keys(state.elements).forEach((name)=>{conststyle=state.styles[name]||{};constattributes=state.attributes[name]||{};constelement=state.elements[name];
Object.keys(state.elements).forEach((name) => {, name will be "reference"
And for this line: const attributes = state.attributes[name] || {};, because we polluted Object.prototype.reference, so state.attributes["reference"] will be the object we gave, which is { onfocus: "..." }
Small Talk
Description
Take a little break in your journey, read some of our extravagant knowledgement to become your best version...
...and, of course, share your sentences with us.
Source code:
quote.html
Writeup
First, shvl is so suspicious so I went to it's GitHub page and found that there is a prototype pollution we can leverage: robinvdvleuten/shvl#35
There is no
X-Frame-Options
header so we can embed index page and postMessage to it, but we need to be faster than quote.html because index page only accept first message event.So I think the goal is to win the race and pollute some attributes to abuse Popper. But how do we do this? Let's check the source code!
When creating new Popper instance, it merges default modifiers and the modifiers user set:
https://github.com/popperjs/popper-core/blob/4800b37c5b4cabb711ac1d904664a70271487c4b/src/createPopper.js#L97
And in
mergeByName
, it checks if property exists first:https://github.com/popperjs/popper-core/blob/4800b37c5b4cabb711ac1d904664a70271487c4b/src/utils/mergeByName.js#L4
So we can pollute here to override the default modifier if we need. Fortunately, we don't. Because there is a default modifier called
applyStyles
which adds styles and attributes to the element: https://github.com/popperjs/popper-core/blob/4800b37c5b4cabb711ac1d904664a70271487c4b/src/modifiers/applyStyles.js#L31So we can set
onfocus
to the element and use hashtag to trigger the focus event.The last thing is, how to be faster than quote.html to send message before it? The answer is, just keep sending it! I use
requestAnimationFrame
to send the message recursively until it reaches a limit(40 times in this case).Final exploit, not perfect but works:
The text was updated successfully, but these errors were encountered: