javascript伪协议解析

admin 2024年2月4日21:52:48评论13 views字数 2937阅读9分47秒阅读模式

前言

首先来介绍一下这个伪协议,JavaScript伪协议最重要的,其实就是可以用来执行js的代码,哪些地方可以用呢,

a标签的href里面,iframe标签的src里面,甚至form标签的action和button的formaction也是可以的

<a href=javascript:alert(1)>LLLL</a>
<iframe src=javascript:alert(1)></iframe>
<form action=javascript:alert(1)>
<button>submit</button>
</form>

<form id=f2>
</form>
<button form=f2 formaction=javascript:alert(2)>submit</button>

危害方式

这里可能会产生这种危害的地方,比如一个网站需要发布一个文章,发文的时候在文中会自动填入一个网址进行嵌入,然后这个功能可能没什么过滤,那么就可以尝试插入javascript伪协议进行xss

<iframe src="<?= $youtube_url ?>" width="500" height="300"></iframe>

当然也有可能会进行网址内是否包含正常网站的检查,我们也可以绕过,这里比如会对网址内是否包含youtube.com进行检测,就可以使用javascript:alert(1);console.log('youtube.com')绕过。

正确的方式是检测网址是否为上网址的格式,并且确保是https开头

这里有一个后端存在这种漏洞案列

<a href="<?php echo htmlspecialchars($data) ?>">link</a>`

这里虽然将<>";做了编码,但是没办法新增标签,也没办法跳脱引号新增属性,但是攻击者可以插入javascript伪协议

vue中案例:

<script setup>
import { ref } from 'vue'

const link = ref('javascript:alert(1)')
</script>

<template>
<a :href="link">click me</a>
</template>

如果是跳转登录的话,也会产生这种类型的漏洞

页面重定向一般来说使用

const searchParams = new URLSearchParams(location.search)
window.location = searchParams.get('redirect')

问题在于window.location的值也可以是javascript伪协议

这里举一个案例:

这是一个登录页面,javascript伪协议解析

点击登入之后,会出现一个redirectToTarget 的 function ,而这个的源代码是这样

export const redirectToTarget = ({
fallback = 'current',
}: {
fallback?: 'homepage' | 'current'
} = {}) => {
const fallbackTarget =
fallback === 'homepage'
? `/` // FIXME: to purge cache
: window.location.href
const target = getTarget() || fallbackTarget

window.location.href = decodeURIComponent(target)
}

简单阅读下,就是使用了window.location.href机型重定向,如果登录的网址是https://xxxx/login?target=javascript:alert(1)

那么攻击者就会触发xss,这样如果攻击者抓取input的值,也就是账号密码就会泄露。

防御手法

针对这种类型的攻击,仅仅是将javascript过滤是不行的,因为href的内容是可以进行编码的

比如:

<a href="&#106avascript&colon;alert(1)">click me</a>

比较好的判断方式就是只允许http和https开头的字段,而且利用JavaScript去解析url,比如:

console.log(new URL('javascript:alert(1)'))
/*
{
// ...
href: "javascript:alert(1)",
origin: "null",
pathname: "alert(1)",
protocol: "javascript:",
}
*/

这样就可以根据protocol普安段是否合法

这里也会有一个错误的写法

console.log(new URL('javascript:alert(1)'))
/*
{
// ...
hostname: "",
host: "",
origin: null
}
*/

当hostname或者host为空,就代表不合法,但是我们可以利用//在JavaScript中注解方式,搭配一个元素看起来像网址,比如:

console.log(new URL('javascript://huli.tw/%0aalert(1)'))

这个在谷歌上没有问题,但是有一些浏览器就会存在问题。

上述这些问题,其实加一个target="_blank"就可以解决大部分问题,只需要重启一个新页面,浏览器会处理好很多问题。

实际案例

这里是一个23年6月telegram的漏洞,网页版中,有一个ensureProtocol函数,负责确认url有没有://,没有的话就加上,

export function ensureProtocol(url?: string) {
if (!url) {
return undefined;
}
return url.includes('://') ? url : `http://${url}`;
}

要绕过就很简单,我们只要加上javascript:alert('://')

但是这里浏览器解析也会分析url是不是合法的网址,而url本来最前面就可以带上账号和木马,中间就是使用:进行分割。像这样:

https://username:[email protected]/

因此攻击者发现可以用这样的字符串来绕过

javascript:[email protected]/#://

这里javascript伪装成账号,而alert是密码,后面的hostname是github,后面://进行绕过,虽然前面没有http或者https,但是仍认为合法.

最后搭配url,进行编码,产生出一个密码只有合法的网址

javascript:alert%28%27Slonser%20was%20here%21%27%29%3B%2F%[email protected]#;alert(10);://eow5kas78d0wlv0.m.pipedream.net%27

解码之后就是

javascript:alert('Slonser was here!');//@github.com#;alert(10);://eow5kas78d0wlv0.m.pipedream.net'

这里字符串会被服务器判断为一个链接类型,同时://也逃过检测,攻击者点击就会触发。

原文始发于微信公众号(白安全组):javascript伪协议解析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年2月4日21:52:48
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   javascript伪协议解析http://cn-sec.com/archives/2468259.html

发表评论

匿名网友 填写信息