Disadvantages of Using Basic Server-Side Authorization in Shiny

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



Disadvantages of Using Basic Server-Side Authorization in Shiny



I have created very basic and primitive authorization on Shiny. It just checks the userid-password pair in the server side and conditionally shows the hidden interface.



What could be the downsides of using such primitive authorization?


library(shiny)

ui <- fluidPage(uiOutput("auth"))

server <- function(input, output)

output$auth <- renderUI(
tagList(
textInput(inputId = "username",label = "Username"),
passwordInput(inputId = "userpassword",label = "Password"),
actionButton("userlogin", "Login")
))

observeEvent(input$userlogin,
if(input$username=="demo" & input$userpassword=="demo")
output$auth <- renderUI(
tagList(
textInput(inputId = "Secret",label = NULL, placeholder = "Secret Data...")
))

)



shinyApp(ui = ui, server = server)




1 Answer
1



I am not a security professional, but potential problems that jump to mind are the reactive nature of the hidden section. I believe you would need to preface most reactives with a shiny::validate statement to prevent manipulation of the input object triggering underlying actions.



In this case, suppose something was depending on that input$Secret input, they can create an input just like that on their client page and submit whatever they want to you.



Now suppose you had this section:


# Insert Secret into database
observeEvent(input$Secret,
# INSERT RECORD
)



They can trigger that without ever having access to the textInput section you created.



A smart actor can make the input object whatever they want, so you need to write every part of your app with that in mind.



That's not to say this is impossible, but there are lots of pitfalls, here's a way to deal with the above problem with validation


authorized <- eventReactive(input$submitpass,
input$username == 'demo' & input$password == 'demo'
)
# Insert Secret into database
observeEvent(input$Secret,
shiny::validate(need(authorized(), 'You are not authorized'))
# INSERT RECORD
)



EDIT:



Also worth noting that writing authorization is hard, I'd be tempted to use something off the shelf, rather than trying to brew my own. Especially once you get in to having multiple users and storing/hashing passwords... it's very not easy






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard