前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >javascript伪协议解析

javascript伪协议解析

作者头像
网e渗透安全部
发布2024-02-21 17:16:59
2600
发布2024-02-21 17:16:59
举报
文章被收录于专栏:白安全组白安全组

前言

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

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

代码语言:javascript
复制
<a href=javascript:alert(1)>LLLL</a>
代码语言:javascript
复制
<iframe src=javascript:alert(1)></iframe>
代码语言:javascript
复制
<form action=javascript:alert(1)>
  <button>submit</button>
</form>

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

危害方式

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

代码语言:javascript
复制
<iframe src="<?= $youtube_url ?>" width="500" height="300"></iframe>

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

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

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

代码语言:javascript
复制
<a href="<?php echo htmlspecialchars($data) ?>">link</a>`

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

vue中案例:

代码语言:javascript
复制
<script setup>
  import { ref } from 'vue'

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

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

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

页面重定向一般来说使用

代码语言:javascript
复制
const searchParams = new URLSearchParams(location.search)
window.location = searchParams.get('redirect')

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

这里举一个案例:

这是一个登录页面,

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

代码语言:javascript
复制
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的内容是可以进行编码的

比如:

代码语言:javascript
复制
<a href="&#106avascript&colon;alert(1)">click me</a>

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

代码语言:javascript
复制
console.log(new URL('javascript:alert(1)'))
/*
  {
    // ...
    href: "javascript:alert(1)",
    origin: "null",
    pathname: "alert(1)",
    protocol: "javascript:",
  }
*/

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

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

代码语言:javascript
复制
console.log(new URL('javascript:alert(1)'))
/*
  {
    // ...
    hostname: "",
    host: "",
    origin: null
  }
*/

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

代码语言:javascript
复制
console.log(new URL('javascript://huli.tw/%0aalert(1)'))

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

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

实际案例

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

代码语言:javascript
复制
export function ensureProtocol(url?: string) {
  if (!url) {
    return undefined;
  }
  return url.includes('://') ? url : `http://${url}`;
}

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

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

https://username:password@www.example.com/

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

代码语言:javascript
复制
javascript:alert@github.com/#://

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

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

代码语言:javascript
复制
javascript:alert%28%27Slonser%20was%20here%21%27%29%3B%2F%2F@github.com#;alert(10);://eow5kas78d0wlv0.m.pipedream.net%27

解码之后就是

代码语言:javascript
复制
javascript:alert('Slonser was here!');//@github.com#;alert(10);://eow5kas78d0wlv0.m.pipedream.net'

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-02-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 白安全组 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 危害方式
  • 防御手法
  • 实际案例
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档