question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Make telefuncs default safe?

See original GitHub issue

Reading https://telefunc.com/shield I am concerned that someone inevitably will forget to include a throw new Abort() or a shield() command, and thus expose functions that are dangerous.

How about making telefunc default safe / restrictive, and then only opening up based on an explicit whitelisting approach, instead of a blacklisting approach?

So instead of shield() you could have unshield() or expose(), and similar for Abort. All functions could throw new Abort() abort by default, unless the context is set explicitly.

So instead of:

  if( !context.user?.isAdmin ) {
    throw new Abort()
  }
  const result = await database.runSQL(query)
  return result

It could be something like:

  if( context.user?.isAdmin ) {
    const result = await database.runSQL(query)
    return result
  } else {
    throw new Abort() // could be made default, so this else-condition would not be needed
  }

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:18 (10 by maintainers)

github_iconTop GitHub Comments

1reaction
brilloutcommented, Feb 9, 2022
// Environment: Node.js server

import { telefuncConfig } from 'telefunc'
// Enforce all telefunctions to have a permission function
telefuncConfig.permissionFunction = true
// components/Comment.telefunc.js
// Environment: Node.js server

import { permission } from '../auth/permission'
import { shield } from 'telefunc'

// Only admins are allowed to delete comments
shield(onCommentDelete, [shield.type.number], permission('admin'))
export async function onCommentDelete(id) {
  const comment = await Comment.findOne({ id })
  await comment.delete()
}
// auth/permission.js
// Environment: Node.js server

export { permission }

import { getContext } from 'telefunc'

function permission(permissionName) {
  return () => {
    if (permissionName === 'public') {
      return true
    }

    if (permissionName === 'admin') {
      const { user } = getContext()
      return user?.isAdmin
    }

    // ...
  }
}

This means that our telefunctions are guaranteed to be secure (as long as our permission() function is correct).

Thoughts?

1reaction
brilloutcommented, Dec 27, 2021

I am concerned that someone inevitably will forget to include a throw new Abort() or a shield() command, and thus expose functions that are dangerous.

I agree that’s a problem. It’s actually a problem with RPC in general.

Or something like this:

export async function runSQL(query) {
  const { user } = getContext()
  if (user.isAdmin) {
    allow()
  }
  const result = await database.runSQL(query)
  return result
}

But the problem with that is that allow() cannot be called after await:

export async function someTelefunction() {
  await somePromise;
  // This won't work
  allow()
}

In JavaScript, async call stacks cannot be traced.

Read more comments on GitHub >

github_iconTop Results From Across the Web

No results found

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found